@asteby/metacore-runtime-react 23.8.0 → 23.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/custom-stages.d.ts +96 -1
  3. package/dist/custom-stages.d.ts.map +1 -1
  4. package/dist/custom-stages.js +259 -24
  5. package/dist/dynamic-form-schema.d.ts +18 -1
  6. package/dist/dynamic-form-schema.d.ts.map +1 -1
  7. package/dist/dynamic-form-schema.js +43 -0
  8. package/dist/dynamic-form.d.ts.map +1 -1
  9. package/dist/dynamic-form.js +30 -9
  10. package/dist/dynamic-kanban.d.ts +8 -0
  11. package/dist/dynamic-kanban.d.ts.map +1 -1
  12. package/dist/dynamic-kanban.js +188 -16
  13. package/dist/dynamic-line-items.d.ts.map +1 -1
  14. package/dist/dynamic-line-items.js +24 -3
  15. package/dist/dynamic-table.d.ts.map +1 -1
  16. package/dist/dynamic-table.js +5 -0
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -1
  20. package/dist/stage-overrides.d.ts +25 -0
  21. package/dist/stage-overrides.d.ts.map +1 -0
  22. package/dist/stage-overrides.js +64 -0
  23. package/dist/types.d.ts +69 -4
  24. package/dist/types.d.ts.map +1 -1
  25. package/package.json +3 -3
  26. package/src/__tests__/dependent-enum-form.test.tsx +84 -0
  27. package/src/__tests__/dependent-enum-options.test.ts +67 -0
  28. package/src/__tests__/dynamic-kanban.test.tsx +75 -0
  29. package/src/__tests__/stage-overrides.test.tsx +293 -0
  30. package/src/custom-stages.tsx +716 -109
  31. package/src/dynamic-form-schema.ts +44 -1
  32. package/src/dynamic-form.tsx +76 -28
  33. package/src/dynamic-kanban.tsx +236 -25
  34. package/src/dynamic-line-items.tsx +26 -2
  35. package/src/dynamic-table.tsx +4 -0
  36. package/src/index.ts +13 -0
  37. package/src/stage-overrides.ts +95 -0
  38. package/src/types.ts +63 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 23.9.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 3db80ab: fix(data-table/kanban): indicadores de filtro sin duplicados y tarjetas kanban con relaciones resueltas
8
+ - El botón "Limpiar filtros" del toolbar ya no muestra badge de conteo y solo aparece para el estado propio de la tabla (column filters / búsqueda); los filtros dinámicos ya tienen su fila de chips con "Limpiar todo".
9
+ - El icono de filtro del header de columna ya no superpone un badge de conteo: el icono en color primary es el único indicador activo.
10
+ - `f_<col>=eq:<valor>` en la URL se desenvuelve al valor plano, por lo que el chip muestra la etiqueta de la opción ("Estado: Recepción") en vez de `eq:reception`.
11
+ - Las tarjetas del kanban resuelven columnas FK (`<rel>_id`) al objeto hermano resuelto por el backend (nombre/label) en vez del UUID crudo, y un FK UUID-cero se muestra como vacío (—).
12
+
13
+ - Updated dependencies [3db80ab]
14
+ - @asteby/metacore-ui@2.9.2
15
+
16
+ ## 23.9.0
17
+
18
+ ### Minor Changes
19
+
20
+ - 0c41860: DynamicKanban: per-lane configuration gear (⚙). Every board lane — declared
21
+ stages (Backlog, Done…) included, not just custom ones — now carries a subtle
22
+ gear next to the search/filter/⚡ header icons that opens a "Configurar etapa"
23
+ dialog to rename the lane, recolor it, and attach extra CONDITIONS (a
24
+ field/operator/value builder reusing the same eq/neq/contains/in component as
25
+ custom stages).
26
+ - Declared lanes persist through a new `/stage-overrides` endpoint
27
+ (`useStageOverrides`), with a "Restablecer etapa" action that drops the
28
+ override; custom real stages persist through their existing `/custom-stages`
29
+ CRUD (which now also accepts `filters`). The gear unifies both behind one UI.
30
+ - A lane that carries conditions queries its data — and counts its header —
31
+ with the stage scope PLUS those conditions (serialized like smart-lane
32
+ filters), and shows a filter indicator + tooltip listing them. Cards can still
33
+ be dragged into the lane (the drop only sets the stage value).
34
+ - The dialog pre-populates the whole form from the lane's live metadata (label,
35
+ color and every condition, editable) and opens with a "Condiciones actuales"
36
+ chip row summarizing the effective query: a locked base "Etapa = <label>" chip,
37
+ an "Etapa final" chip (with tooltip) for terminal stages, and one
38
+ editable/removable chip per extra condition. An overridden lane shows a
39
+ "Personalizada" badge and a two-step "Restablecer al original" that spells out
40
+ exactly what reverts (from `metadata.stages[].original` when the host serves it).
41
+ - Non-intrusive: when `/stage-overrides` is absent the gear simply doesn't
42
+ render on declared lanes. All copy goes through `t('dynamic.stage_config.*')`
43
+ with Spanish defaults.
44
+
45
+ New exports: `useStageOverrides`, `StageConfigDialog`, `StageConditionBuilder`,
46
+ `cardMatchesStageFilters`, and their types. `StageMeta` gains optional
47
+ `overridden` and `filters`.
48
+
3
49
  ## 23.8.0
