-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: renterd autopilot and not enough contract onboarding
- Loading branch information
1 parent
2659481
commit 30fb33f
Showing
9 changed files
with
268 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'renterd': minor | ||
--- | ||
|
||
New users are now more clearly instructed to configure autopilot and to wait for enough contracts before files can be uploaded. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { CloudUpload32, LinkButton, Text } from '@siafoundation/design-system' | ||
import { routes } from '../../config/routes' | ||
import { useFiles } from '../../contexts/files' | ||
import { useAutopilotNotConfigured } from './checks/useAutopilotNotConfigured' | ||
import { useNotEnoughContracts } from './checks/useNotEnoughContracts' | ||
import { StateError } from './StateError' | ||
import { StateNoneMatching } from './StateNoneMatching' | ||
import { StateNoneYet } from './StateNoneYet' | ||
|
||
export function EmptyState() { | ||
const { dataState, activeDirectoryPath } = useFiles() | ||
|
||
const autopilotNotConfigured = useAutopilotNotConfigured() | ||
const notEnoughContracts = useNotEnoughContracts() | ||
|
||
if (dataState === 'noneMatchingFilters') { | ||
return <StateNoneMatching /> | ||
} | ||
|
||
if (dataState === 'error') { | ||
return <StateError /> | ||
} | ||
|
||
// only show on root directory and when there are no files | ||
if ( | ||
activeDirectoryPath === '/' && | ||
dataState === 'noneYet' && | ||
autopilotNotConfigured.active | ||
) { | ||
return ( | ||
<div className="flex flex-col gap-10 justify-center items-center h-[400px] cursor-pointer"> | ||
<Text> | ||
<CloudUpload32 className="scale-[200%]" /> | ||
</Text> | ||
<div className="flex flex-col gap-6 justify-center items-center"> | ||
<Text color="subtle" className="text-center max-w-[500px]"> | ||
Before you can upload files you must configure autopilot. Autopilot | ||
finds contracts with hosts based on the settings you choose. | ||
Autopilot also repairs your data as hosts come and go. | ||
</Text> | ||
<LinkButton variant="accent" href={routes.autopilot.index}> | ||
Configure autopilot → | ||
</LinkButton> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
// only show on root directory and when there are no files | ||
if ( | ||
activeDirectoryPath === '/' && | ||
dataState === 'noneYet' && | ||
notEnoughContracts.active | ||
) { | ||
return ( | ||
<div className="flex flex-col gap-12 justify-center items-center h-[400px] cursor-pointer"> | ||
<Text> | ||
<CloudUpload32 className="scale-[200%]" /> | ||
</Text> | ||
<div className="flex flex-col gap-4 justify-center items-center"> | ||
<Text color="subtle" className="text-center max-w-[500px]"> | ||
There are not enough contracts to upload data yet. Redundancy is | ||
configured to use {notEnoughContracts.required} shards which means | ||
at least that many contracts are required. | ||
</Text> | ||
<Text size="30" className="text-center max-w-[500px]"> | ||
{notEnoughContracts.count}/{notEnoughContracts.required} | ||
</Text> | ||
</div> | ||
</div> | ||
) | ||
} | ||
|
||
if (dataState === 'noneYet') { | ||
return <StateNoneYet /> | ||
} | ||
|
||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 107 additions & 91 deletions
198
apps/renterd/components/Files/FilesStatsMenu/FilesStatsMenuWarnings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,122 @@ | ||
import { Link, Text, Tooltip, Warning16 } from '@siafoundation/design-system' | ||
import { useAutopilotConfig } from '@siafoundation/react-renterd' | ||
import { useIsApcsEqDcs } from '../../../hooks/useIsApcsEqDcs' | ||
import { useFiles } from '../../../contexts/files' | ||
import { routes } from '../../../config/routes' | ||
import { useContractSetSettings } from '../../../hooks/useContractSetSettings' | ||
import { useApp } from '../../../contexts/app' | ||
import { useContractSetMismatch } from '../checks/useContractSetMismatch' | ||
import { useDefaultContractSetNotSet } from '../checks/useDefaultContractSetNotSet' | ||
import { useAutopilotNotConfigured } from '../checks/useAutopilotNotConfigured' | ||
import { useNotEnoughContracts } from '../checks/useNotEnoughContracts' | ||
|
||
export function FilesStatsMenuWarnings() { | ||
const { autopilot } = useApp() | ||
const apc = useAutopilotConfig({ | ||
config: { | ||
swr: { | ||
errorRetryCount: 0, | ||
}, | ||
}, | ||
}) | ||
const css = useContractSetSettings() | ||
const isApcsEqDcs = useIsApcsEqDcs() | ||
const { dataState, activeDirectoryPath } = useFiles() | ||
const contractSetMismatch = useContractSetMismatch() | ||
const defaultContractSetNotSet = useDefaultContractSetNotSet() | ||
const autopilotNotConfigured = useAutopilotNotConfigured() | ||
const notEnoughContracts = useNotEnoughContracts() | ||
|
||
let warning = 'none' | ||
|
||
if ( | ||
autopilot.status === 'on' && | ||
!isApcsEqDcs.isValidating && | ||
!isApcsEqDcs.data | ||
) { | ||
warning = 'contractSetMismatch' | ||
// onboard/warn about default contract set | ||
if (defaultContractSetNotSet.active) { | ||
return ( | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Configure a default contract set to get started.{' '} | ||
<Link | ||
underline="hover" | ||
size="12" | ||
font="mono" | ||
weight="medium" | ||
color="amber" | ||
href={routes.config.index} | ||
> | ||
Configuration → | ||
</Link> | ||
</Text> | ||
</div> | ||
) | ||
} | ||
|
||
if (autopilot.status === 'on' && apc.error) { | ||
warning = 'setupAutopilot' | ||
} | ||
|
||
if (css.data && !css.data?.default) { | ||
warning = 'setupDefaultContractSet' | ||
} | ||
|
||
return ( | ||
<> | ||
{warning === 'setupDefaultContractSet' && ( | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Configure a default contract set to get started.{' '} | ||
<Link | ||
underline="hover" | ||
size="12" | ||
font="mono" | ||
weight="medium" | ||
color="amber" | ||
href={routes.config.index} | ||
> | ||
Configuration → | ||
</Link> | ||
</Text> | ||
</div> | ||
)} | ||
{warning === 'setupAutopilot' && ( | ||
// warn about contract set mismatch | ||
if (contractSetMismatch.active) { | ||
return ( | ||
<Tooltip | ||
align="start" | ||
content={ | ||
<> | ||
The autopilot contract set does not match the default contract set. | ||
This means that by default workers will not upload data to contracts | ||
that autopilot manages. Unless these contract are being manually | ||
maintained, this will result in data loss. Continue with caution or | ||
update the autopilot contract set to match the default contract set. | ||
</> | ||
} | ||
> | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Configure autopilot to get started.{' '} | ||
<Link | ||
underline="hover" | ||
size="12" | ||
font="mono" | ||
weight="medium" | ||
color="amber" | ||
href={routes.autopilot.index} | ||
> | ||
Autopilot → | ||
</Link> | ||
Uploaded data will not be managed by autopilot. | ||
</Text> | ||
</div> | ||
)} | ||
{warning === 'contractSetMismatch' && ( | ||
<Tooltip | ||
align="start" | ||
content={ | ||
<> | ||
The autopilot contract set does not match the default contract | ||
set. This means that by default workers will not upload data to | ||
contracts that autopilot manages. Unless these contract are being | ||
manually maintained, this will result in data loss. Continue with | ||
caution or update the autopilot contract set to match the default | ||
contract set. | ||
</> | ||
} | ||
> | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Uploaded data will not be managed by autopilot. | ||
</Text> | ||
</div> | ||
</Tooltip> | ||
)} | ||
</> | ||
) | ||
</Tooltip> | ||
) | ||
} | ||
|
||
// only show if not on the root directory because the explorer empty state shows the same info | ||
const notEnoughContractsRootDirectory = | ||
notEnoughContracts.active && | ||
activeDirectoryPath === '/' && | ||
dataState !== 'noneYet' | ||
const notEnoughContractsNotRootDirectory = | ||
notEnoughContracts.active && activeDirectoryPath !== '/' | ||
if (notEnoughContractsRootDirectory || notEnoughContractsNotRootDirectory) { | ||
return ( | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Not enought contracts to upload files. {notEnoughContracts.count}/ | ||
{notEnoughContracts.required} | ||
</Text> | ||
</div> | ||
) | ||
} | ||
|
||
// only show if not on the root directory because the explorer empty state shows the same info | ||
const autopilotNotConfiguredRootDirectory = | ||
autopilotNotConfigured.active && | ||
activeDirectoryPath === '/' && | ||
dataState !== 'noneYet' | ||
const autopilotNotConfiguredNotRootDirectory = | ||
autopilotNotConfigured.active && activeDirectoryPath !== '/' | ||
if ( | ||
autopilotNotConfiguredRootDirectory || | ||
autopilotNotConfiguredNotRootDirectory | ||
) { | ||
return ( | ||
<div className="flex gap-1"> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
<Warning16 /> | ||
</Text> | ||
<Text size="12" font="mono" weight="medium" color="amber"> | ||
Configure autopilot to get started.{' '} | ||
<Link | ||
underline="hover" | ||
size="12" | ||
font="mono" | ||
weight="medium" | ||
color="amber" | ||
href={routes.autopilot.index} | ||
> | ||
Autopilot → | ||
</Link> | ||
</Text> | ||
</div> | ||
) | ||
} | ||
|
||
return null | ||
} |
17 changes: 17 additions & 0 deletions
17
apps/renterd/components/Files/checks/useAutopilotNotConfigured.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useAutopilotConfig } from '@siafoundation/react-renterd' | ||
import { useApp } from '../../../contexts/app' | ||
|
||
export function useAutopilotNotConfigured() { | ||
const { autopilot } = useApp() | ||
const apc = useAutopilotConfig({ | ||
config: { | ||
swr: { | ||
errorRetryCount: 0, | ||
}, | ||
}, | ||
}) | ||
|
||
return { | ||
active: autopilot.status === 'on' && !!apc.error, | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
apps/renterd/components/Files/checks/useContractSetMismatch.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { useIsApcsEqDcs } from '../../../hooks/useIsApcsEqDcs' | ||
import { useApp } from '../../../contexts/app' | ||
|
||
export function useContractSetMismatch() { | ||
const { autopilot } = useApp() | ||
const isApcsEqDcs = useIsApcsEqDcs() | ||
|
||
// warn about contract set mismatch | ||
const active = | ||
autopilot.status === 'on' && !isApcsEqDcs.isValidating && !isApcsEqDcs.data | ||
|
||
return { | ||
active, | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
apps/renterd/components/Files/checks/useDefaultContractSetNotSet.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { useContractSetSettings } from '../../../hooks/useContractSetSettings' | ||
|
||
export function useDefaultContractSetNotSet() { | ||
const css = useContractSetSettings() | ||
|
||
return { | ||
active: css.data && !css.data?.default, | ||
} | ||
} |
Oops, something went wrong.