diff --git a/app/react/docker/containers/CreateView/CreateView.tsx b/app/react/docker/containers/CreateView/CreateView.tsx index bec91a0ef..8bf0d9668 100644 --- a/app/react/docker/containers/CreateView/CreateView.tsx +++ b/app/react/docker/containers/CreateView/CreateView.tsx @@ -138,14 +138,14 @@ function CreateForm() { }); if (!confirmed) { - return; + return false; } } const registry = getRegistry(values.image, registriesQuery.data || []); const config = toRequest(values, registry, hideCapabilities); - mutation.mutate( + return mutation.mutate( { config, environment, values, registry, oldContainer, extraNetworks }, { onSuccess() { diff --git a/app/react/docker/containers/CreateView/InnerForm.tsx b/app/react/docker/containers/CreateView/InnerForm.tsx index abc729877..9b619b872 100644 --- a/app/react/docker/containers/CreateView/InnerForm.tsx +++ b/app/react/docker/containers/CreateView/InnerForm.tsx @@ -186,13 +186,13 @@ export function InnerForm({ ? (values) => ( { + onChange={(values) => { setFieldValue( 'resources.resources', values ); - return submitForm(); }} + redeploy={submitForm} isImageInvalid={!!errors?.image} /> ) diff --git a/app/react/docker/containers/CreateView/ResourcesTab/EditResourceForm.tsx b/app/react/docker/containers/CreateView/ResourcesTab/EditResourceForm.tsx index 99d801e95..9b9c35b78 100644 --- a/app/react/docker/containers/CreateView/ResourcesTab/EditResourceForm.tsx +++ b/app/react/docker/containers/CreateView/ResourcesTab/EditResourceForm.tsx @@ -1,7 +1,10 @@ import { Formik } from 'formik'; import { useMutation } from 'react-query'; import { useCurrentStateAndParams } from '@uirouter/react'; +import { useState } from 'react'; +import { FormikHelpers } from 'formik/dist/types'; +import { invalidateContainer } from '@/react/docker/containers/queries/container'; import { notifySuccess } from '@/portainer/services/notifications'; import { mutationOptions, withError } from '@/react-tools/react-query'; import { useSystemLimits } from '@/react/docker/proxy/queries/useInfo'; @@ -21,17 +24,22 @@ import { import { toConfigCpu, toConfigMemory } from './memory-utils'; export function EditResourcesForm({ + onChange, redeploy, initialValues, isImageInvalid, }: { initialValues: Values; - redeploy: (values: Values) => Promise; + onChange: (values: Values) => void; + redeploy: () => Promise; isImageInvalid: boolean; }) { const { params: { from: containerId }, } = useCurrentStateAndParams(); + + const [savedInitValues, setSavedInitValues] = useState(initialValues); + if (!containerId || typeof containerId !== 'string') { throw new Error('missing parameter "from"'); } @@ -54,7 +62,10 @@ export function EditResourcesForm({
{ + onChange(values); + setValues(values); + }} errors={errors} /> @@ -82,28 +93,44 @@ export function EditResourcesForm({ ); - function handleSubmit(values: Values) { + function handleSubmit(values: Values, helper: FormikHelpers) { updateMutation.mutate(values, { - onSuccess: () => { - notifySuccess('Success', 'Limits updated'); + onSuccess: (data) => { + if (data) { + notifySuccess('Success', 'Limits updated'); + helper.resetForm({ values: initialValues }); + invalidateContainer(environmentId, containerId); + } }, }); } function settingUnlimitedResources(values: Values) { return ( - (initialValues.limit > 0 && values.limit === 0) || - (initialValues.reservation > 0 && values.reservation === 0) || - (initialValues.cpu > 0 && values.cpu === 0) + (savedInitValues.limit > 0 && values.limit === 0) || + (savedInitValues.reservation > 0 && values.reservation === 0) || + (savedInitValues.cpu > 0 && values.cpu === 0) ); } + // return true only if limits are updated + // return false otherwise(container recreated, user canceled container recreation, etc.) async function updateLimitsOrCreate(values: Values) { if (settingUnlimitedResources(values)) { - return redeploy(values); + const ret = await redeploy(); + + if (ret === false) { + return false; + } + + setSavedInitValues(values); + return false; } - return updateLimits(environmentId, containerId, values); + setSavedInitValues(values); + await updateLimits(environmentId, containerId, values); + + return true; } } diff --git a/app/react/docker/containers/CreateView/ResourcesTab/GpuFieldset/GpuFieldset.tsx b/app/react/docker/containers/CreateView/ResourcesTab/GpuFieldset/GpuFieldset.tsx index 3f7699afb..ceb8c89c1 100644 --- a/app/react/docker/containers/CreateView/ResourcesTab/GpuFieldset/GpuFieldset.tsx +++ b/app/react/docker/containers/CreateView/ResourcesTab/GpuFieldset/GpuFieldset.tsx @@ -135,7 +135,7 @@ export function GpuFieldset({ checked={values.enabled && !!enableGpuManagement} onChange={toggleEnableGpu} className="ml-2" - disabled={enableGpuManagement === false} + disabled={!enableGpuManagement} />
{enableGpuManagement && values.enabled && ( diff --git a/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx b/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx index 10cd27f8b..aace001ef 100644 --- a/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx +++ b/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx @@ -35,6 +35,7 @@ export function ResourceFieldset({ onChange({ ...values, reservation: value })} max={maxMemory} @@ -45,6 +46,7 @@ export function ResourceFieldset({ onChange({ ...values, limit: value })} max={maxMemory} @@ -55,6 +57,7 @@ export function ResourceFieldset({ onChange({ diff --git a/app/react/docker/containers/queries/container.ts b/app/react/docker/containers/queries/container.ts index 75c2e91a6..8084f673f 100644 --- a/app/react/docker/containers/queries/container.ts +++ b/app/react/docker/containers/queries/container.ts @@ -12,6 +12,7 @@ import { PortainerResponse } from '@/react/docker/types'; import axios, { parseAxiosError } from '@/portainer/services/axios'; import { ContainerId } from '@/react/docker/containers/types'; import { EnvironmentId } from '@/react/portainer/environments/types'; +import { queryClient } from '@/react-tools/react-query'; import { urlBuilder } from '../containers.service'; @@ -89,6 +90,15 @@ export function useContainer( ); } +export function invalidateContainer( + environmentId: EnvironmentId, + containerId?: ContainerId +) { + return queryClient.invalidateQueries( + containerId ? queryKeys.container(environmentId, containerId) : [] + ); +} + export type ContainerResponse = PortainerResponse; async function getContainer(