4
50
 
5
51
  ### Minor Changes
@@ -57,7 +57,11 @@ export declare function mergeLaneStages(declared: StageMeta[], customLaneStages:
57
57
  * - in → `f_<field>=IN:v1,v2,...` (comma-separated after `IN:`)
58
58
  * Empty fields/values are skipped.
59
59
  */
60
- export declare function smartLaneParams(filters: CustomStageFilter[] | undefined): Record<string, string>;
60
+ export declare function smartLaneParams(filters: {
61
+ field: string;
62
+ op: string;
63
+ value: string;
64
+ }[] | undefined): Record<string, string>;
61
65
  /**
62
66
  * Resolves the smart lanes to paint. The kernel's `metadata.smart_lanes` is the
63
67
  * source of truth for rendering (ops #704); the CRUD list only backs the
@@ -75,6 +79,17 @@ export declare function isCustomStageDraftValid(draft: {
75
79
  type: CustomStageType;
76
80
  filters: CustomStageFilter[];
77
81
  }): boolean;
82
+ /**
83
+ * Whether a card passes a set of extra lane `filters` (the same conditions a
84
+ * smart lane uses, layered on top of a real stage). Ops:
85
+ * - eq → equal (string compare)
86
+ * - neq → not equal
87
+ * - contains → the card's value (array or string) includes the value
88
+ * - in → the card's value is one of the comma-separated candidates
89
+ * Empty/absent filters pass. Pure — a client-side belt-and-suspenders over the
90
+ * initial (unscoped) board page; the server scopes the per-lane top-up queries.
91
+ */
92
+ export declare function cardMatchesStageFilters(card: any, filters: CustomStageFilter[] | undefined): boolean;
78
93
  /** Slugify a label into a stable-ish lane key (used only when creating). */
79
94
  export declare function slugifyStageKey(label: string): string;
80
95
  export interface UseCustomStagesResult {
@@ -111,6 +126,23 @@ export interface CustomStageLaneMenuProps {
111
126
  }
112
127
  /** The ⋮ menu shown in a custom lane's header. */
113
128
  export declare function CustomStageLaneMenu({ stage, onEdit, onDelete, }: CustomStageLaneMenuProps): React.JSX.Element;
129
+ export interface StageConditionBuilderProps {
130
+ /** The current filter rows. */
131
+ filters: CustomStageFilter[];
132
+ /** Called with the next filter rows on any add/remove/patch. */
133
+ onChange: (filters: CustomStageFilter[]) => void;
134
+ /** Columns offered in the field dropdown (visible, non-id). */
135
+ fieldChoices: ColumnDefinition[];
136
+ /** Optional heading shown above the rows. */
137
+ label?: string;
138
+ }
139
+ /**
140
+ * The reusable field/operator/value condition builder. Emits `CustomStageFilter[]`
141
+ * through `onChange`. Same ops (eq/neq/contains/in) and testids the smart-lane
142
+ * editor has always used, so it drops in for both the custom-stage smart lane
143
+ * and the declared-stage config dialog.
144
+ */
145
+ export declare function StageConditionBuilder({ filters, onChange, fieldChoices, label, }: StageConditionBuilderProps): React.JSX.Element;
114
146
  export interface CustomStageDialogProps {
115
147
  open: boolean;
116
148
  onOpenChange: (open: boolean) => void;
@@ -144,6 +176,69 @@ export interface CustomStageDeleteDialogProps {
144
176
  * cards to; confirming again retries the delete with `reassign_to`.
145
177
  */
146
178
  export declare function CustomStageDeleteDialog({ open, onOpenChange, stage, reassignTargets, onConfirm, }: CustomStageDeleteDialogProps): React.JSX.Element | null;
179
+ export type StageConfigKind = 'declared' | 'custom';
180
+ /** What the gear opens the config dialog against — a declared or custom lane. */
181
+ export interface StageConfigTarget {
182
+ kind: StageConfigKind;
183
+ /** Stable lane key. */
184
+ stageKey: string;
185
+ /** Custom-stage id — required (and only used) when `kind === 'custom'`. */
186
+ id?: CustomStage['id'];
187
+ label: string;
188
+ color: string;
189
+ filters: CustomStageFilter[];
190
+ /**
191
+ * Declared kind: an override is currently applied → shows a "Personalizada"
192
+ * badge + "Restablecer al original". Ignored for custom stages (they reset
193
+ * via their own delete flow).
194
+ */
195
+ overridden?: boolean;
196
+ /** Terminal stage (e.g. "Done") — surfaces an "Etapa final" chip + tooltip. */
197
+ isFinal?: boolean;
198
+ /**
199
+ * The manifest ORIGINAL (pre-override) values, when the host serves them
200
+ * (`metadata.stages[].original`). Drives the "Restablecer al original" confirm
201
+ * so the user sees exactly what reverts. Absent → a generic confirm.
202
+ */
203
+ original?: {
204
+ label?: string;
205
+ color?: string;
206
+ filters?: CustomStageFilter[];
207
+ };
208
+ /** The backing CustomStage (custom kind) so "Eliminar" can trigger delete. */
209
+ customStage?: CustomStage;
210
+ }
211
+ /** A legible operator glyph for a condition chip: = / ≠ / contiene / en. */
212
+ export declare function stageFilterOpSymbol(op: string): string;
213
+ export interface StageConfigDialogProps {
214
+ open: boolean;
215
+ onOpenChange: (open: boolean) => void;
216
+ /** Columns for the condition builder. */
217
+ columns: ColumnDefinition[];
218
+ /** The lane being configured, or null. */
219
+ target: StageConfigTarget | null;
220
+ /** Declared: upsert the lane override (PUT /stage-overrides). */
221
+ onSaveOverride: (stageKey: string, patch: {
222
+ label: string;
223
+ color: string;
224
+ filters: CustomStageFilter[];
225
+ }) => Promise<void>;
226
+ /** Declared: reset the lane to its manifest default (DELETE /stage-overrides). */
227
+ onResetOverride: (stageKey: string) => Promise<void>;
228
+ /** Custom: update the stage via its own CRUD (PUT /custom-stages/:id). */
229
+ onUpdateCustom: (id: CustomStage['id'], patch: Partial<CustomStage>) => Promise<void>;
230
+ /** Custom: hand off to the existing delete (reassign) flow. */
231
+ onDeleteCustom: (stage: CustomStage) => void;
232
+ }
233
+ /**
234
+ * The gear (⚙) dialog. Renames, recolors and attaches extra CONDITIONS to a
235
+ * lane. One UI, two backends: a DECLARED lane persists through `/stage-overrides`
236
+ * (with a "Restablecer etapa" that drops the override); a CUSTOM real stage
237
+ * persists through its own `/custom-stages` CRUD (and deletes via that flow). The
238
+ * conditions narrow which cards the lane shows/counts but never stop it being a
239
+ * drop target — dropping a card only sets the stage value.
240
+ */
241
+ export declare function StageConfigDialog({ open, onOpenChange, columns, target, onSaveOverride, onResetOverride, onUpdateCustom, onDeleteCustom, }: StageConfigDialogProps): React.JSX.Element | null;
147
242
  export interface SmartLaneProps {
148
243
  stage: CustomStage;
149
244
  model: string;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-stages.d.ts","sourceRoot":"","sources":["../src/custom-stages.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"custom-stages.d.ts","sourceRoot":"","sources":["../src/custom-stages.tsx"],"names":[],"mappings":"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"}
@@ -20,7 +20,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
20
20
  // All UI text goes through t() with a Spanish defaultValue.
21
21
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
22
22
  import { useTranslation } from 'react-i18next';
23
- import { Plus, Trash2, Pencil, MoreVertical, Filter, GripVertical, X } from 'lucide-react';
23
+ import { Plus, Trash2, Pencil, MoreVertical, Filter, Flag, GripVertical, Lock, RotateCcw, X } from 'lucide-react';
24
24
  import { toast } from 'sonner';
25
25
  import { Badge, Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, } from '@asteby/metacore-ui/primitives';
26
26
  import { generateBadgeStyles, optionColor } from '@asteby/metacore-ui/lib';
@@ -85,6 +85,8 @@ export function mergeLaneStages(declared, customLaneStages) {
85
85
  label: cs.label,
86
86
  color: cs.color,
87
87
  order: cs.position,
88
+ custom: true,
89
+ filters: cs.filters,
88
90
  });
89
91
  }
90
92
  lanes.sort((a, b) => {
@@ -172,6 +174,42 @@ export function isCustomStageDraftValid(draft) {
172
174
  }
173
175
  return true;
174
176
  }
177
+ /**
178
+ * Whether a card passes a set of extra lane `filters` (the same conditions a
179
+ * smart lane uses, layered on top of a real stage). Ops:
180
+ * - eq → equal (string compare)
181
+ * - neq → not equal
182
+ * - contains → the card's value (array or string) includes the value
183
+ * - in → the card's value is one of the comma-separated candidates
184
+ * Empty/absent filters pass. Pure — a client-side belt-and-suspenders over the
185
+ * initial (unscoped) board page; the server scopes the per-lane top-up queries.
186
+ */
187
+ export function cardMatchesStageFilters(card, filters) {
188
+ if (!filters || filters.length === 0)
189
+ return true;
190
+ return filters.every((f) => {
191
+ if (!f.field || String(f.value ?? '').trim() === '')
192
+ return true;
193
+ const target = String(f.value).trim();
194
+ const raw = card?.[f.field];
195
+ switch (f.op) {
196
+ case 'neq':
197
+ return String(raw ?? '') !== target;
198
+ case 'contains':
199
+ if (Array.isArray(raw))
200
+ return raw.map(String).includes(target);
201
+ return String(raw ?? '').includes(target);
202
+ case 'in':
203
+ return target
204
+ .split(',')
205
+ .map((s) => s.trim())
206
+ .includes(String(raw ?? ''));
207
+ case 'eq':
208
+ default:
209
+ return String(raw ?? '') === target;
210
+ }
211
+ });
212
+ }
175
213
  /** Slugify a label into a stable-ish lane key (used only when creating). */
176
214
  export function slugifyStageKey(label) {
177
215
  return (label
@@ -279,6 +317,36 @@ export function CustomStageLaneMenu({ stage, onEdit, onDelete, }) {
279
317
  defaultValue: 'Opciones de la etapa',
280
318
  }), "data-testid": `custom-stage-menu-${stage.key}`, children: _jsx(MoreVertical, { className: "h-3.5 w-3.5" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: () => onEdit(stage), children: [_jsx(Pencil, { className: "mr-2 h-4 w-4" }), t('dynamic.custom_stages.edit', { defaultValue: 'Editar' })] }), _jsxs(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onClick: () => onDelete(stage), children: [_jsx(Trash2, { className: "mr-2 h-4 w-4" }), t('dynamic.custom_stages.delete', { defaultValue: 'Eliminar' })] })] })] }));
