11import {
22 Button ,
3+ FieldNumber ,
34 RemoteDataStates ,
45 Text ,
56 triggerErrorToast ,
67 triggerSuccessToast ,
78 useRemoteData ,
89} from '@siafoundation/design-system'
10+ import { EditablePanel } from '../EditablePanel'
911import { SidePanel } from '../SidePanel'
1012import { useDialog } from '../../../contexts/dialog'
1113import { TrashCan16 } from '@siafoundation/react-icons'
@@ -16,14 +18,39 @@ import { SidePanelHeadingCopyable } from '../SidePanelHeadingCopyable'
1618import {
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'
2025import { SidePanelSkeleton } from '../SidePanelSkeleton'
2126import { 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
2348export 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 )
0 commit comments