Skip to content

Commit

Permalink
clunky but functioning side modal form based resize UI
Browse files Browse the repository at this point in the history
  • Loading branch information
david-crespo committed Oct 4, 2024
1 parent 91aebf4 commit c71671f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
75 changes: 75 additions & 0 deletions app/forms/instance-resize.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* Copyright Oxide Computer Company
*/
import { useForm } from 'react-hook-form'
import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom'
import * as R from 'remeda'

import {
apiQueryClient,
useApiMutation,
useApiQueryClient,
usePrefetchedApiQuery,
} from '@oxide/api'

import { NumberField } from '~/components/form/fields/NumberField'
import { SideModalForm } from '~/components/form/SideModalForm'
import { getInstanceSelector, useInstanceSelector } from '~/hooks/use-params'
import { addToast } from '~/stores/toast'
import { pb } from '~/util/path-builder'

InstanceResizeForm.loader = async ({ params }: LoaderFunctionArgs) => {
const { project, instance } = getInstanceSelector(params)
await apiQueryClient.prefetchQuery('instanceView', {
path: { instance },
query: { project },
})
return null
}

export function InstanceResizeForm() {
const { instance: instanceName, project } = useInstanceSelector()
const queryClient = useApiQueryClient()
const navigate = useNavigate()

const { data: instance } = usePrefetchedApiQuery('instanceView', {
path: { instance: instanceName },
query: { project },
})

const instanceUpdate = useApiMutation('instanceUpdate', {
onSuccess(_updatedInstance) {
queryClient.invalidateQueries('instanceView')
navigate(pb.instance({ project, instance: instanceName }))
addToast({ title: 'Instance updated' })
},
})

const form = useForm({ defaultValues: R.pick(instance, ['ncpus', 'memory']) })

return (
<SideModalForm
form={form}
formType="edit"
resourceName="Instance"
onDismiss={() => navigate(pb.instance({ project, instance: instanceName }))}
onSubmit={({ ncpus, memory }) => {
instanceUpdate.mutate({
path: { instance: instanceName },
query: { project },
// very important to include the boot disk or it will be unset
body: { ncpus, memory, bootDisk: instance.bootDiskId },
})
}}
loading={instanceUpdate.isPending}
submitError={instanceUpdate.error}
>
<NumberField name="ncpus" control={form.control} />
<NumberField name="memory" control={form.control} />
</SideModalForm>
)
}
7 changes: 5 additions & 2 deletions app/pages/project/instances/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ export const useMakeInstanceActions = (
),
},
{
label: 'View serial console',
label: 'Resize',
onActivate() {
navigate(pb.serialConsole(instanceSelector))
navigate(pb.instanceResize(instanceSelector))
},
disabled: !instanceCan.update(instance) && (
<>Only {fancifyStates(instanceCan.update.states)} instances can be resized</>
),
},
{
label: 'Delete',
Expand Down
12 changes: 12 additions & 0 deletions app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { CreateImageFromSnapshotSideModalForm } from './forms/image-from-snapshot'
import { CreateImageSideModalForm } from './forms/image-upload'
import { CreateInstanceForm } from './forms/instance-create'
import { InstanceResizeForm } from './forms/instance-resize'
import { CreateIpPoolSideModalForm } from './forms/ip-pool-create'
import { EditIpPoolSideModalForm } from './forms/ip-pool-edit'
import { IpPoolAddRangeSideModalForm } from './forms/ip-pool-range-add'
Expand Down Expand Up @@ -319,6 +320,17 @@ export const routes = createRoutesFromElements(
loader={StorageTab.loader}
handle={{ crumb: 'Storage' }}
/>
<Route
path="resize"
element={
<>
<StorageTab />
<InstanceResizeForm />
</>
}
loader={StorageTab.loader}
handle={{ crumb: 'Resize' }}
/>
<Route
path="networking"
element={<NetworkingTab />}
Expand Down
1 change: 1 addition & 0 deletions app/util/path-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ test('path builder', () => {
"instanceConnect": "/projects/p/instances/i/connect",
"instanceMetrics": "/projects/p/instances/i/metrics",
"instanceNetworking": "/projects/p/instances/i/networking",
"instanceResize": "/projects/p/instances/i/resize",
"instanceStorage": "/projects/p/instances/i/storage",
"instances": "/projects/p/instances",
"instancesNew": "/projects/p/instances-new",
Expand Down
1 change: 1 addition & 0 deletions app/util/path-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const pb = {
instanceStorage: (params: Instance) => `${instanceBase(params)}/storage`,
instanceConnect: (params: Instance) => `${instanceBase(params)}/connect`,
instanceNetworking: (params: Instance) => `${instanceBase(params)}/networking`,
instanceResize: (params: Instance) => `${instanceBase(params)}/resize`,
serialConsole: (params: Instance) => `${instanceBase(params)}/serial-console`,

disksNew: (params: Project) => `${projectBase(params)}/disks-new`,
Expand Down

0 comments on commit c71671f

Please sign in to comment.