281
319
  }
320
+ /**
321
+ * The reusable field/operator/value condition builder. Emits `CustomStageFilter[]`
322
+ * through `onChange`. Same ops (eq/neq/contains/in) and testids the smart-lane
323
+ * editor has always used, so it drops in for both the custom-stage smart lane
324
+ * and the declared-stage config dialog.
325
+ */
326
+ export function StageConditionBuilder({ filters, onChange, fieldChoices, label, }) {
327
+ const { t } = useTranslation();
328
+ const patchFilter = (i, patch) => onChange(filters.map((f, idx) => (idx === i ? { ...f, ...patch } : f)));
329
+ const addFilter = () => onChange([...filters, emptyCustomStageFilter(fieldChoices[0]?.key ?? '')]);
330
+ const removeFilter = (i) => onChange(filters.filter((_, idx) => idx !== i));
331
+ return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border bg-muted/30 p-3", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-muted-foreground", children: [_jsx(Filter, { className: "h-3.5 w-3.5" }), label ??
332
+ t('dynamic.custom_stages.conditions_label', {
333
+ defaultValue: 'Condiciones',
334
+ })] }), filters.map((f, i) => (_jsxs("div", { className: "grid grid-cols-[1fr_auto_1fr_auto] items-center gap-1.5", "data-testid": `custom-stage-condition-${i}`, children: [_jsxs(Select, { value: f.field, onValueChange: (v) => patchFilter(i, { field: v }), children: [_jsx(SelectTrigger, { className: "h-8 text-xs", "data-testid": `custom-stage-condition-field-${i}`, children: _jsx(SelectValue, { placeholder: t('dynamic.custom_stages.field_placeholder', { defaultValue: 'Campo' }) }) }), _jsx(SelectContent, { children: fieldChoices.map((c) => (_jsx(SelectItem, { value: c.key, className: "text-xs", children: t(c.label, { defaultValue: c.label }) }, c.key))) })] }), _jsxs(Select, { value: f.op, onValueChange: (v) => patchFilter(i, { op: v }), children: [_jsx(SelectTrigger, { className: "h-8 w-[104px] text-xs", "data-testid": `custom-stage-condition-op-${i}`, children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: CUSTOM_STAGE_FILTER_OPS.map((op) => (_jsx(SelectItem, { value: op, className: "text-xs", children: t(`dynamic.custom_stages.op.${op}`, {
335
+ defaultValue: op === 'eq'
336
+ ? 'es igual'
337
+ : op === 'neq'
338
+ ? 'distinto'
339
+ : op === 'contains'
340
+ ? 'contiene'
341
+ : 'en lista',
342
+ }) }, op))) })] }), _jsx(Input, { value: f.value, onChange: (e) => patchFilter(i, { value: e.target.value }), placeholder: t('dynamic.custom_stages.value_placeholder', {
343
+ defaultValue: 'Valor',
344
+ }), className: "h-8 text-xs", "data-testid": `custom-stage-condition-value-${i}` }), _jsx("button", { type: "button", onClick: () => removeFilter(i), disabled: filters.length === 1, className: "flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-destructive disabled:opacity-40", "aria-label": t('dynamic.custom_stages.remove_condition', {
345
+ defaultValue: 'Quitar condición',
346
+ }), "data-testid": `custom-stage-condition-remove-${i}`, children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }, i))), _jsxs(Button, { variant: "ghost", size: "sm", className: "h-7 justify-start gap-1 text-xs", onClick: addFilter, "data-testid": "custom-stage-add-condition", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), t('dynamic.custom_stages.add_condition', {
347
+ defaultValue: 'Agregar condición',
348
+ })] })] }));
349
+ }
282
350
  export function CustomStageDialog({ open, onOpenChange, model, columns, initial, nextPosition, onCreate, onUpdate, }) {
283
351
  const { t } = useTranslation();
284
352
  const isDark = typeof document !== 'undefined' &&
@@ -308,12 +376,6 @@ export function CustomStageDialog({ open, onOpenChange, model, columns, initial,
308
376
  setFilters([emptyCustomStageFilter(fieldChoices[0]?.key ?? '')]);
309
377
  }
310
378
  }, [open, initial, fieldChoices]);
