- 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.
93 lines
2.4 KiB
TypeScript
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}
|
|
/>
|
|
);
|
|
}
|