metis-desk/packages/rdx-ui/src/components/field-picker-list.tsx
David ccb52fb534 feat: add catalog field picker dialog and list components
- 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.
2026-10-15 15:58:01 +02:00

93 lines
2.4 KiB
TypeScript

import { Checkbox } from "@repo/shadcn-ui/components/checkbox";
import { EntityTable } from "./entity-list";
export type FieldPickerSelection = {
selectedIds: readonly string[];
disabled: (id: string) => boolean;
onToggle: (id: string) => void;
};
/** Tabla de selección de campos; datos y textos pertenecen al consumidor. */
export function FieldPickerList({
fields,
labels,
locale,
selectedIds,
disabled,
onToggle,
}: FieldPickerSelection & {
fields: readonly { id: string; name: string; description: string; type: string; unit: string }[];
labels: {
title: string;
name: string;
type: string;
unit: string;
select: string;
selectField: (name: string) => string;
empty: string;
fields: string;
search: string;
};
locale: string;
}) {
return (
<EntityTable
columns={[
{
id: "selection",
label: labels.select,
hideable: false,
render: (field) => (
<Checkbox
aria-label={labels.selectField(field.name)}
checked={selectedIds.includes(field.id)}
disabled={disabled(field.id)}
onCheckedChange={() => onToggle(field.id)}
/>
),
},
{
id: "name",
label: labels.name,
hideable: false,
value: (field) => `${field.name} ${field.description}`,
render: (field) => (
<div className="space-y-1">
<span className="font-medium">{field.name}</span>
{field.description && (
<p className="text-xs text-muted-foreground">{field.description}</p>
)}
</div>
),
},
{
id: "type",
label: labels.type,
value: (field) => field.type,
render: (field) => field.type,
},
{
id: "unit",
label: labels.unit,
value: (field) => field.unit,
render: (field) => field.unit,
},
]}
emptyMessage={labels.empty}
entityLabel={labels.fields}
items={fields}
layout="fill"
locale={locale}
onRowClick={(field) => {
if (!disabled(field.id)) {
onToggle(field.id);
}
}}
rowClassName={(field) => (disabled(field.id) ? "cursor-not-allowed!" : "")}
searchPlaceholder={labels.search}
title={labels.title}
/>
);
}