Skip to content

Commit b9fbb89

Browse files
committed
feat(indexd): add account update with editable max pinned data
1 parent 6c275d1 commit b9fbb89

File tree

6 files changed

+154
-31
lines changed

6 files changed

+154
-31
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@siafoundation/indexd-types': minor
3+
'@siafoundation/indexd-js': minor
4+
'@siafoundation/indexd-react': minor
5+
---
6+
7+
Added account update API.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'indexd': minor
3+
---
4+
5+
Added editable max pinned data field to account side panel.

apps/indexd/components/Data/Accounts/SidePanelAccount.tsx

Lines changed: 109 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import {
22
Button,
3+
FieldNumber,
34
RemoteDataStates,
45
Text,
56
triggerErrorToast,
67
triggerSuccessToast,
78
useRemoteData,
89
} from '@siafoundation/design-system'
10+
import { EditablePanel } from '../EditablePanel'
911
import { SidePanel } from '../SidePanel'
1012
import { useDialog } from '../../../contexts/dialog'
1113
import { TrashCan16 } from '@siafoundation/react-icons'
@@ -16,14 +18,39 @@ import { SidePanelHeadingCopyable } from '../SidePanelHeadingCopyable'
1618
import {
1719
useAdminAccount,
1820
useAdminAccountSlabsPrune,
21+
useAdminAccountUpdate,
1922
} from '@siafoundation/indexd-react'
23+
import { useMutate } from '@siafoundation/react-core'
24+
import { adminAccountsRoute } from '@siafoundation/indexd-types'
2025
import { SidePanelSkeleton } from '../SidePanelSkeleton'
2126
import { transformAccount } from './transform'
27+
import { useCallback, useMemo } from 'react'
28+
import BigNumber from 'bignumber.js'
29+
import { ConfigFields } from '@siafoundation/design-system'
30+
31+
type Values = {
32+
maxPinnedDataGB: BigNumber | undefined
33+
}
34+
35+
function getFields(): ConfigFields<Values, never> {
36+
return {
37+
maxPinnedDataGB: {
38+
type: 'number',
39+
title: 'Max pinned data (GB)',
40+
decimalsLimit: 2,
41+
validation: {
42+
required: 'required',
43+
},
44+
},
45+
}
46+
}
2247

