- Introduced `CatalogFieldPickerDialog` and `CatalogFieldPickerList` for selecting catalog fields. - Implemented `appendTemplateFields` helper function for managing template fields. - Added tests for catalog field selection and template field management. - Created reusable components for field picking and reordering in the UI library. - Enhanced drag-and-drop functionality for reordering items in lists.
88 lines
2.8 KiB
TypeScript
88 lines
2.8 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 { InventoryFeedback } from "../../../shared";
|
|
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.inventory.isPending || c.catalog.isPending) && <p role="status">{t("loading")}</p>}
|
|
<InventoryFeedback error={c.inventory.error ?? c.catalog.error} />
|
|
{(c.inventory.isError || c.catalog.isError) && (
|
|
<Button
|
|
onClick={() => {
|
|
c.retry().catch(() => undefined);
|
|
}}
|
|
type="button"
|
|
variant="outline"
|
|
>
|
|
{t("retry")}
|
|
</Button>
|
|
)}
|
|
{c.inventory.data && (
|
|
<AssetPickerList
|
|
assets={c.assets}
|
|
catalog={c.catalog.data?.items ?? []}
|
|
disabled={c.disabled}
|
|
mode={selection.mode ?? "single"}
|
|
onClearFilters={() => {
|
|
c.setSearch("");
|
|
c.setTemplateId(null);
|
|
}}
|
|
onSearchChange={c.setSearch}
|
|
onTemplateChange={(id) => c.setTemplateId(id === "all" ? null : id)}
|
|
onToggle={c.toggle}
|
|
search={c.search}
|
|
selectedIds={c.selectedIds}
|
|
sites={selection.sites}
|
|
templateId={c.templateId}
|
|
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>
|
|
);
|
|
}
|