Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/components/entities/EntitiesTable.tsx
T

124 lines
4.6 KiB
TypeScript

import { useTranslation } from "react-i18next";
import { Link } from "react-router";
import { EntityWithCount } from "~/utils/db/entities/entities.db.server";
import SimpleBadge from "../ui/badges/SimpleBadge";
import { Colors } from "~/application/enums/shared/Colors";
import TableSimple from "../ui/tables/TableSimple";
import RelationshipHelper from "~/utils/helpers/RelationshipHelper";
import OrderListButtons from "../ui/sort/OrderListButtons";
import { useEffect, useState } from "react";
import { RowHeaderDisplayDto } from "~/application/dtos/data/RowHeaderDisplayDto";
import { useAppOrAdminData } from "~/utils/data/useAppOrAdminData";
import { adminPath } from "~/utils/app/CanonicalUrlUtils";
import { translateEntityTitlePlural, translatePropertyTitle } from "~/utils/i18n/translateLabel";
interface Props {
items: EntityWithCount[];
selected?: EntityWithCount[];
onSelected?: (items: EntityWithCount[]) => void;
}
export default function EntitiesTable({ items, selected, onSelected }: Props) {
const appOrAdminData = useAppOrAdminData();
const { t, i18n } = useTranslation();
const [headers, setHeaders] = useState<RowHeaderDisplayDto<EntityWithCount>[]>([]);
useEffect(() => {
const headers: RowHeaderDisplayDto<EntityWithCount>[] = [
{
name: "type",
title: t("models.entity.type"),
value: (item) => (
<SimpleBadge
title={item.type === "all" ? "app-and-admin" : item.type}
color={item.type === "app" ? Colors.BLUE : item.type === "admin" ? Colors.GRAY : Colors.EMERALD}
/>
),
},
{
title: t("shared.order"),
name: "order",
value: (item) => item.order,
formattedValue: (_, idx) => <OrderListButtons index={idx} items={items} />,
},
{
name: "title",
title: t("models.entity.title"),
value: (item) => (
<div className="flex items-center space-x-1">
<Link to={adminPath("entities/" + item.slug + "/details", { mode: "host-aware" })} className="font-medium hover:underline">
{translateEntityTitlePlural(t, i18n, item)}
</Link>
</div>
),
},
{
name: "properties",
title: t("models.property.plural"),
className: "w-full text-xs",
value: (item) => (
<div className="max-w-xs truncate">
{item.properties.filter((f) => !f.isDefault).length > 0 ? (
<Link className="truncate pb-1 hover:underline" to={adminPath("entities/" + item.slug + "/properties", { mode: "host-aware" })}>
{item.properties
.filter((f) => !f.isDefault)
.map((f) => translatePropertyTitle(t, i18n, item.name, f) + (f.isRequired ? "*" : ""))
.join(", ")}
</Link>
) : (
<Link className="text-muted-foreground truncate pb-1 hover:underline" to={adminPath("entities/" + item.slug + "/properties", { mode: "host-aware" })}>
{t("shared.setCustomProperties")}
</Link>
)}
</div>
),
},
{
name: "relationships",
title: t("models.relationship.plural"),
value: (item) => (
<Link className="truncate pb-1 hover:underline" to={adminPath("entities/" + item.slug + "/relationships", { mode: "host-aware" })}>
{[...item.parentEntities, ...item.childEntities]
.map((relationship) => t(RelationshipHelper.getTitleWithName({ fromEntityId: item.id, relationship })))
.join(", ")}
</Link>
),
className: "text-xs",
},
{
name: "rows",
title: t("models.row.plural"),
value: (item) => (
<Link to={adminPath("entities/" + item.slug + "/rows", { mode: "host-aware" })} className="hover:underline">
{item._count.rows}
</Link>
),
},
];
setHeaders(headers);
}, [appOrAdminData.tenantTypes, items, t]);
return (
<div className="space-y-2">
<TableSimple
selectedRows={selected}
onSelected={onSelected}
items={items}
actions={[
{
title: t("models.entity.noCode.menu"),
onClickRoute: (_, item) => adminPath(`entities/${item.slug}/no-code`, { mode: "host-aware" }),
disabled: (i) => !i.isAutogenerated,
},
{
title: t("shared.edit"),
onClickRoute: (_, item) => adminPath(`entities/${item.slug}/details`, { mode: "host-aware" }),
},
]}
headers={headers}
/>
</div>
);
}