2348
export function SidePanelAccount() {
2449
const { panelId, setPanelId } = useAccountsParams()
2550
const { openDialog, openConfirmDialog } = useDialog()
2651
const pruneSlabs = useAdminAccountSlabsPrune()
52+
const accountUpdate = useAdminAccountUpdate()
53+
const mutate = useMutate()
2754
const account = useAdminAccount({
2855
disabled: !panelId,
2956
params: {
@@ -34,8 +61,47 @@ export function SidePanelAccount() {
3461
{
3562
account,
3663
},
37-
({ account }) => transformAccount(account),
64+
({ account }) => {
65+
const transformed = transformAccount(account)
66+
return {
67+
account: transformed,
68+
values: {
69+
maxPinnedDataGB: new BigNumber(account.maxPinnedData).div(1e9),
70+
} as Values,
71+
}
72+
},
73+
)
74+
75+
const fields = useMemo(() => getFields(), [])
76+
77+
const onSave = useCallback(
78+
async (values: Values) => {
79+
if (!data.data) {
80+
return
81+
}
82+
const response = await accountUpdate.patch({
83+
params: {
84+
accountkey: data.data.account.publicKey,
85+
},
86+
payload: {
87+
maxPinnedData: values.maxPinnedDataGB
88+
? values.maxPinnedDataGB.times(1e9).toNumber()
89+
: 0,
90+
},
91+
})
92+
if (response.error) {
93+
triggerErrorToast({
94+
title: 'Error updating account',
95+
body: response.error,
96+
})
97+
} else {
98+
triggerSuccessToast({ title: 'Account updated' })
99+
await mutate((key) => key.startsWith(adminAccountsRoute))
100+
}
101+
},
102+
[accountUpdate, mutate, data.data],
38103
)
104+
39105
return (
40106
<RemoteDataStates
41107
data={data}
@@ -49,18 +115,22 @@ export function SidePanelAccount() {
49115
</div>
50116
</SidePanel>
51117
}
52-
loaded={(account) => (
53-
<SidePanel
54-
onClose={() => setPanelId(undefined)}
118+
loaded={({ account, values }) => (
119+
<EditablePanel
120+
key={account.id}
55121
heading={
56122
<SidePanelHeadingCopyable
57123
heading="Account"
58124
value={account.id}
59125
label="account"
60126
/>
61127
}
62-
actions={
63-
<div className="flex items-center justify-between w-full">
128+
onClose={() => setPanelId(undefined)}
129+
remoteValues={values}
130+
fields={fields}
131+
onSave={onSave}
132+
actionsLeft={
133+
<div className="flex items-center gap-2">
64134
<Button
65135
onClick={() =>
66136
openConfirmDialog({
@@ -95,31 +165,39 @@ export function SidePanelAccount() {
95165
</Button>
96166
</div>
97167
}
98-
>
99-
<SidePanelSection heading="Info">
100-
<div className="flex flex-col gap-2">
101-
<InfoRow
102-
label="Description"
103-
value={account.description}
104-
variant="column"
105-
/>
106-
<InfoRow
107-
label="Max pinned data"
108-
value={account.displayFields.maxPinnedData}
109-
/>
110-
<InfoRow
111-
label="Pinned data"
112-
value={account.displayFields.pinnedData}
113-
/>
114-
<InfoRow
115-
label="Last used"
116-
value={account.displayFields.lastUsed}
117-
/>
118-
<InfoRow label="Logo URL" value={account.logoURL} />
119-
<InfoRow label="Service URL" value={account.serviceURL} />
120-
</div>
121-
</SidePanelSection>
122-
</SidePanel>
168+
render={(form, fields) => (
169+
<>
170+
<SidePanelSection heading="Storage">
171+
<div className="flex flex-col gap-2">
172+
<FieldNumber
173+
name="maxPinnedDataGB"
174+
form={form}
175+
fields={fields}
176+
/>
177+
<InfoRow
178+
label="Pinned data"
179+
value={account.displayFields.pinnedData}
180+
/>
181+
</div>
182+
</SidePanelSection>
183+
<SidePanelSection heading="Info">
184+
<div className="flex flex-col gap-2">
185+
<InfoRow
186+
label="Description"
187+
value={account.description}
188+
variant="column"
189+
/>
190+
<InfoRow
191+
label="Last used"
192+
value={account.displayFields.lastUsed}
193+
/>
194+
<InfoRow label="Logo URL" value={account.logoURL} />
195+
<InfoRow label="Service URL" value={account.serviceURL} />
196+
</div>
197+
</SidePanelSection>
198+
</>
199+
)}
200+
/>
123201
)}
124202
/>
125203
)

libs/indexd-js/src/admin.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import {
1414
AdminAccountRotateKeyParams,
1515
AdminAccountRotateKeyPayload,
1616
AdminAccountRotateKeyResponse,
17+
AdminAccountUpdateParams,
18+
AdminAccountUpdatePayload,
19+
AdminAccountUpdateResponse,
1720
AdminAccountDeleteParams,
1821
AdminAccountDeletePayload,
1922
AdminAccountDeleteResponse,
@@ -241,6 +244,11 @@ export function Admin({
241244
AdminAccountRotateKeyPayload,
242245
AdminAccountRotateKeyResponse
243246
>(axios, 'put', adminAccountRoute),
247+
accountUpdate: buildRequestHandler<
248+
AdminAccountUpdateParams,
249+
AdminAccountUpdatePayload,
250+
AdminAccountUpdateResponse
251+
>(axios, 'patch', adminAccountRoute),
244252
accountDelete: buildRequestHandler<
245253
AdminAccountDeleteParams,
246254
AdminAccountDeletePayload,

libs/indexd-react/src/admin.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
useDeleteFunc,
33
useGetSwr,
4+
usePatchFunc,
45
usePutFunc,
56
usePostFunc,
67
HookArgsSwr,
@@ -20,6 +21,9 @@ import {
2021
AdminAccountRotateKeyResponse,
2122
AdminAccountRotateKeyPayload,
2223
AdminAccountRotateKeyParams,
24+
AdminAccountUpdateParams,
25+
AdminAccountUpdatePayload,
26+
AdminAccountUpdateResponse,
2327
AdminAccountDeleteParams,
2428
AdminAccountDeletePayload,
2529
AdminAccountDeleteResponse,
@@ -279,6 +283,19 @@ export function useAdminAccountRotateKey(
279283
})
280284
}
281285

286+
export function useAdminAccountUpdate(
287+
args?: HookArgsCallback<
288+
AdminAccountUpdateParams,
289+
AdminAccountUpdatePayload,
290+
AdminAccountUpdateResponse
291+
>,
292+
) {
293+
return usePatchFunc({
294+
...args,
295+
route: adminAccountRoute,
296+
})
297+
}
298+
282299
export function useAdminAccountDelete(
283300
args?: HookArgsCallback<
284301
AdminAccountDeleteParams,

libs/indexd-types/src/admin/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ export type AdminAccountRotateKeyPayload = {
103103
}
104104
export type AdminAccountRotateKeyResponse = void
105105

106+
export type AdminAccountUpdateParams = {
107+
accountkey: PublicKey
108+
}
109+
export type AdminAccountUpdatePayload = {
110+
maxPinnedData: number
111+
}
112+
export type AdminAccountUpdateResponse = void
113+
106114
export type AdminAccountDeleteParams = {
107115
accountkey: PublicKey
108116
}

0 commit comments

Comments
 (0)