75 lines
2.8 KiB
TypeScript
75 lines
2.8 KiB
TypeScript
import { useTranslation } from "react-i18next";
|
|
|
|
import type { ResourceDTO } from "../common/inventory";
|
|
|
|
export function ResourceDetail({ resource }: { resource: ResourceDTO }) {
|
|
const { t, i18n } = useTranslation("resources");
|
|
const display = (value: string | number | boolean | undefined) =>
|
|
value === undefined
|
|
? t("noValue")
|
|
: typeof value === "boolean"
|
|
? t(value ? "yes" : "no")
|
|
: String(value);
|
|
return (
|
|
<div className="space-y-5">
|
|
<p className="text-sm text-muted-foreground">{t("snapshotNotice")}</p>
|
|
<dl className="grid gap-4 sm:grid-cols-2">
|
|
<div>
|
|
<dt className="text-sm text-muted-foreground">{t("template")}</dt>
|
|
<dd>{resource.specification.templateName}</dd>
|
|
</div>
|
|
<div>
|
|
<dt className="text-sm text-muted-foreground">{t("status")}</dt>
|
|
<dd>{t(resource.values.active ? "active" : "inactive")}</dd>
|
|
</div>
|
|
{resource.specification.fields.map((field) => (
|
|
<div key={field.fieldId}>
|
|
<dt className="text-sm text-muted-foreground">
|
|
{field.name}
|
|
{field.unit ? ` (${field.unit})` : ""}
|
|
</dt>
|
|
<dd className="whitespace-pre-wrap break-words">
|
|
{display(resource.values.characteristics[field.fieldId])}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
{resource.values.notes && (
|
|
<p className="whitespace-pre-wrap break-words">{resource.values.notes}</p>
|
|
)}
|
|
<h3 className="font-medium">
|
|
{t("history")} ({resource.history.length})
|
|
</h3>
|
|
<ol className="space-y-4">
|
|
{[...resource.history].reverse().map((revision) => (
|
|
<li className="space-y-2 rounded-md border p-3 text-sm" key={revision.id}>
|
|
<p className="font-medium">
|
|
{new Intl.DateTimeFormat(i18n.language, {
|
|
dateStyle: "medium",
|
|
timeStyle: "short",
|
|
}).format(new Date(revision.recordedAt))}{" "}
|
|
· {t("recordedBy", { name: revision.actorName })}
|
|
</p>
|
|
<p>
|
|
{revision.values.name} · {t(revision.values.active ? "active" : "inactive")}
|
|
</p>
|
|
<dl className="grid gap-2 sm:grid-cols-2">
|
|
{resource.specification.fields.map((field) => (
|
|
<div key={field.fieldId}>
|
|
<dt className="text-muted-foreground">{field.name}</dt>
|
|
<dd className="whitespace-pre-wrap break-words">
|
|
{display(revision.values.characteristics[field.fieldId])}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
{revision.values.notes && (
|
|
<p className="whitespace-pre-wrap break-words">{revision.values.notes}</p>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</div>
|
|
);
|
|
}
|