Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/modules/jsonProperties/components/JsonPropertiesTable.tsx
T

185 lines
8.3 KiB
TypeScript

import { useTranslation } from "react-i18next";
import { useRef, useState } from "react";
import SlideOverWideEmpty from "~/components/ui/slideOvers/SlideOverWideEmpty";
import JsonPropertyForm from "./JsonPropertyForm";
import TrashIcon from "~/components/ui/icons/TrashIcon";
import { JsonPropertyDto } from "~/modules/jsonProperties/dtos/JsonPropertyTypeDto";
import OrderListButtons from "~/components/ui/sort/OrderListButtons";
import JsonPropertyTypeIcon from "./JsonPropertyTypeIcon";
import PencilIcon from "~/components/ui/icons/PencilIcon";
import NewFieldIcon from "~/components/ui/icons/NewFieldIcon";
import { useSubmit } from "react-router";
import ConfirmModal, { RefConfirmModal } from "~/components/ui/modals/ConfirmModal";
interface Props {
items: JsonPropertyDto[];
}
export default function JsonPropertiesTable({ items }: Props) {
const { t } = useTranslation();
const submit = useSubmit();
const confirmDelete = useRef<RefConfirmModal>(null);
const [selectedProperty, setSelectedProperty] = useState<JsonPropertyDto | null | undefined>(undefined);
function onDelete(item: JsonPropertyDto) {
confirmDelete.current?.setValue(item);
confirmDelete.current?.show(t("shared.confirmDelete"), t("shared.delete"), t("shared.cancel"), t("shared.warningCannotUndo"));
}
function onDeleteConfirmed(item: JsonPropertyDto) {
const form = new FormData();
form.set("action", "properties-delete");
form.set("name", item.name);
submit(form, {
method: "post",
});
}
return (
<div className="space-y-1">
{/* <div className="flex justify-between space-x-2">
<label className="text-xs font-medium">{t("models.jsonProperty.plural")}</label>
<button
type="button"
className="bg-secondary hover:bg-secondary hover:text-secondary-foreground hover:border-border text-muted-foreground rounded-md border border-transparent p-1 px-2 text-sm font-medium"
onClick={() => setSelectedProperty(null)}
>
{t("shared.add")}
</button>
</div> */}
{items.map((item, idx) => {
return <input key={idx} type="hidden" name="properties[]" value={JSON.stringify(item)} readOnly hidden />;
})}
<div className="space-y-1">
{items.map((item, idx) => {
return (
<div key={item.name} className="border-border bg-background rounded-md border px-4 py-1 shadow-2xs">
<div className="flex items-center justify-between space-x-2">
<div className="flex items-center space-x-2 truncate">
<div className=" flex items-center space-x-3 truncate">
<div className="hidden shrink-0 sm:flex">
<OrderListButtons
index={idx}
items={items.map((f, idx) => ({ ...f, id: f.name, order: idx }))}
editable={true}
actionName="properties-sort"
/>
</div>
<div className="flex items-center space-x-2">
<JsonPropertyTypeIcon type={item.type} className="text-muted-foreground h-4 w-4" />
</div>
<div className="text-foreground flex items-center space-x-2 truncate text-sm">
<div className="flex items-baseline space-x-1 truncate">
<div className="flex flex-col">
<div>
{item.title}
{item.required && <span className="text-red-500">*</span>}
</div>
<div className="text-muted-foreground text-xs">
{item.name}
{["select", "multiselect"].includes(item.type) && "[]"}
{["range-date", "range-number"].includes(item.type) && ` (${t("models.jsonProperty.badges.range")})`}
</div>
</div>
{/* {item.type === PropertyType.FORMULA && <div className="truncate italic text-muted-foreground">({item.formula})</div>} */}
{["select", "multiselect"].includes(item.type) && (
<div className="text-muted-foreground truncate text-xs">
{t("shared.options")}: [{!item.options || item.options.length === 0 ? "" : item.options?.map((f) => f.value).join(", ")}]
</div>
)}
</div>
</div>
</div>
</div>
<div className="flex shrink-0 space-x-1">
<div className="flex items-center space-x-1 truncate p-1">
<button
type="button"
onClick={() => setSelectedProperty(item)}
className="hover:bg-secondary/90 focus:bg-secondary/90 group flex items-center rounded-md border border-transparent p-2 focus:outline-hidden focus:ring-2 focus:ring-gray-400 focus:ring-offset-1"
// onClick={() => update(idx, item)}
>
<PencilIcon className="group-hover:text-muted-foreground h-4 w-4 text-gray-300" />
</button>
<button
type="button"
className="hover:bg-secondary/90 focus:bg-secondary/90 group flex items-center rounded-md border border-transparent p-2 focus:outline-hidden focus:ring-2 focus:ring-gray-400 focus:ring-offset-1"
onClick={() => onDelete(item)}
>
<TrashIcon className="group-hover:text-muted-foreground h-4 w-4 text-gray-300" />
</button>
</div>
</div>
</div>
</div>
);
})}
<div>
<button
type="button"
onClick={() => setSelectedProperty(null)}
className="focus:ring-ring border-border hover:border-border relative block w-full rounded-lg border-2 border-dashed px-12 py-3 text-center focus:outline-hidden focus:ring-2 focus:ring-offset-2"
>
<NewFieldIcon className="text-muted-foreground mx-auto h-4" />
<span className="mt-1 block text-xs font-medium">{t("models.jsonProperty.actions.add")}</span>
</button>
</div>
</div>
{/* <TableSimple
items={items}
emptyState={{ title: t("shared.noCustomProperties"), description: "" }}
actions={[
{
title: t("shared.edit"),
onClick: (_, item) => setSelectedProperty(item),
},
{
title: <TrashIcon className="text-muted-foreground group-hover:text-foreground h-4 w-4" />,
onClick: (_, item) => onChange(items.filter((i) => i !== item)),
},
]}
headers={[
{
name: "type",
title: t("models.jsonProperty.fields.type"),
value: (item) => <JsonPropertyTypeIcon type={item.type} className="h-4 w-4 text-muted-foreground" />,
},
{
name: "name",
title: t("models.jsonProperty.fields.name"),
className: "w-full",
value: (item) => (
<div className="flex flex-col">
<div className="font-medium">
{item.title} <span className="text-muted-foreground text-xs">({item.name})</span>
</div>
</div>
),
},
{
name: "required",
title: t("shared.required"),
value: (item) => (item.required ? <CheckIcon className="text-muted-foreground h-4 w-4" /> : <XIcon className="text-muted-foreground h-4 w-4" />),
},
]}
/> */}
<SlideOverWideEmpty
title={selectedProperty === null ? t("shared.new") : t("shared.edit")}
open={selectedProperty !== undefined}
onClose={() => setSelectedProperty(undefined)}
size="md"
>
{selectedProperty !== undefined && <JsonPropertyForm item={selectedProperty} onClose={() => setSelectedProperty(undefined)} />}
</SlideOverWideEmpty>
<ConfirmModal ref={confirmDelete} destructive onYes={onDeleteConfirmed} />
</div>
);
}