import { Fragment } from "react"; import { ColumnDto } from "~/application/dtos/data/ColumnDto"; import { EntityWithDetails, PropertyWithDetails } from "../db/entities/entities.db.server"; import { RowWithDetails } from "../db/entities/rows.db.server"; import DateUtils from "../shared/DateUtils"; import RowHelper from "./RowHelper"; import { RowHeaderDisplayDto } from "~/application/dtos/data/RowHeaderDisplayDto"; import { EntitiesApi } from "../api/.server/EntitiesApi"; import EntityHelper from "./EntityHelper"; import SimpleBadge from "~/components/ui/badges/SimpleBadge"; import { Colors } from "~/application/enums/shared/Colors"; import { TFunction, i18n as I18nextInstance } from "i18next"; import { RowDisplayDefaultProperty } from "./PropertyHelper"; import DateCell from "~/components/ui/dates/DateCell"; import RowCreatedByCell from "~/components/entities/rows/cells/RowCreatedByCell"; import RowFolioCell from "~/components/entities/rows/cells/RowFolioCell"; import RowTagsCell from "~/components/entities/rows/cells/RowTagsCell"; import RowOrderButtons from "~/components/entities/rows/RowOrderButtons"; import RowRelationshipRow from "~/components/entities/rows/cells/RowRelationshipRow"; import RowRelationshipRowsByEntity from "~/components/entities/rows/cells/RowRelationshipRowsByEntity"; import { translateEntityTitle, translateEntityTitlePlural, translatePropertyTitle } from "~/utils/i18n/translateLabel"; function isColumnVisible(columns?: ColumnDto[], name?: string) { if (!columns) { return true; } const column = columns?.find((f) => f.name === name); if (!columns || !column) { return false; } return column.visible; } function displayTenant(t: TFunction): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.TENANT, title: "models.tenant.object", value: (item) =>
{item.tenant === null ?
{t("shared.admin")}
:
{item.tenant.name}
}
, // href: (item) => item.tenant?.id ?? "", breakpoint: "sm", }; } function displayFolio(entity: EntityWithDetails, routes?: EntitiesApi.Routes, onClick?: (item: RowWithDetails) => void): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.FOLIO, title: "models.row.folio", value: (item) => ( onClick(item) : undefined} /> ), // breakpoint: "sm", sortable: true, }; } function displayOrder(): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.ORDER, title: "", className: "w-12", value: (item) => , }; } function displayTags(): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.TAGS, title: "models.tag.plural", value: (item) => , breakpoint: "sm", sortable: true, }; } function translatedEntityTitleKey( t: TFunction, i18n: Pick | null | undefined, entity: { name: string; title?: string | null } ): string { const key = `models.${entity.name}.object`; return i18n?.exists(key) ? key : translateEntityTitle(t, i18n, entity); } function translatedEntityTitlePluralKey( t: TFunction, i18n: Pick | null | undefined, entity: { name: string; titlePlural?: string | null } ): string { const key = `models.${entity.name}.plural`; return i18n?.exists(key) ? key : translateEntityTitlePlural(t, i18n, entity); } function translatedPropertyTitleKey( t: TFunction, i18n: Pick | null | undefined, entityName: string, property: { name: string; title?: string | null } ): string { const key = `models.${entityName}.${property.name}`; return i18n?.exists(key) ? key : translatePropertyTitle(t, i18n, entityName, property); } function displayProperty( entity: EntityWithDetails, property: PropertyWithDetails, i18n: Pick | null | undefined, t: TFunction, layout?: string ): RowHeaderDisplayDto { return { name: property.name, title: translatedPropertyTitleKey(t, i18n, entity.name, property), value: (item) => RowHelper.getPropertyValue({ entity, item, property }), formattedValue: (item) =>
{RowHelper.getCellValue({ entity, property, item })}
, }; } function displayCreatedAt(): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.CREATED_AT, title: "shared.createdAt", value: (item) => DateUtils.dateAgo(item.createdAt), formattedValue: (item) => , className: "text-muted-foreground text-xs", breakpoint: "sm", }; } function displayCreatedBy(): RowHeaderDisplayDto { return { name: RowDisplayDefaultProperty.CREATED_BY, title: "shared.createdBy", value: (item) => , className: "text-muted-foreground text-xs", breakpoint: "sm", }; } function getDisplayedHeaders({ entity, columns, layout, allEntities, routes, onFolioClick, onEditClick, onRelatedRowClick, t, i18n, }: { entity: EntityWithDetails; columns?: ColumnDto[]; layout?: string; allEntities: EntityWithDetails[]; routes?: EntitiesApi.Routes; onFolioClick?: (item: RowWithDetails) => void; onEditClick?: (item: RowWithDetails) => void; onRelatedRowClick?: (item: RowWithDetails) => void; t: TFunction; i18n?: Pick | null; }): RowHeaderDisplayDto[] { let headers: RowHeaderDisplayDto[] = []; if (columns && isColumnVisible(columns, RowDisplayDefaultProperty.ID)) { headers.push({ name: RowDisplayDefaultProperty.ID, title: "ID", value: (item) => (
{onEditClick !== undefined ? ( ) : (
{item.id}
)}
), href: (item) => (onEditClick === undefined ? item.id : undefined), breakpoint: "sm", }); } if (columns && isColumnVisible(columns, RowDisplayDefaultProperty.ENTITY)) { headers.push({ name: RowDisplayDefaultProperty.ENTITY, title: "models.row.entity", value: () => translateEntityTitle(t, i18n, entity), }); } if (columns && isColumnVisible(columns, RowDisplayDefaultProperty.TENANT)) { headers.push(displayTenant(t)); } if (columns && isColumnVisible(columns, RowDisplayDefaultProperty.ORDER) && layout === "table") { headers.push(displayOrder()); } if (isColumnVisible(columns, RowDisplayDefaultProperty.FOLIO)) { headers.push(displayFolio(entity, routes, onFolioClick)); } entity.properties .filter((f) => !f.isHidden && isColumnVisible(columns, f.name)) .forEach((property) => { headers.push(displayProperty(entity, property, i18n, t, layout)); }); entity.parentEntities .filter((f) => !f.hiddenIfEmpty) .forEach((relationship) => { const parentEntity = allEntities.find((f) => f.id === relationship.parentId); if (parentEntity && isColumnVisible(columns, `parent.${parentEntity.name}`)) { headers.push({ name: `parent.${parentEntity.name}`, title: translatedEntityTitleKey(t, i18n, parentEntity), value: (item) => (
{!item.parentRows?.length || item.parentRows.length === 0 ? (
{t("shared.none")}
) : ( {item.parentRows ?.filter((f) => f.relationshipId === relationship.id) .map(({ parent }) => { return ( onRelatedRowClick(item) : undefined} routes={routes} t={t} /> ); })} )}
), }); } }); entity.childEntities .filter((f) => !f.hiddenIfEmpty) .forEach((relationship) => { const childEntity = allEntities.find((f) => f.id === relationship.childId); if (childEntity && isColumnVisible(columns, `child.${childEntity.name}`)) { headers.push({ name: `child.${childEntity.name}`, title: translatedEntityTitlePluralKey(t, i18n, childEntity), value: (item) => (
    {!item.childRows?.length || item.childRows.length === 0 ? (
    {t("shared.none")}
    ) : ( {childEntity.properties.filter((f) => !f.isDefault && f.isDisplay).length === 0 ? (
    ) : ( {item.childRows ?.filter((f) => f.relationshipId === relationship.id) .map(({ child }) => { return (
  • onRelatedRowClick(item) : undefined} routes={routes} t={t} />
  • ); })}
    )}
    )}
), }); } }); if (isColumnVisible(columns, RowDisplayDefaultProperty.HIDDEN_PARENTS)) { headers.push({ name: RowDisplayDefaultProperty.HIDDEN_PARENTS, title: "", value: (item) => ( onRelatedRowClick(item) : undefined} routes={routes} allEntities={allEntities} type="parents" /> ), }); } if (isColumnVisible(columns, RowDisplayDefaultProperty.HIDDEN_CHILDREN)) { headers.push({ name: RowDisplayDefaultProperty.HIDDEN_CHILDREN, title: "", value: (item) => ( onRelatedRowClick(item) : undefined} routes={routes} allEntities={allEntities} type="children" /> ), }); } if (isColumnVisible(columns, RowDisplayDefaultProperty.CREATED_AT)) { headers.push(displayCreatedAt()); } if (isColumnVisible(columns, RowDisplayDefaultProperty.CREATED_BY)) { headers.push(displayCreatedBy()); } if (columns && isColumnVisible(columns, RowDisplayDefaultProperty.PERMISSIONS)) { headers.push({ name: RowDisplayDefaultProperty.PERMISSIONS, title: "models.row.permissions", value: () =>
{t("shared.notAvailable")}
, }); } if (columns && entity.hasTags && isColumnVisible(columns, RowDisplayDefaultProperty.TAGS)) { headers.push(displayTags()); } if (columns && entity.hasTasks && isColumnVisible(columns, RowDisplayDefaultProperty.TASKS)) { headers.push({ name: RowDisplayDefaultProperty.TASKS, title: "models.row.tasks", value: () =>
{t("shared.notAvailable")}
, }); } if (columns && entity.hasComments && isColumnVisible(columns, RowDisplayDefaultProperty.COMMENTS)) { headers.push({ name: RowDisplayDefaultProperty.COMMENTS, title: "models.row.comments", value: () =>
{t("shared.notAvailable")}
, }); } if (columns && columns.length > 0) { const newOrder: RowHeaderDisplayDto[] = []; columns.forEach((column) => { const header = headers.find((f) => f.name === column.name); if (header && !newOrder.includes(header)) { newOrder.push(header); } }); headers = newOrder; } let nonDefaultHeaders = headers.filter((f) => !f.name?.startsWith("default.")); if (nonDefaultHeaders.length === 1) { nonDefaultHeaders[0].className = "w-full"; } return headers; } export default { isColumnVisible, displayTenant, displayFolio, displayProperty, displayCreatedAt, displayCreatedBy, getDisplayedHeaders, };