Skip to content

Commit

Permalink
feat(instance) target cluster group or member on creation WD-4263
Browse files Browse the repository at this point in the history
  • Loading branch information
edlerd committed Jun 7, 2023
1 parent 30e6ff6 commit e2150c2
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/api/instances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ export const fetchInstances = (project: string): Promise<LxdInstance[]> => {

export const createInstance = (
body: string,
project: string
project: string,
target?: string
): Promise<LxdOperationResponse> => {
return new Promise((resolve, reject) => {
fetch(`/1.0/instances?project=${project}`, {
fetch(`/1.0/instances?project=${project}&target=${target ?? ""}`, {
method: "POST",
body: body,
})
Expand Down
2 changes: 1 addition & 1 deletion src/pages/instances/CreateInstanceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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("/")
Expand Down
3 changes: 3 additions & 0 deletions src/pages/instances/forms/InstanceCreateDetailsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ 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;
description?: string;
image?: RemoteImage;
instanceType: string;
profiles: string[];
target?: string;
type: string;
readOnly: boolean;
}
Expand Down Expand Up @@ -125,6 +127,7 @@ const InstanceCreateDetailsForm: FC<Props> = ({
isVmOnlyImage(formik.values.image)
}
/>
<InstanceLocationSelect formik={formik} />
</Col>
</Row>
<ProfileSelect
Expand Down
100 changes: 100 additions & 0 deletions src/pages/instances/forms/InstanceLocationSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { FC, useState } from "react";
import { Select } from "@canonical/react-components";
import { useQuery } from "@tanstack/react-query";
import { queryKeys } from "util/queryKeys";
import Loader from "components/Loader";
import { useSettings } from "context/useSettings";
import { fetchClusterGroups } from "api/cluster";
import { FormikProps } from "formik/dist/types";
import { CreateInstanceFormValues } from "pages/instances/CreateInstanceForm";

interface Props {
formik: FormikProps<CreateInstanceFormValues>;
}

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<Props> = ({ 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 <Loader />;
}

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 (
<>
<Select
id="locationGroup"
label="Location group"
onChange={(e) => setGroup(e.target.value)}
value={selectedGroup}
options={clusterGroups.map((group) => {
return {
label: group.name,
value: group.name,
disabled: group.members.length < 1,
};
})}
/>
<Select
id="locationMember"
label="Location member"
onChange={(e) => setMember(e.target.value)}
value={selectedMember}
options={[
...(availableMembers.length > 1 ? [{ label: "any", value: "" }] : []),
...availableMembers.map((member) => {
return { label: member, value: member };
}),
]}
/>
</>
);
};

export default InstanceLocationSelect;

0 comments on commit e2150c2

Please sign in to comment.