Skip to content

Commit

Permalink
fix: edit node form feedback & final state
Browse files Browse the repository at this point in the history
  • Loading branch information
amalcaraz committed Dec 11, 2023
1 parent d930fef commit e1ba676
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 36 deletions.
30 changes: 21 additions & 9 deletions src/domain/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export type BaseNode = {
owner: string
reward: string
locked: boolean
authorized: string[]
authorized?: string[]
time: number
score: number
score_updated: boolean
Expand Down Expand Up @@ -171,7 +171,7 @@ export type BaseUpdateNode = {
name?: string
description?: string
reward?: string
authorized?: string | string[]
authorized?: string[]
locked?: boolean
registration_url?: string
manager?: string
Expand Down Expand Up @@ -346,13 +346,17 @@ export class NodeManager {
return res.item_hash
}

async updateCoreChannelNode(updateCCN: UpdateCCN): Promise<string> {
async updateCoreChannelNode(
updateCCN: UpdateCCN,
): Promise<[string, Partial<CCN>]> {
updateCCN = await NodeManager.updateCCNSchema.parseAsync(updateCCN)

return this.updateNode(updateCCN, 'create-node')
}

async updateComputeResourceNode(updateCRN: UpdateCRN): Promise<string> {
async updateComputeResourceNode(
updateCRN: UpdateCRN,
): Promise<[string, Partial<CRN>]> {
updateCRN = await NodeManager.updateCRNSchema.parseAsync(updateCRN)

return this.updateNode(updateCRN, 'create-resource-node')
Expand Down Expand Up @@ -438,10 +442,10 @@ export class NodeManager {
)
}

protected async updateNode(
{ hash, ...details }: UpdateAlephNode,
protected async updateNode<U extends UpdateAlephNode, N extends AlephNode>(
{ hash, ...details }: U,
action: 'create-node' | 'create-resource-node',
): Promise<string> {
): Promise<[string, Partial<N>]> {
if (!this.account) throw new Error('Invalid account')
if (!hash) throw new Error('Invalid node hash')

Expand Down Expand Up @@ -471,7 +475,15 @@ export class NodeManager {
APIServer: apiServer,
})

return res.item_hash
return [
res.item_hash,
{
hash,
...details,
picture: details.picture as string,
banner: details.banner as string,
} as unknown as Partial<N>,
]
}

isCRN(node: AlephNode): node is CRN {
Expand All @@ -484,7 +496,7 @@ export class NodeManager {

isKYCCleared(node: CCN): boolean {
if (!this.account) return false
return node.authorized?.includes(this.account.address)
return node.authorized?.includes(this.account.address) || false
}

isLocked(node: CCN): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const updateBaseNodeSchema = z.object({
reward: optionalString(ethereumAddressSchema),
manager: optionalString(ethereumAddressSchema),
authorized: optionalString(requiredStringSchema).or(
z.array(ethereumAddressSchema),
z.array(ethereumAddressSchema).optional(),
),
locked: z.boolean().optional(),
registration_url: optionalString(urlSchema),
Expand Down
42 changes: 33 additions & 9 deletions src/hooks/form/useEditComputeResourceNodeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {
useWatch,
} from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { NodeManager, UpdateCRN } from '@/domain/node'
import { CRN, NodeManager, UpdateCRN } from '@/domain/node'
import { useNotification } from '@aleph-front/aleph-core'
import { EntityAddAction } from '@/store/entity'

export type UseEditComputeResourceNodeFormState = UpdateCRN

Expand Down Expand Up @@ -54,11 +55,22 @@ export type UseEditComputeResourceNodeFormReturn = {
handleSubmit: (e: FormEvent) => Promise<void>
}

function calculateVirtualNode(node: CRN, updated: Partial<CRN>): CRN {
const virtualNode: CRN = {
...(node || {}),
...updated,
virtual: Date.now(),
}

return virtualNode
}

export function useEditComputeResourceNodeForm({
defaultValues,
}: UseEditComputeResourceNodeFormProps): UseEditComputeResourceNodeFormReturn {
const [appState] = useAppState()
const [appState, dispatch] = useAppState()
const { account } = appState.account
const { entities: nodes } = appState.crns

const noti = useNotification()

Expand All @@ -68,24 +80,36 @@ export function useEditComputeResourceNodeForm({
const onSubmit = useCallback(
async (state: UseEditComputeResourceNodeFormState) => {
if (!manager) throw new Error('Manager not ready')
if (!account) throw new Error('Invalid account')

await manager.updateComputeResourceNode(state)
return state.hash as string
const [, partialCRN] = await manager.updateComputeResourceNode(state)

const node = nodes?.find((node) => node.hash === partialCRN.hash)
const entity = calculateVirtualNode(node as CRN, partialCRN)

return entity
},
[manager],
[account, manager, nodes],
)

const onSuccess = useCallback(
async (hash: string) => {
async (entity: CRN) => {
if (!noti) throw new Error('Notification not ready')

noti.add({
variant: 'success',
title: 'Success',
text: `Your node "${hash}" was updated successfully.`,
text: `Your node "${entity.hash}" was updated successfully.`,
})

dispatch(
new EntityAddAction({
name: 'crns',
entities: [entity],
}),
)
},
[noti],
[dispatch, noti],
)

const {
Expand All @@ -97,7 +121,7 @@ export function useEditComputeResourceNodeForm({
onSubmit,
onSuccess,
resolver: zodResolver(NodeManager.updateCCNSchema),
readyDeps: [defaultValues?.hash],
readyDeps: [defaultValues],
})
// @note: dont use watch, use useWatch instead: https://github.com/react-hook-form/react-hook-form/issues/10753
const values = useWatch({ control }) as UseEditComputeResourceNodeFormState
Expand Down
42 changes: 33 additions & 9 deletions src/hooks/form/useEditCoreChannelNodeForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import {
useWatch,
} from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { NodeManager, UpdateCCN } from '@/domain/node'
import { CCN, NodeManager, UpdateCCN } from '@/domain/node'
import { useNotification } from '@aleph-front/aleph-core'
import { EntityAddAction } from '@/store/entity'

export type UseEditCoreChannelNodeFormState = UpdateCCN

Expand Down Expand Up @@ -48,11 +49,22 @@ export type UseEditCoreChannelNodeFormReturn = {
handleSubmit: (e: FormEvent) => Promise<void>
}

function calculateVirtualNode(node: CCN, updated: Partial<CCN>): CCN {
const virtualNode: CCN = {
...(node || {}),
...updated,
virtual: Date.now(),
}

return virtualNode
}

export function useEditCoreChannelNodeForm({
defaultValues,
}: UseEditCoreChannelNodeFormProps): UseEditCoreChannelNodeFormReturn {
const [appState] = useAppState()
const [appState, dispatch] = useAppState()
const { account } = appState.account
const { entities: nodes } = appState.ccns

const noti = useNotification()

Expand All @@ -62,24 +74,36 @@ export function useEditCoreChannelNodeForm({
const onSubmit = useCallback(
async (state: UseEditCoreChannelNodeFormState) => {
if (!manager) throw new Error('Manager not ready')
if (!account) throw new Error('Invalid account')

await manager.updateCoreChannelNode(state)
return state.hash as string
const [, partialCCN] = await manager.updateCoreChannelNode(state)

const node = nodes?.find((node) => node.hash === partialCCN.hash)
const entity = calculateVirtualNode(node as CCN, partialCCN)

return entity
},
[manager],
[account, manager, nodes],
)

const onSuccess = useCallback(
async (hash: string) => {
async (entity: CCN) => {
if (!noti) throw new Error('Notification not ready')

noti.add({
variant: 'success',
title: 'Success',
text: `Your node "${hash}" was updated successfully.`,
text: `Your node "${entity.hash}" was updated successfully.`,
})

dispatch(
new EntityAddAction({
name: 'ccns',
entities: [entity],
}),
)
},
[noti],
[dispatch, noti],
)

const {
Expand All @@ -91,7 +115,7 @@ export function useEditCoreChannelNodeForm({
onSubmit,
onSuccess,
resolver: zodResolver(NodeManager.updateCCNSchema),
readyDeps: [defaultValues?.hash],
readyDeps: [defaultValues],
})
// @note: dont use watch, use useWatch instead: https://github.com/react-hook-form/react-hook-form/issues/10753
const values = useWatch({ control }) as UseEditCoreChannelNodeFormState
Expand Down
10 changes: 6 additions & 4 deletions src/hooks/pages/earn/useComputeResourceNodeDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ export function useComputeResourceNodeDetailPage(): UseComputeResourceNodeDetail

// -----------------------------

const formProps = useEditComputeResourceNodeForm({
defaultValues: {
const defaultValues = useMemo(() => {
return {
hash: node?.hash,
name: node?.name,
description: node?.description,
Expand All @@ -107,8 +107,10 @@ export function useComputeResourceNodeDetailPage(): UseComputeResourceNodeDetail
picture: node?.picture,
banner: node?.banner,
address: node?.address,
},
})
}
}, [node])

const formProps = useEditComputeResourceNodeForm({ defaultValues })

return {
nodes,
Expand Down
10 changes: 6 additions & 4 deletions src/hooks/pages/earn/useCoreChannelNodeDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ export function useCoreChannelNodeDetailPage(): UseCoreChannelNodeDetailPageRetu

// -----------------------------

const formProps = useEditCoreChannelNodeForm({
defaultValues: {
const defaultValues = useMemo(() => {
return {
hash: node?.hash,
name: node?.name,
picture: node?.picture,
Expand All @@ -114,8 +114,10 @@ export function useCoreChannelNodeDetailPage(): UseCoreChannelNodeDetailPageRetu
registration_url: node?.registration_url,
manager: node?.manager,
multiaddress: node?.multiaddress,
},
})
}
}, [node])

const formProps = useEditCoreChannelNodeForm({ defaultValues })

return {
aggregateLatency,
Expand Down

0 comments on commit e1ba676

Please sign in to comment.