Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

renterd bucket support, hostd remaining renter funds #372

Merged
merged 4 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cold-days-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'hostd': minor
---

The contracts table now has a column for "remaining renter funds".
9 changes: 9 additions & 0 deletions apps/hostd/contexts/contracts/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ export const columns: ContractsTableColumn[] = (
<ValueSc size="12" value={revision.payout} />
),
},
{
id: 'remainingRenterFunds',
label: 'remaining renter funds',
category: 'financial',
contentClassName: 'w-[120px] justify-end',
render: ({ data: { revision } }) => (
<ValueSc size="12" value={revision.remainingRenterFunds} />
),
},
{
id: 'lockedCollateral',
label: 'locked collateral',
Expand Down
3 changes: 3 additions & 0 deletions apps/hostd/contexts/contracts/dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ function getContractFields(c: Contract): ContractData {
? c.revision.validProofOutputs[1].value
: c.revision.missedProofOutputs[1].value
),
remainingRenterFunds: new BigNumber(
c.revision.validProofOutputs?.[0].value || 0
),
validProofOutputs: c.revision.validProofOutputs,
missedProofOutputs: c.revision.missedProofOutputs,
unlockHash: c.revision.unlockHash,
Expand Down
1 change: 1 addition & 0 deletions apps/hostd/contexts/contracts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type ContractData = {
windowStart: number
windowEnd: number
payout: BigNumber
remainingRenterFunds: BigNumber
validProofOutputs: SiacoinOutput[]
missedProofOutputs: SiacoinOutput[]
unlockHash: Hash256
Expand Down
1 change: 0 additions & 1 deletion apps/renterd/components/Files/FilesActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export function FilesActionsMenu() {
<div className="flex gap-2">
{isViewingBuckets ? (
<Button
disabled={!canUpload}
onClick={() => openDialog('filesCreateBucket')}
tip="Create bucket"
>
Expand Down
99 changes: 99 additions & 0 deletions apps/renterd/components/Files/FilesBucketCreateDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {
Paragraph,
Dialog,
triggerErrorToast,
triggerSuccessToast,
ConfigFields,
useOnInvalid,
FormSubmitButton,
FieldText,
} from '@siafoundation/design-system'
import { useCallback, useMemo } from 'react'
import { useForm } from 'react-hook-form'
import { useDialog } from '../../contexts/dialog'
import { useBucketCreate } from '@siafoundation/react-renterd'

const defaultValues = {
name: '',
}

function getFields(): ConfigFields<typeof defaultValues, never> {
return {
name: {
type: 'text',
title: 'Name',
placeholder: 'photos, backups, etc',
validation: {
required: 'required',
},
},
}
}

type Props = {
trigger?: React.ReactNode
open: boolean
onOpenChange: (val: boolean) => void
}

export function FilesBucketCreateDialog({
trigger,
open,
onOpenChange,
}: Props) {
const { closeDialog } = useDialog()

const bucketCreate = useBucketCreate()
const form = useForm({
mode: 'all',
defaultValues,
})

const onSubmit = useCallback(
async (values: typeof defaultValues) => {
const response = await bucketCreate.post({
payload: {
name: values.name,
},
})
if (response.error) {
triggerErrorToast(response.error)
} else {
triggerSuccessToast('Bucket created.')
form.reset()
closeDialog()
}
},
[form, bucketCreate, closeDialog]
)

const fields = useMemo(() => getFields(), [])

const onInvalid = useOnInvalid(fields)

return (
<Dialog
title="Create Bucket"
trigger={trigger}
open={open}
onOpenChange={(val) => {
if (!val) {
form.reset(defaultValues)
}
onOpenChange(val)
}}
contentVariants={{
className: 'w-[400px]',
}}
onSubmit={form.handleSubmit(onSubmit, onInvalid)}
>
<div className="flex flex-col gap-4">
<Paragraph size="14">
A bucket is an isolated collection of files.
</Paragraph>
<FieldText name="name" form={form} fields={fields} autoComplete="off" />
<FormSubmitButton form={form}>Create bucket</FormSubmitButton>
</div>
</Dialog>
)
}
11 changes: 4 additions & 7 deletions apps/renterd/components/Files/FilesBucketDeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function getFields(name: string): ConfigFields<typeof defaultValues, never> {
required: 'required',
validate: {
notDefault: () =>
name === 'default' || 'cannot delete default bucket',
name !== 'default' || 'cannot delete default bucket',
equals: (value) => value === name || 'bucket name does not match',
},
},
Expand Down Expand Up @@ -95,16 +95,13 @@ export function FilesBucketDeleteDialog({
>
<div className="flex flex-col gap-4">
<Paragraph size="14">
Are you sure you would like to delete the following bucket and all the
contained files?
Before you delete a bucket you must ensure that it is empty. Re-enter
the bucket name to confirm the removal.
</Paragraph>
<div>
<Code color="gray">{name}</Code>
</div>
<Paragraph size="14">
Enter the bucket name to confirm the removal.
</Paragraph>
<FieldText name="name" form={form} fields={fields} />
<FieldText name="name" form={form} fields={fields} autoComplete="off" />
<FormSubmitButton variant="red" form={form}>
Delete
</FormSubmitButton>
Expand Down
89 changes: 0 additions & 89 deletions apps/renterd/components/Files/FilesCreateBucketDialog.tsx

This file was deleted.

8 changes: 7 additions & 1 deletion apps/renterd/components/Files/useCanUpload.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { useFiles } from '../../contexts/files'
import { useAutopilotNotConfigured } from './checks/useAutopilotNotConfigured'
import { useNotEnoughContracts } from './checks/useNotEnoughContracts'

export function useCanUpload() {
const { isViewingABucket } = useFiles()
const autopilotNotConfigured = useAutopilotNotConfigured()
const notEnoughContracts = useNotEnoughContracts()
return !autopilotNotConfigured.active && !notEnoughContracts.active
return (
isViewingABucket &&
!autopilotNotConfigured.active &&
!notEnoughContracts.active
)
}
4 changes: 2 additions & 2 deletions apps/renterd/contexts/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { RenterdSendSiacoinDialog } from '../dialogs/RenterdSendSiacoinDialog'
import { RenterdTransactionDetailsDialog } from '../dialogs/RenterdTransactionDetailsDialog'
import { AlertsDialog } from '../dialogs/AlertsDialog'
import { HostsFilterPublicKeyDialog } from '../components/Hosts/HostsFilterPublicKeyDialog'
import { FilesCreateBucketDialog } from '../components/Files/FilesCreateBucketDialog'
import { FilesBucketDeleteDialog } from '../components/Files/FilesBucketDeleteDialog'
import { FilesBucketCreateDialog } from '../components/Files/FilesBucketCreateDialog'

export type DialogType =
| 'cmdk'
Expand Down Expand Up @@ -153,7 +153,7 @@ export function Dialogs() {
}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
/>
<FilesCreateBucketDialog
<FilesBucketCreateDialog
open={dialog === 'filesCreateBucket'}
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
/>
Expand Down
15 changes: 6 additions & 9 deletions apps/renterd/contexts/files/downloads.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {

type UploadsMap = Record<string, ObjectData>

type Props = {
activeDirectoryPath: string
}

export function useDownloads({ activeDirectoryPath }: Props) {
export function useDownloads() {
const download = useObjectDownloadFunc()
const [downloadsMap, setDownloadsMap] = useState<UploadsMap>({})

Expand Down Expand Up @@ -108,16 +104,17 @@ export function useDownloads({ activeDirectoryPath }: Props) {

const { settings } = useAppSettings()
const getFileUrl = useCallback(
(name: string, authenticated: boolean) => {
const path = `/worker/objects${name}`
(path: FullPath, authenticated: boolean) => {
const { bucket, key } = bucketAndKeyParamsFromPath(path)
const workerPath = `/worker/objects/${key}?bucket=${bucket}`
// Parse settings.api if its set otherwise URL
const origin = settings.api || location.origin
const scheme = origin.startsWith('https') ? 'https' : 'http'
const host = origin.replace('https://', '').replace('http://', '')
if (authenticated) {
return `${scheme}://:${settings.password}@${host}/api${path}`
return `${scheme}://:${settings.password}@${host}/api${workerPath}`
}
return `${scheme}://${host}/api${path}`
return `${scheme}://${host}/api${workerPath}`
},
[settings]
)
Expand Down
4 changes: 1 addition & 3 deletions apps/renterd/contexts/files/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ function useFilesMain() {
)

const { uploadFiles, uploadsList } = useUploads({ activeDirectoryPath })
const { downloadFiles, downloadsList, getFileUrl } = useDownloads({
activeDirectoryPath,
})
const { downloadFiles, downloadsList, getFileUrl } = useDownloads()

const { response, dataset } = useDataset({
activeDirectoryPath,
Expand Down