mirror of
https://github.com/khairul169/garage-webui.git
synced 2025-10-14 14:59:32 +07:00
feat: enhance AssignNode functionality with zone redundancy options and update API integration
This commit is contained in:
parent
d6847884e0
commit
4de96071d4
@ -23,6 +23,8 @@ const defaultValues: AssignNodeSchema = {
|
||||
capacityUnit: "GB",
|
||||
isGateway: false,
|
||||
tags: [],
|
||||
zoneRedundancyType: "atLeast",
|
||||
zoneRedundancyAtLeast: 1,
|
||||
};
|
||||
|
||||
const AssignNodeDialog = () => {
|
||||
@ -36,6 +38,10 @@ const AssignNodeDialog = () => {
|
||||
defaultValues,
|
||||
});
|
||||
const isGateway = useWatch({ control: form.control, name: "isGateway" });
|
||||
const zoneRedundancyType = useWatch({
|
||||
control: form.control,
|
||||
name: "zoneRedundancyType",
|
||||
});
|
||||
|
||||
const assignNode = useAssignNode({
|
||||
onSuccess() {
|
||||
@ -106,10 +112,20 @@ const AssignNodeDialog = () => {
|
||||
? calculateCapacity(values.capacity, values.capacityUnit)
|
||||
: null;
|
||||
const data = {
|
||||
id: values.nodeId,
|
||||
zone: values.zone,
|
||||
capacity,
|
||||
tags: values.tags,
|
||||
parameters: {
|
||||
zoneRedundancy:
|
||||
values.zoneRedundancyType === "maximum"
|
||||
? ("maximum" as const)
|
||||
: { atLeast: Number(values.zoneRedundancyAtLeast) },
|
||||
},
|
||||
roles: [
|
||||
{
|
||||
id: values.nodeId,
|
||||
zone: values.zone,
|
||||
capacity,
|
||||
tags: values.tags,
|
||||
},
|
||||
],
|
||||
};
|
||||
assignNode.mutate(data);
|
||||
});
|
||||
@ -214,9 +230,9 @@ const AssignNodeDialog = () => {
|
||||
value={
|
||||
field.value
|
||||
? (field.value as string[]).map((value) => ({
|
||||
label: value,
|
||||
value,
|
||||
}))
|
||||
label: value,
|
||||
value,
|
||||
}))
|
||||
: null
|
||||
}
|
||||
options={tagsList}
|
||||
@ -228,6 +244,39 @@ const AssignNodeDialog = () => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormControl
|
||||
form={form}
|
||||
name="zoneRedundancyType"
|
||||
title="Zone Redundancy"
|
||||
render={(field) => (
|
||||
<Select
|
||||
name={field.name}
|
||||
value={String(field.value || "")}
|
||||
onChange={field.onChange}
|
||||
>
|
||||
<option value="atLeast">At Least</option>
|
||||
<option value="maximum">Maximum</option>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
|
||||
{zoneRedundancyType === "atLeast" && (
|
||||
<FormControl
|
||||
form={form}
|
||||
name="zoneRedundancyAtLeast"
|
||||
title="Minimum Zones"
|
||||
className="mt-2"
|
||||
render={(field) => (
|
||||
<Input
|
||||
type="number"
|
||||
name={field.name}
|
||||
value={String(field.value || "")}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Modal.Body>
|
||||
<Modal.Actions>
|
||||
<Button type="button" onClick={assignNodeDialog.close}>
|
||||
|
@ -43,7 +43,7 @@ export const useConnectNode = (options?: Partial<UseMutationOptions<ConnectNodeR
|
||||
|
||||
export const useAssignNode = (options?: Partial<UseMutationOptions<void, Error, AssignNodeBody>>) => {
|
||||
return useMutation<void, Error, AssignNodeBody>({
|
||||
mutationFn: (data) => api.post("/v2/AddClusterLayout", { body: [data] }),
|
||||
mutationFn: (data) => api.post("/v2/UpdateClusterLayout", { body: { parameters: data.parameters, roles: data.roles } }),
|
||||
...options,
|
||||
});
|
||||
};
|
||||
@ -51,7 +51,7 @@ export const useAssignNode = (options?: Partial<UseMutationOptions<void, Error,
|
||||
export const useUnassignNode = (options?: Partial<UseMutationOptions<void, Error, string>>) => {
|
||||
return useMutation<void, Error, string>({
|
||||
mutationFn: (nodeId) =>
|
||||
api.post("/v2/AddClusterLayout", { body: [{ id: nodeId, remove: true }] }),
|
||||
api.post("/v2/UpdateClusterLayout", { body: { parameters: null, roles: [{ id: nodeId, remove: true }] } }),
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
@ -16,6 +16,8 @@ export const assignNodeSchema = z
|
||||
capacityUnit: z.enum(capacityUnits),
|
||||
isGateway: z.boolean(),
|
||||
tags: z.string().min(1).array(),
|
||||
zoneRedundancyType: z.enum(["atLeast", "maximum"]),
|
||||
zoneRedundancyAtLeast: z.coerce.number(),
|
||||
})
|
||||
.refine(
|
||||
(values) => values.isGateway || (values.capacity && values.capacity > 0),
|
||||
@ -23,6 +25,19 @@ export const assignNodeSchema = z
|
||||
message: "Capacity required",
|
||||
path: ["capacity"],
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.zoneRedundancyType === "atLeast" && !data.zoneRedundancyAtLeast) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message:
|
||||
'Zone Redundancy At Least is required when Zone Redundancy Type is "atLeast"',
|
||||
path: ["zoneRedundancyAtLeast"],
|
||||
}
|
||||
);
|
||||
|
||||
export type AssignNodeSchema = z.infer<typeof assignNodeSchema>;
|
||||
|
@ -32,7 +32,7 @@ export type DataPartition = {
|
||||
export type Role = {
|
||||
id: string;
|
||||
zone: string;
|
||||
capacity: number;
|
||||
capacity: number | null;
|
||||
tags: string[];
|
||||
};
|
||||
|
||||
@ -46,11 +46,22 @@ export type GetClusterLayoutResult = {
|
||||
stagedRoleChanges: StagedRole[];
|
||||
};
|
||||
|
||||
export type AssignNodeBody = {
|
||||
export type PartitionNumber = {
|
||||
atLeast: number;
|
||||
};
|
||||
|
||||
export type LayoutParameters = {
|
||||
zoneRedundancy: "maximum" | PartitionNumber;
|
||||
}
|
||||
|
||||
export type NodeRoleChange = {
|
||||
remove: boolean;
|
||||
id: string;
|
||||
zone: string;
|
||||
capacity: number | null;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export type AssignNodeBody = {
|
||||
parameters: null | LayoutParameters,
|
||||
roles: Role[] | NodeRoleChange[];
|
||||
};
|
||||
|
||||
export type ApplyLayoutResult = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user