diff --git a/src/api/instances.tsx b/src/api/instances.tsx index 3f5bd4a0a..ba0ba60c4 100644 --- a/src/api/instances.tsx +++ b/src/api/instances.tsx @@ -33,10 +33,11 @@ export const fetchInstances = (project: string): Promise => { export const createInstance = ( body: string, - project: string + project: string, + target?: string ): Promise => { return new Promise((resolve, reject) => { - fetch(`/1.0/instances?project=${project}`, { + fetch(`/1.0/instances?project=${project}&target=${target ?? ""}`, { method: "POST", body: body, }) diff --git a/src/pages/instances/CreateInstanceForm.tsx b/src/pages/instances/CreateInstanceForm.tsx index 2f02abb18..779c5dfb0 100644 --- a/src/pages/instances/CreateInstanceForm.tsx +++ b/src/pages/instances/CreateInstanceForm.tsx @@ -174,7 +174,7 @@ const CreateInstanceForm: FC = () => { ? yamlToObject(values.yaml) : getPayload(values); - createInstance(JSON.stringify(instancePayload), project) + createInstance(JSON.stringify(instancePayload), project, values.target) .then((operation) => { const instanceName = operation.metadata.resources?.instances?.[0] .split("/") diff --git a/src/pages/instances/forms/InstanceCreateDetailsForm.tsx b/src/pages/instances/forms/InstanceCreateDetailsForm.tsx index 1557b86b7..823ee3750 100644 --- a/src/pages/instances/forms/InstanceCreateDetailsForm.tsx +++ b/src/pages/instances/forms/InstanceCreateDetailsForm.tsx @@ -7,6 +7,7 @@ import { instanceCreationTypes } from "util/instanceOptions"; import { FormikProps } from "formik/dist/types"; import { CreateInstanceFormValues } from "pages/instances/CreateInstanceForm"; import { RemoteImage } from "types/image"; +import InstanceLocationSelect from "pages/instances/forms/InstanceLocationSelect"; export interface InstanceDetailsFormValues { name?: string; @@ -14,6 +15,7 @@ export interface InstanceDetailsFormValues { image?: RemoteImage; instanceType: string; profiles: string[]; + target?: string; type: string; readOnly: boolean; } @@ -125,6 +127,7 @@ const InstanceCreateDetailsForm: FC = ({ isVmOnlyImage(formik.values.image) } /> + ; +} + +const figureDefaultGroup = (target?: string) => { + if (!target?.startsWith("@")) { + return "default"; + } + return target.split("@")[1]; +}; + +const figureDefaultMember = (target?: string) => { + if (!target || target.startsWith("@")) { + return ""; + } + return target; +}; + +const InstanceLocationSelect: FC = ({ formik }) => { + const { data: settings } = useSettings(); + const isClustered = settings?.environment?.server_clustered; + + if (!isClustered) { + return <>; + } + + const defaultGroup = figureDefaultGroup(formik.values.target); + const [selectedGroup, setSelectedGroup] = useState(defaultGroup); + const defaultMember = figureDefaultMember(formik.values.target); + const [selectedMember, setSelectedMember] = useState(defaultMember); + + const { data: clusterGroups = [], isLoading } = useQuery({ + queryKey: [queryKeys.cluster, queryKeys.groups], + queryFn: fetchClusterGroups, + }); + + if (isLoading) { + return ; + } + + const setGroup = (group: string) => { + formik.setFieldValue("target", `@${group}`); + setSelectedGroup(group); + setSelectedMember(""); + }; + + const setMember = (member: string) => { + if (member === "") { + setGroup(selectedGroup); + } else { + formik.setFieldValue("target", member); + setSelectedMember(member); + } + }; + + const availableMembers = + clusterGroups.find((group) => group.name === selectedGroup)?.members ?? []; + + return ( + <> + setMember(e.target.value)} + value={selectedMember} + options={[ + ...(availableMembers.length > 1 ? [{ label: "any", value: "" }] : []), + ...availableMembers.map((member) => { + return { label: member, value: member }; + }), + ]} + /> + + ); +}; + +export default InstanceLocationSelect;