311
- const patchFilter = (i, patch) => setFilters((prev) => prev.map((f, idx) => (idx === i ? { ...f, ...patch } : f)));
312
- const addFilter = () => setFilters((prev) => [
313
- ...prev,
314
- emptyCustomStageFilter(fieldChoices[0]?.key ?? ''),
315
- ]);
316
- const removeFilter = (i) => setFilters((prev) => prev.filter((_, idx) => idx !== i));
317
379
  const valid = isCustomStageDraftValid({ label, type, filters });
318
380
  const submit = async () => {
319
381
  if (!valid || saving)
@@ -389,23 +451,7 @@ export function CustomStageDialog({ open, onOpenChange, model, columns, initial,
389
451
  defaultValue: 'Etapa normal',
390
452
  }) }), _jsx(SelectItem, { value: "smart", children: t('dynamic.custom_stages.type_smart', {
391
453
  defaultValue: 'Etapa inteligente',
392
- }) })] })] })] }), type === 'smart' && (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border bg-muted/30 p-3", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-xs font-medium text-muted-foreground", children: [_jsx(Filter, { className: "h-3.5 w-3.5" }), t('dynamic.custom_stages.conditions_label', {
393
- defaultValue: 'Condiciones',
394
- })] }), filters.map((f, i) => (_jsxs("div", { className: "grid grid-cols-[1fr_auto_1fr_auto] items-center gap-1.5", "data-testid": `custom-stage-condition-${i}`, children: [_jsxs(Select, { value: f.field, onValueChange: (v) => patchFilter(i, { field: v }), children: [_jsx(SelectTrigger, { className: "h-8 text-xs", "data-testid": `custom-stage-condition-field-${i}`, children: _jsx(SelectValue, { placeholder: t('dynamic.custom_stages.field_placeholder', { defaultValue: 'Campo' }) }) }), _jsx(SelectContent, { children: fieldChoices.map((c) => (_jsx(SelectItem, { value: c.key, className: "text-xs", children: t(c.label, { defaultValue: c.label }) }, c.key))) })] }), _jsxs(Select, { value: f.op, onValueChange: (v) => patchFilter(i, { op: v }), children: [_jsx(SelectTrigger, { className: "h-8 w-[104px] text-xs", "data-testid": `custom-stage-condition-op-${i}`, children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: CUSTOM_STAGE_FILTER_OPS.map((op) => (_jsx(SelectItem, { value: op, className: "text-xs", children: t(`dynamic.custom_stages.op.${op}`, {
395
- defaultValue: op === 'eq'
396
- ? 'es igual'
397
- : op === 'neq'
398
- ? 'distinto'
399
- : op === 'contains'
400
- ? 'contiene'
401
- : 'en lista',
402
- }) }, op))) })] }), _jsx(Input, { value: f.value, onChange: (e) => patchFilter(i, { value: e.target.value }), placeholder: t('dynamic.custom_stages.value_placeholder', {
403
- defaultValue: 'Valor',
404
- }), className: "h-8 text-xs", "data-testid": `custom-stage-condition-value-${i}` }), _jsx("button", { type: "button", onClick: () => removeFilter(i), disabled: filters.length === 1, className: "flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-destructive disabled:opacity-40", "aria-label": t('dynamic.custom_stages.remove_condition', {
405
- defaultValue: 'Quitar condición',
406
- }), "data-testid": `custom-stage-condition-remove-${i}`, children: _jsx(X, { className: "h-3.5 w-3.5" }) })] }, i))), _jsxs(Button, { variant: "ghost", size: "sm", className: "h-7 justify-start gap-1 text-xs", onClick: addFilter, "data-testid": "custom-stage-add-condition", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), t('dynamic.custom_stages.add_condition', {
407
- defaultValue: 'Agregar condición',
408
- })] })] }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: saving, children: t('dynamic.custom_stages.cancel', { defaultValue: 'Cancelar' }) }), _jsx(Button, { onClick: () => void submit(), disabled: !valid || saving, "data-testid": "custom-stage-save", children: initial
454
+ }) })] })] })] }), type === 'smart' && (_jsx(StageConditionBuilder, { filters: filters, onChange: setFilters, fieldChoices: fieldChoices }))] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: saving, children: t('dynamic.custom_stages.cancel', { defaultValue: 'Cancelar' }) }), _jsx(Button, { onClick: () => void submit(), disabled: !valid || saving, "data-testid": "custom-stage-save", children: initial
409
455
  ? t('dynamic.custom_stages.save', { defaultValue: 'Guardar' })
410
456
  : t('dynamic.custom_stages.create', { defaultValue: 'Crear etapa' }) })] })] }) }));
