metis-desk/modules/assets/src/web/assets/select/ui/asset-picker-dialog.tsx
2026-10-25 01:19:17 +02:00

93 lines
2.9 KiB
TypeScript

import { FormActions, FormBody, FormDialog } from "@repo/rdx-ui/components/form-dialog";
import { Button } from "@repo/shadcn-ui/components/button";
import { useTranslation } from "react-i18next";
import { useAssetPickerController } from "../controllers/use-asset-picker-controller";
import type { AssetSelectProps } from "../types/asset-select-props";
import { AssetPickerList } from "./asset-picker-list";
export function AssetPickerDialog({
selection,
onClose,
}: {
selection: AssetSelectProps;
onClose: () => void;
}) {
const { t } = useTranslation("assets");
const c = useAssetPickerController(selection, onClose);
return (
<FormDialog
cancelLabel={t("cancel")}
formActions
layout="picker"
onOpenChange={(open) => {
if (!open) {
onClose();
}
}}
open
title={t(selection.mode === "multiple" ? "assetPicker.multiple" : "assetPicker.single")}
wide
>
<FormBody>
<p className="text-sm text-muted-foreground">{selection.label}</p>
{c.infrastructure.isError && (
<p className="text-sm text-destructive" role="alert">
{t("assetColumns.infrastructureError")}
</p>
)}
{c.infrastructure.isError && (
<Button
onClick={() => {
return c.infrastructure.refetch();
}}
type="button"
variant="outline"
>
{t("retry")}
</Button>
)}
<AssetPickerList
assets={c.assets}
catalog={c.catalog.data?.items ?? []}
disabled={c.disabled}
infrastructure={c.infrastructure.data?.items ?? []}
loading={c.inventory.isPending || c.catalog.isPending}
mode={selection.mode ?? "single"}
onClearFilters={() => {
c.setSearch("");
c.setTemplateId(null);
}}
onRetry={c.denied ? undefined : c.retry}
onSearchChange={c.setSearch}
onTemplateChange={(id) => c.setTemplateId(id === "all" ? null : id)}
onToggle={c.toggle}
search={c.search}
selectedIds={c.selectedIds}
sites={selection.sites}
state={c.state}
templateId={c.templateId}
unavailable={c.inventory.isError || c.catalog.isError}
unavailableLabels={
new Map(
selection.options
.filter((option) => option.disabled)
.map((option) => [option.value, option.label])
)
}
/>
<p aria-live="polite" className="text-sm text-muted-foreground">
{t("assetPicker.selected", { count: c.selectedIds.length })}
</p>
</FormBody>
<FormActions>
<Button disabled={!c.canConfirm} onClick={c.confirm} type="button">
{t("assetPicker.confirm")}
</Button>
</FormActions>
</FormDialog>
);
}