Files
certimate/ui/src/components/certimate/KVList.tsx
2024-10-21 15:07:09 +08:00

244 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { produce } from "immer";
import { Edit, Plus, Trash2 } from "lucide-react";
import Show from "@/components/Show";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { KVType } from "@/domain/domain";
type KVListProps = {
variables?: KVType[];
onValueChange?: (variables: KVType[]) => void;
};
const KVList = ({ variables, onValueChange }: KVListProps) => {
const [locVariables, setLocVariables] = useState<KVType[]>([]);
const { t } = useTranslation();
useEffect(() => {
if (variables) {
setLocVariables(variables);
}
}, [variables]);
const handleAddClick = (variable: KVType) => {
// 查看是否存在key存在则更新不存在则添加
const index = locVariables.findIndex((item) => {
return item.key === variable.key;
});
const newList = produce(locVariables, (draft) => {
if (index === -1) {
draft.push(variable);
} else {
draft[index] = variable;
}
});
setLocVariables(newList);
onValueChange?.(newList);
};
const handleDeleteClick = (index: number) => {
const newList = [...locVariables];
newList.splice(index, 1);
setLocVariables(newList);
onValueChange?.(newList);
};
const handleEditClick = (index: number, variable: KVType) => {
const newList = [...locVariables];
newList[index] = variable;
setLocVariables(newList);
onValueChange?.(newList);
};
return (
<>
<div className="flex justify-between dark:text-stone-200">
<Label>{t("domain.deployment.form.variables.label")}</Label>
<Show when={!!locVariables?.length}>
<KVEdit
variable={{
key: "",
value: "",
}}
trigger={
<div className="flex items-center text-primary">
<Plus size={16} className="cursor-pointer " />
<div className="text-sm ">{t("common.add")}</div>
</div>
}
onSave={(variable) => {
handleAddClick(variable);
}}
/>
</Show>
</div>
<Show
when={!!locVariables?.length}
fallback={
<div className="border rounded-md p-3 text-sm flex flex-col items-center">
<div className="text-muted-foreground">{t("domain.deployment.form.variables.empty")}</div>
<KVEdit
trigger={
<div className="flex items-center text-primary">
<Plus size={16} className="cursor-pointer " />
<div className="text-sm ">{t("common.add")}</div>
</div>
}
variable={{
key: "",
value: "",
}}
onSave={(variable) => {
handleAddClick(variable);
}}
/>
</div>
}
>
<div className="border p-3 rounded-md text-stone-700 text-sm dark:text-stone-200">
{locVariables?.map((item, index) => (
<div key={index} className="flex justify-between items-center">
<div>
{item.key}={item.value}
</div>
<div className="flex space-x-2">
<KVEdit
trigger={<Edit size={16} className="cursor-pointer" />}
variable={item}
onSave={(variable) => {
handleEditClick(index, variable);
}}
/>
<Trash2
size={16}
className="cursor-pointer"
onClick={() => {
handleDeleteClick(index);
}}
/>
</div>
</div>
))}
</div>
</Show>
</>
);
};
type KVEditProps = {
variable?: KVType;
trigger: React.ReactNode;
onSave: (variable: KVType) => void;
};
const KVEdit = ({ variable, trigger, onSave }: KVEditProps) => {
const [locVariable, setLocVariable] = useState<KVType>({
key: "",
value: "",
});
useEffect(() => {
if (variable) setLocVariable(variable!);
}, [variable]);
const { t } = useTranslation();
const [open, setOpen] = useState<boolean>(false);
const [err, setErr] = useState<Record<string, string>>({});
const handleSaveClick = () => {
if (!locVariable.key) {
setErr({
key: t("domain.deployment.form.variables.key.required"),
});
return;
}
if (!locVariable.value) {
setErr({
value: t("domain.deployment.form.variables.value.required"),
});
return;
}
onSave?.(locVariable);
setOpen(false);
setErr({});
};
return (
<Dialog
open={open}
onOpenChange={() => {
setOpen(!open);
}}
>
<DialogTrigger>{trigger}</DialogTrigger>
<DialogContent className="dark:text-stone-200">
<DialogHeader className="flex flex-col">
<DialogTitle>{t("domain.deployment.form.variables.label")}</DialogTitle>
<div className="pt-5 flex flex-col items-start">
<Label>{t("domain.deployment.form.variables.key")}</Label>
<Input
placeholder={t("domain.deployment.form.variables.key.placeholder")}
value={locVariable?.key}
onChange={(e) => {
setLocVariable({ ...locVariable, key: e.target.value });
}}
className="w-full mt-1"
/>
<div className="text-red-500 text-sm mt-1">{err?.key}</div>
</div>
<div className="pt-2 flex flex-col items-start">
<Label>{t("domain.deployment.form.variables.value")}</Label>
<Input
placeholder={t("domain.deployment.form.variables.value.placeholder")}
value={locVariable?.value}
onChange={(e) => {
setLocVariable({ ...locVariable, value: e.target.value });
}}
className="w-full mt-1"
/>
<div className="text-red-500 text-sm mt-1">{err?.value}</div>
</div>
</DialogHeader>
<DialogFooter>
<div className="flex justify-end">
<Button
onClick={() => {
handleSaveClick();
}}
>
{t("common.save")}
</Button>
</div>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
export default KVList;