411
457
  }
@@ -478,6 +524,195 @@ export function CustomStageDeleteDialog({ open, onOpenChange, stage, reassignTar
478
524
  defaultValue: 'Eliminar',
479
525
  }) })] })] }) }));
480
526
  }
527
+ /** A legible operator glyph for a condition chip: = / ≠ / contiene / en. */
528
+ export function stageFilterOpSymbol(op) {
529
+ switch (op) {
530
+ case 'neq':
531
+ return '≠';
532
+ case 'contains':
533
+ return 'contiene';
534
+ case 'in':
535
+ return 'en';
536
+ case 'eq':
537
+ default:
538
+ return '=';
539
+ }
540
+ }
541
+ /**
542
+ * The gear (⚙) dialog. Renames, recolors and attaches extra CONDITIONS to a
543
+ * lane. One UI, two backends: a DECLARED lane persists through `/stage-overrides`
544
+ * (with a "Restablecer etapa" that drops the override); a CUSTOM real stage
545
+ * persists through its own `/custom-stages` CRUD (and deletes via that flow). The
546
+ * conditions narrow which cards the lane shows/counts but never stop it being a
547
+ * drop target — dropping a card only sets the stage value.
548
+ */
549
+ export function StageConfigDialog({ open, onOpenChange, columns, target, onSaveOverride, onResetOverride, onUpdateCustom, onDeleteCustom, }) {
550
+ const { t } = useTranslation();
551
+ const isDark = typeof document !== 'undefined' &&
552
+ document.documentElement.classList.contains('dark');
553
+ const fieldChoices = useMemo(() => customStageFilterFields(columns), [columns]);
554
+ const [label, setLabel] = useState('');
555
+ const [color, setColor] = useState(CUSTOM_STAGE_COLORS[0]);
556
+ const [filters, setFilters] = useState([]);
557
+ const [saving, setSaving] = useState(false);
558
+ const [resetting, setResetting] = useState(false);
559
+ // Two-step reset: the first click reveals a confirm panel listing exactly
560
+ // what reverts (the manifest original), the second actually drops the override.
561
+ const [confirmingReset, setConfirmingReset] = useState(false);
562
+ // Re-seed the WHOLE form from the lane's current (already-override-applied)
563
+ // metadata each time the dialog opens — the user always sees the live state,
564
+ // never a blank form. Label, color and every extra condition pre-fill editable.
565
+ useEffect(() => {
566
+ if (!open || !target)
567
+ return;
568
+ setLabel(target.label);
569
+ setColor(target.color || CUSTOM_STAGE_COLORS[0]);
570
+ setFilters(target.filters?.map((f) => ({ ...f })) ?? []);
571
+ setConfirmingReset(false);
572
+ }, [open, target]);
573
+ if (!target)
574
+ return null;
575
+ const valid = label.trim().length > 0;
576
+ // Only complete conditions are persisted; empty rows are dropped.
577
+ const cleanFilters = () => filters.filter((f) => f.field && String(f.value).trim() !== '');
578
+ // The conditions that make up the lane's EFFECTIVE query, for the chip row:
579
+ // the immovable stage scope first, then each extra (removable) condition.
580
+ const chipFilters = filters.filter((f) => f.field && String(f.value).trim() !== '');
581
+ const removeFilterAt = (i) => setFilters((prev) => prev.filter((_, idx) => idx !== i));
582
+ const submit = async () => {
583
+ if (!valid || saving)
584
+ return;
585
+ setSaving(true);
586
+ try {
587
+ if (target.kind === 'declared') {
588
+ await onSaveOverride(target.stageKey, {
589
+ label: label.trim(),
590
+ color,
591
+ filters: cleanFilters(),
592
+ });
593
+ }
594
+ else if (target.id != null) {
595
+ await onUpdateCustom(target.id, {
596
+ label: label.trim(),
597
+ color,
598
+ filters: cleanFilters(),
599
+ });
600
+ }
601
+ toast.success(t('dynamic.stage_config.saved', {
602
+ defaultValue: 'Etapa configurada',
603
+ }));
604
+ onOpenChange(false);
605
+ }
606
+ catch {
607
+ // toast already surfaced by the caller's hook; keep the draft open.
608
+ }
609
+ finally {
610
+ setSaving(false);
611
+ }
612
+ };
613
+ const reset = async () => {
614
+ if (resetting)
615
+ return;
616
+ setResetting(true);
617
+ try {
618
+ await onResetOverride(target.stageKey);
619
+ toast.success(t('dynamic.stage_config.reset_done', {
620
+ defaultValue: 'Etapa restablecida',
621
+ }));
622
+ onOpenChange(false);
623
+ }
624
+ catch {
625
+ toast.error(t('dynamic.stage_config.reset_error', {
626
+ defaultValue: 'No se pudo restablecer la etapa',
627
+ }));
628
+ }
629
+ finally {
630
+ setResetting(false);
631
+ }
632
+ };
633
+ const headerDot = generateBadgeStyles(color || optionColor(target.stageKey), { isDark });
634
+ // A one-line, human summary of the manifest original (for the reset confirm).
635
+ const original = target.original;
636
+ const originalConditions = original?.filters && original.filters.length > 0
637
+ ? original.filters
638
+ .map((f) => `${f.field} ${stageFilterOpSymbol(f.op)} ${f.value}`)
639
+ .join(', ')
640
+ : t('dynamic.stage_config.original_no_conditions', {
641
+ defaultValue: 'sin condiciones',
642
+ });
643
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-lg", children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx("span", { className: "inline-block size-3 shrink-0 rounded-full", style: {
644
+ backgroundColor: headerDot.backgroundColor ||
645
+ headerDot.background,
646
+ }, "aria-hidden": true }), t('dynamic.stage_config.title', {
647
+ defaultValue: 'Configurar etapa',
648
+ }), _jsx("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[10px] font-normal text-muted-foreground", children: target.stageKey }), target.kind === 'declared' && target.overridden && (_jsx(Badge, { variant: "secondary", className: "ml-auto text-[10px] font-medium", "data-testid": "stage-config-personalizada", children: t('dynamic.stage_config.customized', {
649
+ defaultValue: 'Personalizada',
650
+ }) }))] }), _jsx(DialogDescription, { children: t('dynamic.stage_config.description', {
651
+ defaultValue: 'Renombra la columna, cambia su color y agrega condiciones para acotar qué tarjetas muestra y cuenta.',
652
+ }) })] }), _jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-xs text-muted-foreground", children: t('dynamic.stage_config.current_conditions_label', {
653
+ defaultValue: 'Condiciones actuales',
654
+ }) }), _jsxs("div", { className: "flex flex-wrap items-center gap-1.5", "data-testid": "stage-config-current-conditions", children: [_jsxs(Badge, { variant: "outline", className: "cursor-default gap-1 border-dashed text-[11px] font-normal text-muted-foreground opacity-80", title: t('dynamic.stage_config.base_chip_hint', {
655
+ defaultValue: 'Alcance base de la etapa: no se puede quitar.',
656
+ }), "data-testid": "stage-config-base-chip", children: [_jsx(Lock, { className: "h-3 w-3" }), t('dynamic.stage_config.base_chip', {
657
+ defaultValue: 'Etapa = {{label}}',
658
+ label: label || target.label,
659
+ })] }), target.isFinal && (_jsxs(Badge, { variant: "outline", className: "cursor-default gap-1 text-[11px] font-normal text-muted-foreground", title: t('dynamic.stage_config.final_chip_hint', {
660
+ defaultValue: 'Etapa terminal: al mover una tarjeta aquí se marca como cerrada (p. ej. en GitHub cierra el issue).',
661
+ }), "data-testid": "stage-config-final-chip", children: [_jsx(Flag, { className: "h-3 w-3" }), t('dynamic.stage_config.final_chip', {
662
+ defaultValue: 'Etapa final',
663
+ })] })), chipFilters.map((f) => {
664
+ // Chip index maps back to its position in `filters`.
665
+ const i = filters.indexOf(f);
666
+ return (_jsxs(Badge, { variant: "secondary", className: "gap-1 pr-1 text-[11px] font-normal", "data-testid": `stage-config-filter-chip-${i}`, children: [_jsx("span", { className: "font-mono", children: f.field }), _jsx("span", { className: "opacity-70", children: stageFilterOpSymbol(f.op) }), _jsx("span", { children: f.value }), _jsx("button", { type: "button", onClick: () => removeFilterAt(i), className: "ml-0.5 rounded p-0.5 hover:bg-background/60", "aria-label": t('dynamic.stage_config.remove_chip', { defaultValue: 'Quitar condición' }), "data-testid": `stage-config-filter-chip-remove-${i}`, children: _jsx(X, { className: "h-2.5 w-2.5" }) })] }, i));
667
+ })] })] }), _jsx("div", { className: "border-t" }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-xs", children: t('dynamic.stage_config.name_label', {
668
+ defaultValue: 'Nombre',
669
+ }) }), _jsx(Input, { value: label, onChange: (e) => setLabel(e.target.value), placeholder: t('dynamic.stage_config.name_placeholder', {
670
+ defaultValue: 'Nombre de la etapa',
671
+ }), "data-testid": "stage-config-name", autoFocus: true })] }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-xs", children: t('dynamic.stage_config.color_label', {
672
+ defaultValue: 'Color',
673
+ }) }), _jsx("div", { className: "flex flex-wrap gap-1.5", "data-testid": "stage-config-colors", children: CUSTOM_STAGE_COLORS.map((c) => {
674
+ const style = generateBadgeStyles(c, { isDark });
675
+ const selected = c === color;
676
+ return (_jsx("button", { type: "button", onClick: () => setColor(c), className: `size-6 rounded-full border-2 transition-transform hover:scale-110 ${selected
677
+ ? 'border-foreground'
678
+ : 'border-transparent'}`, style: {
679
+ backgroundColor: style.backgroundColor ||
680
+ style.background,
681
+ }, "aria-label": c, "aria-pressed": selected, "data-testid": `stage-config-color-${c}` }, c));
682
+ }) })] }), _jsx(StageConditionBuilder, { filters: filters, onChange: setFilters, fieldChoices: fieldChoices, label: t('dynamic.stage_config.conditions_label', {
683
+ defaultValue: 'Condiciones (opcional)',
684
+ }) }), filters.length === 0 && (_jsxs(Button, { variant: "ghost", size: "sm", className: "-mt-2 h-7 justify-start gap-1 text-xs", onClick: () => setFilters([
685
+ emptyCustomStageFilter(fieldChoices[0]?.key ?? ''),
686
+ ]), "data-testid": "stage-config-add-first-condition", children: [_jsx(Plus, { className: "h-3.5 w-3.5" }), t('dynamic.stage_config.add_condition', {
687
+ defaultValue: 'Agregar condición',
688
+ })] })), confirmingReset && (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border border-dashed bg-muted/30 p-3 text-xs", "data-testid": "stage-config-reset-confirm-panel", children: [_jsx("p", { className: "font-medium", children: t('dynamic.stage_config.reset_confirm_title', {
689
+ defaultValue: 'Se restablecerá la etapa a su versión original:',
690
+ }) }), _jsxs("ul", { className: "list-inside list-disc text-muted-foreground", children: [_jsx("li", { children: t('dynamic.stage_config.reset_confirm_label', {
691
+ defaultValue: 'Nombre: {{label}}',
692
+ label: original?.label ?? target.stageKey,
693
+ }) }), _jsx("li", { children: t('dynamic.stage_config.reset_confirm_color', {
694
+ defaultValue: 'Color: {{color}}',
695
+ color: original?.color ?? '—',
696
+ }) }), _jsx("li", { children: t('dynamic.stage_config.reset_confirm_conditions', {
697
+ defaultValue: 'Condiciones: {{list}}',
698
+ list: originalConditions,
699
+ }) })] }), _jsxs("div", { className: "flex justify-end gap-2 pt-1", children: [_jsx(Button, { variant: "outline", size: "sm", className: "h-7 text-xs", onClick: () => setConfirmingReset(false), disabled: resetting, children: t('dynamic.stage_config.cancel', {
700
+ defaultValue: 'Cancelar',
701
+ }) }), _jsx(Button, { variant: "destructive", size: "sm", className: "h-7 text-xs", onClick: () => void reset(), disabled: resetting, "data-testid": "stage-config-reset-confirm", children: t('dynamic.stage_config.reset_confirm', {
702
+ defaultValue: 'Restablecer al original',
703
+ }) })] })] }))] }), _jsxs(DialogFooter, { className: "sm:justify-between", children: [_jsxs("div", { children: [target.kind === 'declared' && target.overridden && (_jsxs(Button, { variant: "ghost", className: "gap-1.5 text-muted-foreground", onClick: () => setConfirmingReset(true), disabled: saving || resetting || confirmingReset, "data-testid": "stage-config-reset", children: [_jsx(RotateCcw, { className: "h-4 w-4" }), t('dynamic.stage_config.reset', {
704
+ defaultValue: 'Restablecer al original',
705
+ })] })), target.kind === 'custom' && target.customStage && (_jsxs(Button, { variant: "ghost", className: "gap-1.5 text-destructive hover:text-destructive", onClick: () => {
706
+ onOpenChange(false);
707
+ onDeleteCustom(target.customStage);
708
+ }, disabled: saving, "data-testid": "stage-config-delete", children: [_jsx(Trash2, { className: "h-4 w-4" }), t('dynamic.stage_config.delete', {
709
+ defaultValue: 'Eliminar etapa',
710
+ })] }))] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: saving || resetting, children: t('dynamic.stage_config.cancel', {
711
+ defaultValue: 'Cancelar',
712
+ }) }), _jsx(Button, { onClick: () => void submit(), disabled: !valid || saving || resetting, "data-testid": "stage-config-save", children: t('dynamic.stage_config.save', {
713
+ defaultValue: 'Guardar',
714
+ }) })] })] })] }) }));
715
+ }
481
716
  /**
482
717
  * A virtual lane defined by `filters`. It runs its OWN list query (the board's
483
718
  * shared records don't include it), so it stays correct regardless of what the
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import type { ActionFieldDef, FieldOptionsConfig } from './types';
2
+ import type { ActionFieldDef, FieldOptionsConfig, OptionDef } from './types';
3
3
  /**
4
4
  * Apps register validator implementations by slug. The slug is the value
5
5
  * `OrgConfig.validators[<key>]` returns for a $org.<key> reference.
@@ -80,6 +80,23 @@ export declare function getDependsOn(field: ActionFieldDef): string | undefined;
80
80
  * field has no dependency or the depended-on value is empty/unset.
81
81
  */
