116 lines
3.6 KiB
TypeScript
116 lines
3.6 KiB
TypeScript
import { RefreshCw } from 'lucide-react';
|
|
import { Form, Formik, useFormikContext } from 'formik';
|
|
import { object } from 'yup';
|
|
import { useRouter } from '@uirouter/react';
|
|
|
|
import { AccessControlForm } from '@CE/react/portainer/access-control';
|
|
import { AccessControlFormData } from '@CE/react/portainer/access-control/types';
|
|
import { parseAccessControlFormData } from '@CE/react/portainer/access-control/utils';
|
|
import { useCurrentUser, useIsEdgeAdmin } from '@CE/react/hooks/useUser';
|
|
import { EnvironmentId } from '@CE/react/portainer/environments/types';
|
|
import { validationSchema as accessControlValidation } from '@CE/react/portainer/access-control/AccessControlForm/AccessControlForm.validation';
|
|
import { useSwarmId } from '@CE/react/docker/proxy/queries/useSwarm';
|
|
import { notifySuccess } from '@CE/portainer/services/notifications';
|
|
|
|
import { LoadingButton } from '@@CE/buttons';
|
|
import { FormSection } from '@@CE/form-components/FormSection';
|
|
|
|
import { useAssociateStackToEnvironmentMutation } from './useAssociateStackToEnvironmentMutation';
|
|
|
|
function validationSchema({ isAdmin }: { isAdmin: boolean }) {
|
|
return object({
|
|
accessControl: accessControlValidation(isAdmin),
|
|
});
|
|
}
|
|
|
|
export function AssociateStackForm({
|
|
stackName,
|
|
environmentId,
|
|
stackId,
|
|
isOrphanedRunning,
|
|
}: {
|
|
stackName: string;
|
|
environmentId: EnvironmentId;
|
|
stackId: number;
|
|
isOrphanedRunning: boolean | undefined;
|
|
}) {
|
|
const router = useRouter();
|
|
const swarmIdQuery = useSwarmId(environmentId);
|
|
const mutation = useAssociateStackToEnvironmentMutation();
|
|
|
|
const { user } = useCurrentUser();
|
|
const { isAdmin } = useIsEdgeAdmin();
|
|
const initialValues: FormValues = {
|
|
accessControl: parseAccessControlFormData(isAdmin, user.Id),
|
|
};
|
|
|
|
return (
|
|
<FormSection title="Associate to this environment">
|
|
<p className="small text-muted">
|
|
This feature allows you to re-associate this stack to the current
|
|
environment.
|
|
</p>
|
|
|
|
<Formik
|
|
initialValues={initialValues}
|
|
onSubmit={(values) => {
|
|
mutation.mutate(
|
|
{
|
|
environmentId,
|
|
accessControl: values.accessControl,
|
|
swarmId: swarmIdQuery.data,
|
|
isOrphanedRunning,
|
|
stackId,
|
|
},
|
|
{
|
|
onSuccess() {
|
|
notifySuccess('Stack successfully associated', stackName);
|
|
router.stateService.go('docker.stacks');
|
|
},
|
|
}
|
|
);
|
|
}}
|
|
validateOnMount
|
|
validationSchema={() => validationSchema({ isAdmin })}
|
|
>
|
|
<InnerForm environmentId={environmentId} />
|
|
</Formik>
|
|
</FormSection>
|
|
);
|
|
}
|
|
type FormValues = {
|
|
accessControl: AccessControlFormData;
|
|
};
|
|
|
|
function InnerForm({ environmentId }: { environmentId: EnvironmentId }) {
|
|
const { values, setFieldValue, errors, isSubmitting } =
|
|
useFormikContext<FormValues>();
|
|
|
|
return (
|
|
<Form className="form-horizontal">
|
|
<AccessControlForm
|
|
values={values.accessControl}
|
|
onChange={(newValues) => setFieldValue('accessControl', newValues)}
|
|
hideTitle
|
|
environmentId={environmentId}
|
|
errors={errors.accessControl}
|
|
/>
|
|
<div className="form-group">
|
|
<div className="col-sm-12">
|
|
<LoadingButton
|
|
color="primary"
|
|
size="small"
|
|
isLoading={isSubmitting}
|
|
loadingText="Association in progress..."
|
|
icon={RefreshCw}
|
|
className="-ml-1.25"
|
|
data-cy="stack-associate-btn"
|
|
>
|
|
Associate
|
|
</LoadingButton>
|
|
</div>
|
|
</div>
|
|
</Form>
|
|
);
|
|
}
|