@asteby/metacore-runtime-react 23.6.0 → 23.7.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.
- package/CHANGELOG.md +25 -0
- package/dist/action-modal-dispatcher.js +19 -10
- package/dist/custom-stages.d.ts +171 -0
- package/dist/custom-stages.d.ts.map +1 -0
- package/dist/custom-stages.js +535 -0
- package/dist/dialogs/dynamic-record.d.ts.map +1 -1
- package/dist/dialogs/dynamic-record.js +7 -4
- package/dist/dynamic-kanban.d.ts.map +1 -1
- package/dist/dynamic-kanban.js +77 -32
- package/dist/field-grid.d.ts +17 -0
- package/dist/field-grid.d.ts.map +1 -0
- package/dist/field-grid.js +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/model-action-toolbar.d.ts.map +1 -1
- package/dist/model-action-toolbar.js +3 -1
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/action-modal-grid-layout.test.tsx +86 -0
- package/src/__tests__/custom-stages.test.tsx +480 -0
- package/src/__tests__/model-action-toolbar-i18n.test.tsx +101 -0
- package/src/action-modal-dispatcher.tsx +44 -37
- package/src/custom-stages.tsx +1113 -0
- package/src/dialogs/dynamic-record.tsx +14 -8
- package/src/dynamic-kanban.tsx +153 -5
- package/src/field-grid.tsx +57 -0
- package/src/index.ts +25 -0
- package/src/model-action-toolbar.tsx +9 -1
- package/src/types.ts +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @asteby/metacore-runtime-react
|
|
2
2
|
|
|
3
|
+
## 23.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a3538da: fix(runtime-react): translate addon action labels at render (toolbar + modal)
|
|
8
|
+
|
|
9
|
+
`ModelActionToolbar` and `ActionModalDispatcher` rendered an action's `label`
|
|
10
|
+
(and each field's `label`) verbatim. For an addon's custom action these are i18n
|
|
11
|
+
keys (e.g. `integration_github.action.create_issue.label`) whose locale bundle
|
|
12
|
+
loads asynchronously, so the create button, the modal title/submit, and the
|
|
13
|
+
field labels showed the raw key — and never re-derived once the bundle landed.
|
|
14
|
+
They now translate at render with `t(label, { defaultValue: label })`, so the
|
|
15
|
+
label resolves the moment the addon i18n arrives (via the i18next store `added`
|
|
16
|
+
event) and an already-localized string passes through unchanged.
|
|
17
|
+
|
|
18
|
+
## 23.7.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- 7611284: DynamicKanban: etapas personalizadas estilo Bitrix. Columna fantasma "+ Agregar etapa", diálogo de nombre/color/tipo y constructor de condiciones para etapas inteligentes (lanes virtuales por filtros, solo lectura), menú Editar/Eliminar en lanes custom, e integración con las automatizaciones de etapa. No intrusivo: sin el endpoint `/custom-stages` la UI no se renderiza y el tablero queda intacto.
|
|
23
|
+
|
|
24
|
+
Alineado al contrato del backend (ops #704): las lanes se pintan desde la metadata (`stages[]` con `custom: true` y `smart_lanes[]`), con el CRUD `/custom-stages` como fuente del diálogo de gestión. Los filtros de las etapas inteligentes se serializan como `f_<field>=OP:valor` (`EQ`, `NEQ`, `HAS` para membresía en arrays jsonb, `IN` para listas). En edición, `model`/`type`/`key` son inmutables. El borrado de una etapa real con tarjetas responde 409 con `meta.cards`; el diálogo muestra el conteo y ofrece reasignar las tarjetas a otra columna vía `?reassign_to=<key>`.
|
|
25
|
+
|
|
26
|
+
- 20cb58f: Pule el layout de los modales de create/acción: grid responsivo de dos columnas compartido (`FieldGrid`/`FieldCell`/`FieldLabel`) para el modal de `placement:create` (p. ej. "Crear Issue" del addon github) y el create/edit automático (CRUD). Los campos escalares fluyen en dos columnas (una sola en móvil), textareas/line-items ocupan el ancho completo, y cada celda lleva `min-w-0` para que un valor largo de select/input no reviente las columnas ni genere scroll horizontal. Ancho del dialog de acción a `sm:max-w-xl`, labels con estilo consistente y asterisco de requerido unificado.
|
|
27
|
+
|
|
3
28
|
## 23.6.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
|
@@ -9,7 +9,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
// depend on a bundler alias to `@/lib/api`.
|
|
10
10
|
import { useState, useEffect, useMemo } from 'react';
|
|
11
11
|
import { useTranslation } from 'react-i18next';
|
|
12
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Input, Textarea,
|
|
12
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Button, Input, Textarea, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Switch, } from '@asteby/metacore-ui/primitives';
|
|
13
13
|
import { Loader2 } from 'lucide-react';
|
|
14
14
|
import { toast } from 'sonner';
|
|
15
15
|
import { useApi } from './api-context';
|
|
@@ -20,6 +20,7 @@ import { DynamicSelectField } from './dynamic-select-field';
|
|
|
20
20
|
import { DynamicDateField } from './dynamic-date-field';
|
|
21
21
|
import { UploadField } from './upload-field';
|
|
22
22
|
import { isLineItemsField, resolveWidget, resolveDependsValue, getDependsOn } from './dynamic-form-schema';
|
|
23
|
+
import { FieldGrid, FieldCell, FieldLabel } from './field-grid';
|
|
23
24
|
// Canonical registry lives in @asteby/metacore-sdk
|
|
24
25
|
import { getActionComponent, } from '@asteby/metacore-sdk';
|
|
25
26
|
function isPrefillSpec(v) {
|
|
@@ -110,6 +111,10 @@ function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoi
|
|
|
110
111
|
const { t } = useTranslation();
|
|
111
112
|
const api = useApi();
|
|
112
113
|
const [executing, setExecuting] = useState(false);
|
|
114
|
+
// `action.label` is an addon-contributed i18n key; its locale bundle loads
|
|
115
|
+
// asynchronously, so translate at render (defaultValue keeps an already
|
|
116
|
+
// localized label unchanged).
|
|
117
|
+
const label = t(action.label, { defaultValue: action.label });
|
|
113
118
|
const execute = async () => {
|
|
114
119
|
setExecuting(true);
|
|
115
120
|
try {
|
|
@@ -131,10 +136,14 @@ function ConfirmActionDialog({ open, onOpenChange, action, model, record, endpoi
|
|
|
131
136
|
setExecuting(false);
|
|
132
137
|
}
|
|
133
138
|
};
|
|
134
|
-
return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(DynamicIcon, { name: action.icon, className: "h-5 w-5" }),
|
|
139
|
+
return (_jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsxs(AlertDialogTitle, { className: "flex items-center gap-2", children: [_jsx(DynamicIcon, { name: action.icon, className: "h-5 w-5" }), label] }), _jsx(AlertDialogDescription, { children: action.confirmMessage || `${label}?` })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { disabled: executing, children: t('common.cancel') }), _jsxs(AlertDialogAction, { onClick: (e) => { e.preventDefault(); execute(); }, disabled: executing, style: action.color ? { backgroundColor: action.color } : undefined, children: [executing ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), label] })] })] }) }));
|
|
135
140
|
}
|
|
136
141
|
function GenericActionModal({ open, onOpenChange, action, model, record, endpoint, onSuccess }) {
|
|
137
142
|
const { t } = useTranslation();
|
|
143
|
+
// Addon-contributed labels (action + fields) are i18n keys whose locale
|
|
144
|
+
// bundle loads asynchronously; translate at render so they don't render raw.
|
|
145
|
+
// defaultValue keeps an already-localized string unchanged.
|
|
146
|
+
const tl = (s) => t(s, { defaultValue: s });
|
|
138
147
|
const api = useApi();
|
|
139
148
|
const [formData, setFormData] = useState({});
|
|
140
149
|
const [executing, setExecuting] = useState(false);
|
|
@@ -193,13 +202,13 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
193
202
|
if (isLineItemsField(field)) {
|
|
194
203
|
const rows = formData[field.key];
|
|
195
204
|
if (!Array.isArray(rows) || rows.length === 0) {
|
|
196
|
-
toast.error(`${field.label} requiere al menos un renglón`);
|
|
205
|
+
toast.error(`${tl(field.label)} requiere al menos un renglón`);
|
|
197
206
|
return;
|
|
198
207
|
}
|
|
199
208
|
continue;
|
|
200
209
|
}
|
|
201
210
|
if (!formData[field.key] && formData[field.key] !== false) {
|
|
202
|
-
toast.error(`${field.label} es requerido`);
|
|
211
|
+
toast.error(`${tl(field.label)} es requerido`);
|
|
203
212
|
return;
|
|
204
213
|
}
|
|
205
214
|
}
|
|
@@ -238,12 +247,12 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
|
|
|
238
247
|
: hasLineItems
|
|
239
248
|
? '820px'
|
|
240
249
|
: undefined;
|
|
241
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: 'flex max-h-[90vh] flex-col overflow-hidden ' + (widthPx ? '' : 'sm:max-w-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: 'flex max-h-[90vh] flex-col overflow-hidden ' + (widthPx ? '' : 'sm:max-w-xl'), style: { maxHeight: '90vh', ...(widthPx ? { maxWidth: widthPx, width: '95vw' } : {}) }, children: [_jsxs(DialogHeader, { className: "shrink-0", children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(DynamicIcon, { name: action.icon, className: "h-5 w-5" }), tl(action.label)] }), action.confirmMessage && _jsx(DialogDescription, { children: action.confirmMessage })] }), _jsx("div", { className: "-mx-1 min-h-0 flex-1 overflow-y-auto px-1 py-4", children: _jsxs(FieldGrid, { children: [action.fields?.map((field) => {
|
|
251
|
+
const fullWidth = isLineItemsField(field) ||
|
|
252
|
+
resolveWidget(field) === 'textarea' ||
|
|
253
|
+
resolveWidget(field) === 'richtext';
|
|
254
|
+
return (_jsxs(FieldCell, { fullWidth: fullWidth, children: [_jsx(FieldLabel, { htmlFor: field.key, required: field.required, children: tl(field.label) }), renderField(field, formData[field.key], (v) => updateField(field.key, v), formData)] }, field.key));
|
|
255
|
+
}), relations.length > 0 && (_jsx(FieldCell, { fullWidth: true, children: _jsx(DynamicRelations, { record: record, relations: relations }) }))] }) }), _jsxs(DialogFooter, { className: "shrink-0", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: executing, children: t('common.cancel') }), _jsxs(Button, { onClick: execute, disabled: executing, style: action.color ? { backgroundColor: action.color, color: 'white' } : undefined, children: [executing ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), tl(action.label)] })] })] }) }));
|
|
247
256
|
}
|
|
248
257
|
function renderField(field, value, onChange,
|
|
249
258
|
// Full current form values — lets a line-items grid (and any cascading
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ApiClient } from './api-context';
|
|
3
|
+
import type { ColumnDefinition, StageMeta, SmartLaneMeta } from './types';
|
|
4
|
+
export type CustomStageType = 'stage' | 'smart';
|
|
5
|
+
export type CustomStageFilterOp = 'eq' | 'neq' | 'contains' | 'in';
|
|
6
|
+
export interface CustomStageFilter {
|
|
7
|
+
field: string;
|
|
8
|
+
op: CustomStageFilterOp;
|
|
9
|
+
value: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CustomStage {
|
|
12
|
+
id: string | number;
|
|
13
|
+
model: string;
|
|
14
|
+
/** Stable lane key (also the value stored on a card for `type: "stage"`). */
|
|
15
|
+
key: string;
|
|
16
|
+
label: string;
|
|
17
|
+
/** Semantic palette name ('slate', 'blue', …) or a hex literal. */
|
|
18
|
+
color: string;
|
|
19
|
+
/** Board position (lane order). */
|
|
20
|
+
position: number;
|
|
21
|
+
type: CustomStageType;
|
|
22
|
+
/** Only meaningful for `type: "smart"` — the virtual lane's funnel. */
|
|
23
|
+
filters: CustomStageFilter[];
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Draft for a new custom stage (no server id yet). */
|
|
27
|
+
export type NewCustomStage = Omit<CustomStage, 'id'>;
|
|
28
|
+
export declare const CUSTOM_STAGE_COLORS: readonly ["slate", "blue", "green", "amber", "red", "purple", "pink", "cyan"];
|
|
29
|
+
export declare const CUSTOM_STAGE_FILTER_OPS: CustomStageFilterOp[];
|
|
30
|
+
/** A blank filter row for the smart-lane condition builder. */
|
|
31
|
+
export declare function emptyCustomStageFilter(field?: string): CustomStageFilter;
|
|
32
|
+
/** Enabled custom stages split by flavor (disabled ones are dropped). */
|
|
33
|
+
export declare function splitCustomStages(stages: CustomStage[] | undefined): {
|
|
34
|
+
laneStages: CustomStage[];
|
|
35
|
+
smartStages: CustomStage[];
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Merges `type: "stage"` custom stages into the model's declared lanes. A
|
|
39
|
+
* custom stage whose key the metadata ALREADY carries (the backend surfaced it
|
|
40
|
+
* in `metadata.stages`) is not duplicated — it's just tagged as custom so the
|
|
41
|
+
* lane grows an edit/delete menu. Unknown-key custom stages are appended.
|
|
42
|
+
* Returns the merged lanes (sorted by order) plus a `key → CustomStage` map so
|
|
43
|
+
* the board can decorate the custom lanes.
|
|
44
|
+
*/
|
|
45
|
+
export declare function mergeLaneStages(declared: StageMeta[], customLaneStages: CustomStage[]): {
|
|
46
|
+
lanes: StageMeta[];
|
|
47
|
+
customByKey: Map<string, CustomStage>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Serializes a smart lane's filters into the board's list query params. The ops
|
|
51
|
+
* list endpoint (ops #704) takes a SINGLE `f_<field>` param whose value carries
|
|
52
|
+
* the operator as a `OP:value` prefix:
|
|
53
|
+
* - eq → `f_<field>=EQ:value`
|
|
54
|
+
* - neq → `f_<field>=NEQ:value`
|
|
55
|
+
* - contains → `f_<field>=HAS:value` (membership in a jsonb array — NOT the
|
|
56
|
+
* text-substring ILIKE; that's why it's HAS, not CONTAINS)
|
|
57
|
+
* - in → `f_<field>=IN:v1,v2,...` (comma-separated after `IN:`)
|
|
58
|
+
* Empty fields/values are skipped.
|
|
59
|
+
*/
|
|
60
|
+
export declare function smartLaneParams(filters: CustomStageFilter[] | undefined): Record<string, string>;
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the smart lanes to paint. The kernel's `metadata.smart_lanes` is the
|
|
63
|
+
* source of truth for rendering (ops #704); the CRUD list only backs the
|
|
64
|
+
* management dialog. So when metadata carries smart lanes we map those, folding
|
|
65
|
+
* in the CRUD entry's `id` (matched by key) so the Editar menu can PUT/DELETE.
|
|
66
|
+
* When metadata omits them (older host / metadata lag) we tolerate the gap and
|
|
67
|
+
* fall back to the CRUD smart stages. Returns `CustomStage[]` either way.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveSmartLanes(metaSmartLanes: SmartLaneMeta[] | undefined, crudSmartStages: CustomStage[], model: string): CustomStage[];
|
|
70
|
+
/** Columns offered in the condition builder: visible, non-id model columns. */
|
|
71
|
+
export declare function customStageFilterFields(columns: ColumnDefinition[]): ColumnDefinition[];
|
|
72
|
+
/** Whether a draft is complete enough to save. */
|
|
73
|
+
export declare function isCustomStageDraftValid(draft: {
|
|
74
|
+
label: string;
|
|
75
|
+
type: CustomStageType;
|
|
76
|
+
filters: CustomStageFilter[];
|
|
77
|
+
}): boolean;
|
|
78
|
+
/** Slugify a label into a stable-ish lane key (used only when creating). */
|
|
79
|
+
export declare function slugifyStageKey(label: string): string;
|
|
80
|
+
export interface UseCustomStagesResult {
|
|
81
|
+
/** False when the endpoint is missing/errored — hide the whole feature. */
|
|
82
|
+
available: boolean;
|
|
83
|
+
loading: boolean;
|
|
84
|
+
stages: CustomStage[];
|
|
85
|
+
create: (draft: NewCustomStage) => Promise<void>;
|
|
86
|
+
update: (id: CustomStage['id'], patch: Partial<CustomStage>) => Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Deletes a stage. Pass `reassignTo` (a target lane key) to move a real
|
|
89
|
+
* stage's cards first. Throws on 409 (cards still present, no reassign) so
|
|
90
|
+
* the caller can read `meta.cards` and offer a reassignment target.
|
|
91
|
+
*/
|
|
92
|
+
remove: (id: CustomStage['id'], reassignTo?: string) => Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Loads a model's custom stages and exposes CRUD. A missing endpoint (404 /
|
|
96
|
+
* network error) degrades to `available: false` so the kanban never breaks;
|
|
97
|
+
* real mutation failures surface a toast and re-throw so the dialog keeps its
|
|
98
|
+
* draft. A 409 on delete (existing cards) is re-thrown WITHOUT a generic toast
|
|
99
|
+
* so the delete flow can show a targeted message.
|
|
100
|
+
*/
|
|
101
|
+
export declare function useCustomStages(model: string): UseCustomStagesResult;
|
|
102
|
+
export interface AddStageColumnProps {
|
|
103
|
+
onClick: () => void;
|
|
104
|
+
}
|
|
105
|
+
/** The dotted phantom lane at the end of the board (Bitrix/Trello pattern). */
|
|
106
|
+
export declare function AddStageColumn({ onClick }: AddStageColumnProps): React.JSX.Element;
|
|
107
|
+
export interface CustomStageLaneMenuProps {
|
|
108
|
+
stage: CustomStage;
|
|
109
|
+
onEdit: (stage: CustomStage) => void;
|
|
110
|
+
onDelete: (stage: CustomStage) => void;
|
|
111
|
+
}
|
|
112
|
+
/** The ⋮ menu shown in a custom lane's header. */
|
|
113
|
+
export declare function CustomStageLaneMenu({ stage, onEdit, onDelete, }: CustomStageLaneMenuProps): React.JSX.Element;
|
|
114
|
+
export interface CustomStageDialogProps {
|
|
115
|
+
open: boolean;
|
|
116
|
+
onOpenChange: (open: boolean) => void;
|
|
117
|
+
model: string;
|
|
118
|
+
/** Columns for the smart-lane condition builder. */
|
|
119
|
+
columns: ColumnDefinition[];
|
|
120
|
+
/** Editing an existing stage, or null to create a new one. */
|
|
121
|
+
initial: CustomStage | null;
|
|
122
|
+
/** Next board position for a newly created stage (appended at the end). */
|
|
123
|
+
nextPosition: number;
|
|
124
|
+
onCreate: (draft: NewCustomStage) => Promise<void>;
|
|
125
|
+
onUpdate: (id: CustomStage['id'], patch: Partial<CustomStage>) => Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
export declare function CustomStageDialog({ open, onOpenChange, model, columns, initial, nextPosition, onCreate, onUpdate, }: CustomStageDialogProps): React.JSX.Element;
|
|
128
|
+
export interface CustomStageDeleteDialogProps {
|
|
129
|
+
open: boolean;
|
|
130
|
+
onOpenChange: (open: boolean) => void;
|
|
131
|
+
stage: CustomStage | null;
|
|
132
|
+
/** Other lanes a real stage's cards can be reassigned to (key excluded). */
|
|
133
|
+
reassignTargets?: {
|
|
134
|
+
key: string;
|
|
135
|
+
label: string;
|
|
136
|
+
}[];
|
|
137
|
+
/** `reassignTo` is set on retry after a 409 (real stage with cards). */
|
|
138
|
+
onConfirm: (stage: CustomStage, reassignTo?: string) => Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Confirms deleting a custom lane. A 409 (the backend rejected because cards
|
|
142
|
+
* still sit on a real stage) doesn't close the dialog — it reads `meta.cards`
|
|
143
|
+
* from the response, shows the count, and offers a target lane to reassign the
|
|
144
|
+
* cards to; confirming again retries the delete with `reassign_to`.
|
|
145
|
+
*/
|
|
146
|
+
export declare function CustomStageDeleteDialog({ open, onOpenChange, stage, reassignTargets, onConfirm, }: CustomStageDeleteDialogProps): React.JSX.Element | null;
|
|
147
|
+
export interface SmartLaneProps {
|
|
148
|
+
stage: CustomStage;
|
|
149
|
+
model: string;
|
|
150
|
+
/** Org-scoped list endpoint base (same as the kanban's). */
|
|
151
|
+
endpoint?: string;
|
|
152
|
+
/** Board-wide static filters always applied (never shown as a chip). */
|
|
153
|
+
defaultFilters?: Record<string, any>;
|
|
154
|
+
pageSize?: number;
|
|
155
|
+
isDark: boolean;
|
|
156
|
+
/** Renders one card the same way the board's real lanes do (read-only). */
|
|
157
|
+
renderCard: (card: any) => React.ReactNode;
|
|
158
|
+
/** Refetch trigger — bump to re-run the lane's query. */
|
|
159
|
+
refreshTrigger?: any;
|
|
160
|
+
onEdit: (stage: CustomStage) => void;
|
|
161
|
+
onDelete: (stage: CustomStage) => void;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* A virtual lane defined by `filters`. It runs its OWN list query (the board's
|
|
165
|
+
* shared records don't include it), so it stays correct regardless of what the
|
|
166
|
+
* main board page loaded. Cards render read-only — a smart lane is a saved view,
|
|
167
|
+
* not a drop target — and the header carries a funnel glyph + the custom menu.
|
|
168
|
+
*/
|
|
169
|
+
export declare function SmartLane({ stage, model, endpoint, defaultFilters, pageSize, isDark, renderCard, refreshTrigger, onEdit, onDelete, }: SmartLaneProps): React.JSX.Element;
|
|
170
|
+
export type { ApiClient };
|
|
171
|
+
//# sourceMappingURL=custom-stages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-stages.d.ts","sourceRoot":"","sources":["../src/custom-stages.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAoD,MAAM,OAAO,CAAA;AA4BxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EACR,gBAAgB,EAChB,SAAS,EACT,aAAa,EAEhB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,CAAA;AAC/C,MAAM,MAAM,mBAAmB,GAAG,IAAI,GAAG,KAAK,GAAG,UAAU,GAAG,IAAI,CAAA;AAElE,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,mBAAmB,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAA;IACb,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,eAAe,CAAA;IACrB,uEAAuE;IACvE,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,OAAO,EAAE,OAAO,CAAA;CACnB;AAED,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;AAGpD,eAAO,MAAM,mBAAmB,+EAStB,CAAA;AAEV,eAAO,MAAM,uBAAuB,EAAE,mBAAmB,EAKxD,CAAA;AAMD,+DAA+D;AAC/D,wBAAgB,sBAAsB,CAAC,KAAK,SAAK,GAAG,iBAAiB,CAEpE;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,GAAG;IAClE,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,WAAW,EAAE,WAAW,EAAE,CAAA;CAC7B,CASA;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC3B,QAAQ,EAAE,SAAS,EAAE,EACrB,gBAAgB,EAAE,WAAW,EAAE,GAChC;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;CAAE,CAoB/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC3B,OAAO,EAAE,iBAAiB,EAAE,GAAG,SAAS,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBxB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,cAAc,EAAE,aAAa,EAAE,GAAG,SAAS,EAC3C,eAAe,EAAE,WAAW,EAAE,EAC9B,KAAK,EAAE,MAAM,GACd,WAAW,EAAE,CAqBf;AAED,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,gBAAgB,EAAE,GAC5B,gBAAgB,EAAE,CAEpB;AAED,kDAAkD;AAClD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,eAAe,CAAA;IACrB,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC/B,GAAG,OAAO,CAQV;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUrD;AAYD,MAAM,WAAW,qBAAqB;IAClC,2EAA2E;IAC3E,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,EAAE,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7E;;;;OAIG;IACH,MAAM,EAAE,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACxE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,qBAAqB,CAwFpE;AAMD,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,mBAAmB,qBAe9D;AAMD,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;CACzC;AAED,kDAAkD;AAClD,wBAAgB,mBAAmB,CAAC,EAChC,KAAK,EACL,MAAM,EACN,QAAQ,GACX,EAAE,wBAAwB,qBA+B1B;AAMD,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,8DAA8D;IAC9D,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClF;AAED,wBAAgB,iBAAiB,CAAC,EAC9B,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,OAAO,EACP,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,QAAQ,GACX,EAAE,sBAAsB,qBAsUxB;AAMD,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACzB,4EAA4E;IAC5E,eAAe,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAClD,wEAAwE;IACxE,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACxE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,eAAoB,EACpB,SAAS,GACZ,EAAE,4BAA4B,4BA0H9B;AAMD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,2EAA2E;IAC3E,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1C,yDAAyD;IACzD,cAAc,CAAC,EAAE,GAAG,CAAA;IACpB,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;CACzC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,cAAc,EACd,QAAa,EACb,MAAM,EACN,UAAU,EACV,cAAc,EACd,MAAM,EACN,QAAQ,GACX,EAAE,cAAc,qBAqGhB;AAGD,YAAY,EAAE,SAAS,EAAE,CAAA"}
|