82
82
  export declare function resolveDependsValue(field: ActionFieldDef, formValues?: Record<string, any> | null, rowValues?: Record<string, any> | null): string;
83
+ /**
84
+ * Filters a STATIC enum's `options[]` by each option's `when` gate against the
85
+ * current form values. Pure — no React, no side effects.
86
+ *
87
+ * Rule per option:
88
+ * - No `when` → always included (retrocompat; existing enums untouched).
89
+ * - With `when`: the gating field is `when.field ?? dependsOn`. If neither is
90
+ * present the option is included (nothing to gate on). Otherwise the form's
91
+ * value for that field is compared AS STRING: included when (no `in`, or
92
+ * value ∈ `in`) AND (no `not_in`, or value ∉ `not_in`). Tolerates the
93
+ * snake_case `not_in` the kernel serves alongside camelCase `notIn`.
94
+ *
95
+ * `formValues` is the flat map of the surrounding form/row values the gating
96
+ * field is read from; `dependsOn` is the containing field's declared dependency
97
+ * used as the default gating field.
98
+ */
99
+ export declare function applyOptionWhen(options: OptionDef[] | undefined, formValues: Record<string, any> | null | undefined, dependsOn?: string): OptionDef[];
83
100
  /**
84
101
  * Reads a field's enriched options-resolution config, tolerating the camelCase
85
102
  * `optionsConfig` (authored SDK shape) and the snake_case `options_config` the
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-form-schema.d.ts","sourceRoot":"","sources":["../src/dynamic-form-schema.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAmB,MAAM,KAAK,CAAA;AACxC,OAAO,KAAK,EAAE,cAAc,EAAmB,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAiBlF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,CAEzF;AAcD,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE;;kBAMtD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,EAAE,CAGrE;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,cAAc,GACtB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAatG;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAO3C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACjC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxB;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,GACxB,YAAY,GAAG,SAAS,CAgB1B;AAqDD,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA4B3D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAIrE;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAItE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAC/B,KAAK,EAAE,cAAc,EACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EACvC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GACvC,MAAM,CAQR;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,kBAAkB,GAAG,SAAS,CAGtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACnB,CAQA;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG;IACpD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB,CAaA"}
1
+ {"version":3,"file":"dynamic-form-schema.d.ts","sourceRoot":"","sources":["../src/dynamic-form-schema.ts"],"names":[],"mappings":"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"}