119 lines
4.4 KiB
TypeScript
119 lines
4.4 KiB
TypeScript
|
|
import { inventoryApi, inventoryKeys } from "@metis/assets/client";
|
||
|
|
import { BrowserLink, useListQuery } from "@metis/core/client";
|
||
|
|
import { Button } from "@repo/shadcn-ui/components/button";
|
||
|
|
import { useTranslation } from "react-i18next";
|
||
|
|
|
||
|
|
import type { CompanyDTO } from "../../../../common";
|
||
|
|
import { printerApi, printerKeys } from "../../../printer-configurations/shared/api";
|
||
|
|
import { profileApi, profileKeys } from "../../../work-profiles/shared/api";
|
||
|
|
import { printerUsage } from "../helpers/printer-usage";
|
||
|
|
|
||
|
|
export function AssetPrinterUsage({ company, assetId }: { company: CompanyDTO; assetId: string }) {
|
||
|
|
const { t } = useTranslation("companies");
|
||
|
|
const printers = useListQuery({
|
||
|
|
queryKey: printerKeys.company(company.id),
|
||
|
|
queryFn: () => printerApi.get(company.id),
|
||
|
|
});
|
||
|
|
const profiles = useListQuery({
|
||
|
|
queryKey: profileKeys.company(company.id),
|
||
|
|
queryFn: () => profileApi.get(company.id),
|
||
|
|
});
|
||
|
|
const inventory = useListQuery({
|
||
|
|
queryKey: inventoryKeys.company(company.id),
|
||
|
|
queryFn: () => inventoryApi.get(company.id),
|
||
|
|
});
|
||
|
|
const failed = printers.isError || profiles.isError || inventory.isError;
|
||
|
|
const usage = printerUsage(
|
||
|
|
assetId,
|
||
|
|
printers.data?.configurations ?? [],
|
||
|
|
profiles.data?.profiles ?? [],
|
||
|
|
inventory.data?.assets ?? []
|
||
|
|
);
|
||
|
|
|
||
|
|
if (printers.isPending || profiles.isPending || inventory.isPending) {
|
||
|
|
return <p role="status">{t("loading")}</p>;
|
||
|
|
}
|
||
|
|
if (failed) {
|
||
|
|
return (
|
||
|
|
<div>
|
||
|
|
<p role="alert">{t("infrastructureUsage.error")}</p>
|
||
|
|
<Button
|
||
|
|
onClick={() => {
|
||
|
|
Promise.all([printers.refetch(), profiles.refetch(), inventory.refetch()]).catch(
|
||
|
|
() => undefined
|
||
|
|
);
|
||
|
|
}}
|
||
|
|
size="sm"
|
||
|
|
variant="outline"
|
||
|
|
>
|
||
|
|
{t("retry")}
|
||
|
|
</Button>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="space-y-3">
|
||
|
|
{!usage.groups.length && (
|
||
|
|
<p className="text-sm text-muted-foreground">{t("infrastructureUsage.empty")}</p>
|
||
|
|
)}
|
||
|
|
{usage.unresolved.length > 0 && <p role="alert">{t("infrastructureUsage.incomplete")}</p>}
|
||
|
|
<ul className="space-y-3">
|
||
|
|
{usage.groups.map((group) => (
|
||
|
|
<li className="rounded-md border p-3 text-sm" key={group.id}>
|
||
|
|
<BrowserLink
|
||
|
|
className="font-medium"
|
||
|
|
href={`/companies/${company.id}/assets/${group.id}`}
|
||
|
|
>
|
||
|
|
{group.name}
|
||
|
|
</BrowserLink>
|
||
|
|
<ul className="mt-2 space-y-2">
|
||
|
|
{group.configurations.map(({ profile, configuration }) => (
|
||
|
|
<li key={configuration.id}>
|
||
|
|
<BrowserLink href={`/companies/${company.id}/work-profiles/${profile.id}`}>
|
||
|
|
{profile.values.name}
|
||
|
|
</BrowserLink>{" "}
|
||
|
|
·{" "}
|
||
|
|
{company.people.find((person) => person.id === profile.values.personId)?.name ??
|
||
|
|
"—"}
|
||
|
|
<p className="text-muted-foreground">
|
||
|
|
{t(`mail.${configuration.values.state}`)} ·{" "}
|
||
|
|
{t(`printers.${configuration.values.connection}`)}
|
||
|
|
{configuration.values.isDefault ? ` · ${t("infrastructureUsage.default")}` : ""}
|
||
|
|
</p>
|
||
|
|
{(!profile.values.active || configuration.needsReview) && (
|
||
|
|
<p className="text-amber-700 dark:text-amber-400">
|
||
|
|
{t("infrastructureUsage.review")}
|
||
|
|
</p>
|
||
|
|
)}
|
||
|
|
</li>
|
||
|
|
))}
|
||
|
|
</ul>
|
||
|
|
</li>
|
||
|
|
))}
|
||
|
|
</ul>
|
||
|
|
{usage.history.length > 0 && (
|
||
|
|
<details>
|
||
|
|
<summary className="cursor-pointer text-sm">
|
||
|
|
{t("infrastructureUsage.history", { count: usage.history.length })}
|
||
|
|
</summary>
|
||
|
|
<ul className="mt-2 space-y-2">
|
||
|
|
{usage.history.map((item) => (
|
||
|
|
<li className="text-sm" key={item.id}>
|
||
|
|
<BrowserLink
|
||
|
|
href={`/companies/${company.id}/work-profiles/${item.values.profileId}`}
|
||
|
|
>
|
||
|
|
{profiles.data?.profiles.find((profile) => profile.id === item.values.profileId)
|
||
|
|
?.values.name ?? "—"}
|
||
|
|
</BrowserLink>{" "}
|
||
|
|
· {t(`mail.${item.values.state}`)}
|
||
|
|
</li>
|
||
|
|
))}
|
||
|
|
</ul>
|
||
|
|
</details>
|
||
|
|
)}
|
||
|
|
<p className="text-xs text-muted-foreground">{t("infrastructureUsage.notice")}</p>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|