219 lines
7.7 KiB
TypeScript
219 lines
7.7 KiB
TypeScript
import { Link } from "react-router";
|
|
import { useTranslation } from "react-i18next";
|
|
import TenantBadge from "~/components/core/tenants/TenantBadge";
|
|
import UserBadge from "~/components/core/users/UserBadge";
|
|
import DateCell from "~/components/ui/dates/DateCell";
|
|
import CheckIcon from "~/components/ui/icons/CheckIcon";
|
|
import XIcon from "~/components/ui/icons/XIcon";
|
|
import ShowPayloadModalButton from "~/components/ui/json/ShowPayloadModalButton";
|
|
import TableSimple from "~/components/ui/tables/TableSimple";
|
|
import { EntityViewWithTenantAndUser } from "~/utils/db/entities/entityViews.db.server";
|
|
import { defaultDisplayProperties } from "~/utils/helpers/PropertyHelper";
|
|
import EntityViewLayoutBadge from "./EntityViewLayoutBadge";
|
|
import { adminPath } from "~/utils/app/CanonicalUrlUtils";
|
|
import { useLocaleFormatters } from "~/locale/format";
|
|
import { translateEntityTitlePlural, translateEntityViewTitle } from "~/utils/i18n/translateLabel";
|
|
|
|
export default function EntityViewsTable({
|
|
items,
|
|
onClickRoute,
|
|
}: {
|
|
items: EntityViewWithTenantAndUser[];
|
|
onClickRoute: (item: EntityViewWithTenantAndUser) => string;
|
|
}) {
|
|
const { t, i18n } = useTranslation();
|
|
const formatters = useLocaleFormatters();
|
|
return (
|
|
<TableSimple
|
|
items={items}
|
|
actions={[
|
|
{
|
|
title: t("shared.edit"),
|
|
onClickRoute: (_, i) => onClickRoute(i),
|
|
},
|
|
]}
|
|
headers={[
|
|
// {
|
|
// name: "debug",
|
|
// title: "Debug",
|
|
// value: (i) => (
|
|
// <div>
|
|
// <ShowPayloadModalButton title="Debug" description="Debug" payload={JSON.stringify(i, null, 2)} />
|
|
// </div>
|
|
// ),
|
|
// },
|
|
{
|
|
name: "entity",
|
|
title: t("models.entity.object"),
|
|
value: (i) => (
|
|
<div className="flex flex-col">
|
|
<div>{translateEntityTitlePlural(t, i18n, i.entity)}</div>
|
|
{/* <div className="text-xs text-muted-foreground">{i.entity.name}</div> */}
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "Layout",
|
|
title: t("models.view.layout"),
|
|
value: (i) => (
|
|
<div>
|
|
<EntityViewLayoutBadge layout={i.layout} className="text-muted-foreground mx-auto h-5 w-5" />
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "title",
|
|
title: t("models.view.title"),
|
|
className: "w-full",
|
|
value: (i) => (
|
|
<div className="flex flex-col">
|
|
<Link to={adminPath(`entities/views/${i.id}`, { mode: "host-aware" })} className="hover:underline">
|
|
{translateEntityViewTitle(t, i18n, i.entity.name, i)}
|
|
</Link>
|
|
{/* <div className="text-xs text-muted-foreground">{i.name}</div> */}
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "appliesTo",
|
|
title: t("models.view.appliesTo"),
|
|
value: (i) => (
|
|
<div className="flex items-center space-x-1">
|
|
<div>
|
|
{i.isSystem ? (
|
|
<div className="font-medium italic">{t("models.view.appliesToStates.systemView")}</div>
|
|
) : !i.tenant && !i.user ? (
|
|
<div className="flex flex-col">
|
|
<div className="font-medium italic">{t("models.view.appliesToStates.defaultAllAccounts")}</div>
|
|
</div>
|
|
) : i.tenant && i.user ? (
|
|
<div className="flex items-center space-x-1">
|
|
<div>
|
|
<TenantBadge item={i.tenant} />
|
|
</div>
|
|
<div>→</div>
|
|
<UserBadge item={i.user} />
|
|
</div>
|
|
) : i.tenant ? (
|
|
<div>
|
|
<TenantBadge item={i.tenant} />
|
|
</div>
|
|
) : i.user ? (
|
|
<div>
|
|
<UserBadge item={i.user} />
|
|
</div>
|
|
) : (
|
|
<div className="italic text-red-500">{t("models.view.appliesToStates.invalid")}</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "properties",
|
|
title: t("models.view.properties"),
|
|
value: (i) => {
|
|
return (
|
|
<div>
|
|
{/* {i.properties
|
|
.map((p) => {
|
|
const defaultProperty = defaultDisplayProperties.find((f) => f.name === p.name);
|
|
if (defaultProperty) {
|
|
return t(defaultProperty.title);
|
|
}
|
|
return p.name;
|
|
})
|
|
.join(", ")} */}
|
|
<ShowPayloadModalButton
|
|
description={t("models.view.payload.propertiesCount", { count: i.properties.length })}
|
|
title={t("models.view.properties")}
|
|
payload={JSON.stringify(
|
|
i.properties.map((p) => {
|
|
const defaultProperty = defaultDisplayProperties.find((f) => f.name === p.name);
|
|
if (defaultProperty) {
|
|
return t(defaultProperty.title);
|
|
}
|
|
return p.name;
|
|
}),
|
|
null,
|
|
2
|
|
)}
|
|
/>
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
name: "filters",
|
|
title: t("models.view.filters"),
|
|
value: (i) => (
|
|
<div>
|
|
<ShowPayloadModalButton
|
|
description={t("models.view.payload.filtersCount", { count: i.filters.length })}
|
|
title={t("models.view.filters")}
|
|
payload={JSON.stringify(
|
|
i.filters.map((p) => {
|
|
return `${p.name} ${p.condition} ${p.value}`;
|
|
}),
|
|
null,
|
|
2
|
|
)}
|
|
/>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "sort",
|
|
title: t("models.view.sort"),
|
|
value: (i) => (
|
|
<div>
|
|
<ShowPayloadModalButton
|
|
description={t("models.view.payload.sortCount", { count: i.sort.length })}
|
|
title={t("models.view.sort")}
|
|
payload={JSON.stringify(
|
|
i.sort.map((p) => {
|
|
return `${p.name} ${p.asc ? "asc" : "desc"}`;
|
|
}),
|
|
null,
|
|
2
|
|
)}
|
|
/>
|
|
</div>
|
|
),
|
|
},
|
|
{
|
|
name: "pageSize",
|
|
title: t("models.view.pageSize"),
|
|
value: (i) => <div>{formatters.number(i.pageSize)}</div>,
|
|
},
|
|
{
|
|
name: "isDefault",
|
|
title: t("models.view.isDefault"),
|
|
value: (i) => <div>{i.isDefault ? <CheckIcon className="h-5 w-5 text-green-500" /> : <XIcon className="text-muted-foreground h-5 w-5" />}</div>,
|
|
},
|
|
{
|
|
name: "updatedAt",
|
|
title: t("shared.updatedAt"),
|
|
value: (i) => <DateCell date={i.updatedAt ?? null} />,
|
|
},
|
|
{
|
|
name: "createdAt",
|
|
title: t("shared.createdAt"),
|
|
value: (i) => <DateCell date={i.createdAt ?? null} />,
|
|
},
|
|
{
|
|
name: "createdBy",
|
|
title: t("shared.createdBy"),
|
|
value: (i) => (i.createdByUser ? <UserBadge item={i.createdByUser} /> : <div>-</div>),
|
|
},
|
|
]}
|
|
noRecords={
|
|
<div className="p-12 text-center">
|
|
<h3 className="text-foreground mt-1 text-sm font-medium">{t("models.view.empty.title")}</h3>
|
|
<p className="text-muted-foreground mt-1 text-sm">{t("models.view.empty.description")}</p>
|
|
</div>
|
|
}
|
|
/>
|
|
);
|
|
}
|