@fcurd/core 0.1.0

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.
@@ -0,0 +1,337 @@
1
+ import { Ref, Reactive, ComputedRef } from 'vue';
2
+
3
+ /**
4
+ * Sort configuration
5
+ */
6
+ interface CrudSort<Field extends string = string> {
7
+ field: Field;
8
+ order: 'ascend' | 'descend';
9
+ }
10
+ /**
11
+ * Field visibility context
12
+ */
13
+ interface FieldContext<Row = any, FormModel = Row> {
14
+ surface: 'search' | 'table' | 'form' | 'detail';
15
+ row?: Row;
16
+ formModel?: FormModel;
17
+ query?: Record<string, unknown>;
18
+ }
19
+ /**
20
+ * Cell render context for table columns
21
+ */
22
+ interface CellContext<Row = any> {
23
+ row: Row;
24
+ rowIndex: number;
25
+ value: any;
26
+ }
27
+ /** Alias for backward compatibility */
28
+ type CrudTableCellContext<Row = any> = CellContext<Row>;
29
+ /**
30
+ * Field definition - core schema for form/search/table
31
+ */
32
+ type CrudFieldType = 'text' | 'textarea' | 'select' | 'date' | 'datetime' | 'dateRange' | 'datetimeRange' | 'switch' | 'number' | 'money' | 'custom';
33
+ interface CrudField<Row = any, FormModel = Row, UiExt = unknown> {
34
+ key: string;
35
+ label: string | (() => string);
36
+ type: CrudFieldType | (string & {});
37
+ required?: boolean;
38
+ visibleIn?: {
39
+ search?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
40
+ table?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
41
+ form?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
42
+ detail?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
43
+ };
44
+ /** UI-specific extensions, defined by adapter layer */
45
+ ui?: UiExt;
46
+ }
47
+ /**
48
+ * Table column definition
49
+ */
50
+ interface CrudColumn<Row = any, UiExt = unknown> {
51
+ key: string;
52
+ label?: string | (() => string);
53
+ width?: number;
54
+ minWidth?: number;
55
+ fixed?: 'left' | 'right';
56
+ sortable?: boolean;
57
+ render?: (ctx: CellContext<Row>) => any;
58
+ /** UI-specific extensions */
59
+ ui?: UiExt;
60
+ }
61
+ interface ListParams<Query = Record<string, unknown>> {
62
+ page: number;
63
+ pageSize: number;
64
+ query: Query;
65
+ sort?: CrudSort | null;
66
+ signal?: AbortSignal;
67
+ }
68
+ interface ListResult<Row = any> {
69
+ items: Row[];
70
+ total: number;
71
+ }
72
+ interface ExportParams<Query = Record<string, unknown>> {
73
+ query: Query;
74
+ sort?: CrudSort | null;
75
+ signal?: AbortSignal;
76
+ }
77
+ type ExportResult = Blob | {
78
+ blob: Blob;
79
+ filename?: string;
80
+ } | {
81
+ url: string;
82
+ filename?: string;
83
+ };
84
+ /**
85
+ * CRUD data adapter interface
86
+ */
87
+ interface CrudAdapter<Row = any, Query = Record<string, unknown>> {
88
+ list: (params: ListParams<Query>) => Promise<ListResult<Row>>;
89
+ create?: (data: Partial<Row>) => Promise<Row>;
90
+ update?: (id: string | number, data: Partial<Row>) => Promise<Row>;
91
+ remove?: (id: string | number) => Promise<void>;
92
+ export?: (params: ExportParams<Query>) => Promise<ExportResult>;
93
+ getId?: (row: Row) => string | number;
94
+ }
95
+ interface UseCrudListOptions<Row = any, Query = Record<string, unknown>> {
96
+ adapter: CrudAdapter<Row, Query>;
97
+ initialQuery?: Query;
98
+ initialPage?: number;
99
+ initialPageSize?: number;
100
+ autoFetch?: boolean;
101
+ debounceMs?: number;
102
+ dedupe?: boolean;
103
+ onError?: (error: unknown) => void;
104
+ }
105
+ interface UseCrudListReturn<Row = any, Query = Record<string, unknown>> {
106
+ rows: Ref<Row[]>;
107
+ total: Ref<number>;
108
+ loading: Ref<boolean>;
109
+ error: Ref<unknown>;
110
+ page: Ref<number>;
111
+ pageSize: Ref<number>;
112
+ query: Ref<Query>;
113
+ sort: Ref<CrudSort | null>;
114
+ refresh: () => Promise<void>;
115
+ setQuery: (partial: Partial<Query>, options?: SetQueryOptions) => void;
116
+ setPage: (page: number) => void;
117
+ setPageSize: (size: number) => void;
118
+ setSort: (sort: CrudSort | null) => void;
119
+ reset: () => void;
120
+ }
121
+ interface SetQueryOptions {
122
+ /**
123
+ * How to apply the partial query update
124
+ * - merge: shallow merge into existing query (default)
125
+ * - replace: replace the whole query with partial
126
+ */
127
+ mode?: 'merge' | 'replace';
128
+ /** Keys to delete from current query before applying the update (useful for flat search forms) */
129
+ clearKeys?: string[];
130
+ /**
131
+ * Remove empty values after applying update.
132
+ * Treats `undefined | null | '' | [] | {}` as empty (deep).
133
+ * Keeps `0` / `false`.
134
+ */
135
+ pruneEmpty?: boolean;
136
+ }
137
+ interface UseCrudFormOptions<Row = any> {
138
+ fields: CrudField<Row>[];
139
+ initialData?: Partial<Row>;
140
+ }
141
+ interface UseCrudFormReturn<Row = any> {
142
+ model: Reactive<Partial<Row>>;
143
+ mode: Ref<'create' | 'edit'>;
144
+ dirty: ComputedRef<boolean>;
145
+ changedKeys: ComputedRef<string[]>;
146
+ changedData: ComputedRef<Partial<Row>>;
147
+ visibleFields: ComputedRef<CrudField<Row>[]>;
148
+ reset: (data?: Partial<Row>) => void;
149
+ setMode: (mode: 'create' | 'edit') => void;
150
+ getSubmitData: () => Partial<Row>;
151
+ }
152
+ interface UseCrudSelectionOptions<Row = any> {
153
+ rows: Ref<Row[]>;
154
+ getId?: (row: Row) => string | number;
155
+ }
156
+ interface UseCrudSelectionReturn<Row = any> {
157
+ selectedIds: Ref<Set<string | number>>;
158
+ selectedRows: ComputedRef<Row[]>;
159
+ selectedCount: ComputedRef<number>;
160
+ /** Replace the whole selectedIds set (used by UI adapters to keep cross-page selection stable) */
161
+ setSelectedIds: (ids: (string | number)[]) => void;
162
+ select: (id: string | number) => void;
163
+ deselect: (id: string | number) => void;
164
+ toggle: (id: string | number) => void;
165
+ selectAll: () => void;
166
+ clear: () => void;
167
+ isSelected: (id: string | number) => boolean;
168
+ }
169
+ interface ActionContext<Row = any> {
170
+ row?: Row;
171
+ selectedRows: Row[];
172
+ selectedIds: (string | number)[];
173
+ /** Current list query (if available) */
174
+ query?: Record<string, unknown>;
175
+ /** Current list sort (if available) */
176
+ sort?: CrudSort | null;
177
+ /** Current page (if available) */
178
+ page?: number;
179
+ /** Current page size (if available) */
180
+ pageSize?: number;
181
+ refresh: () => Promise<void>;
182
+ clearSelection: () => void;
183
+ }
184
+ interface CrudAction<Row = any> {
185
+ id: string;
186
+ label: string;
187
+ icon?: any;
188
+ type?: 'primary' | 'default' | 'success' | 'warning' | 'error';
189
+ area: 'toolbar' | 'row' | 'batch';
190
+ order?: number;
191
+ confirm?: boolean | string;
192
+ visible?: (ctx: ActionContext<Row>) => boolean;
193
+ disabled?: (ctx: ActionContext<Row>) => boolean;
194
+ onClick: (ctx: ActionContext<Row>) => Promise<void> | void;
195
+ }
196
+ interface UseCrudActionsOptions<Row = any> {
197
+ actions?: CrudAction<Row>[];
198
+ adapter?: CrudAdapter<Row>;
199
+ getId?: (row: Row) => string | number;
200
+ refresh?: () => Promise<void>;
201
+ clearSelection?: () => void;
202
+ onError?: (error: unknown) => void;
203
+ }
204
+ interface UseCrudActionsReturn<Row = any> {
205
+ actions: Ref<CrudAction<Row>[]>;
206
+ getByArea: (area: CrudAction['area']) => CrudAction<Row>[];
207
+ register: (action: CrudAction<Row>) => void;
208
+ unregister: (id: string) => void;
209
+ }
210
+
211
+ /**
212
+ * Core hook for CRUD action management
213
+ */
214
+ declare function useCrudActions<Row = any>(options?: UseCrudActionsOptions<Row>): UseCrudActionsReturn<Row>;
215
+ interface CreateActionOptions {
216
+ label?: string;
217
+ onClick: () => void;
218
+ }
219
+ declare function createAction(options: CreateActionOptions): CrudAction;
220
+ interface EditActionOptions<Row = any> {
221
+ label?: string;
222
+ onClick: (row: Row) => void;
223
+ }
224
+ declare function editAction<Row = any>(options: EditActionOptions<Row>): CrudAction<Row>;
225
+ interface DeleteActionOptions<Row = any> {
226
+ label?: string;
227
+ adapter: CrudAdapter<Row>;
228
+ getId?: (row: Row) => string | number;
229
+ confirm?: boolean | string;
230
+ onSuccess?: () => void;
231
+ onError?: (error: unknown) => void;
232
+ }
233
+ declare function deleteAction<Row = any>(options: DeleteActionOptions<Row>): CrudAction<Row>;
234
+ interface BatchDeleteActionOptions<Row = any> {
235
+ label?: string;
236
+ adapter: CrudAdapter<Row>;
237
+ getId?: (row: Row) => string | number;
238
+ confirm?: boolean | string;
239
+ onSuccess?: () => void;
240
+ onError?: (error: unknown) => void;
241
+ }
242
+ declare function batchDeleteAction<Row = any>(options: BatchDeleteActionOptions<Row>): CrudAction<Row>;
243
+ interface ExportActionOptions<Row = any> {
244
+ label?: string;
245
+ adapter: CrudAdapter<Row>;
246
+ filename?: string;
247
+ onSuccess?: () => void;
248
+ onError?: (error: unknown) => void;
249
+ /** UI layer provides download handler */
250
+ handleExport?: (result: any, filename?: string) => void;
251
+ }
252
+ declare function exportAction<Row = any>(options: ExportActionOptions<Row>): CrudAction<Row>;
253
+ /**
254
+ * Preset action factories
255
+ */
256
+ declare const presetActions: {
257
+ create: typeof createAction;
258
+ edit: typeof editAction;
259
+ delete: typeof deleteAction;
260
+ batchDelete: typeof batchDeleteAction;
261
+ export: typeof exportAction;
262
+ };
263
+
264
+ /**
265
+ * Core hook for CRUD form state management
266
+ */
267
+ declare function useCrudForm<Row = any>(options: UseCrudFormOptions<Row>): UseCrudFormReturn<Row>;
268
+
269
+ /**
270
+ * Core hook for CRUD list operations - handles pagination, sorting, query, and data fetching
271
+ */
272
+ declare function useCrudList<Row = any, Query extends object = Record<string, unknown>>(options: UseCrudListOptions<Row, Query>): UseCrudListReturn<Row, Query>;
273
+
274
+ interface UseCrudRouteSyncOptions<Query = Record<string, unknown>> {
275
+ /** Query ref from useCrudList */
276
+ query: Ref<Query>;
277
+ /** Set query function from useCrudList */
278
+ setQuery: (partial: Partial<Query>, options?: SetQueryOptions) => void;
279
+ /** Router instance (vue-router) */
280
+ router?: any;
281
+ /** Route instance (vue-router) */
282
+ route?: any;
283
+ /** Query key in URL (default: 'q') */
284
+ queryKey?: string;
285
+ /** Serialize query to string (default: JSON.stringify) */
286
+ serialize?: (query: Query) => string;
287
+ /** Deserialize string to query (default: JSON.parse) */
288
+ deserialize?: (str: string) => Partial<Query>;
289
+ /** Debounce delay in ms (default: 300) */
290
+ debounceMs?: number;
291
+ /**
292
+ * How to apply query when syncing from route (default: 'replace')
293
+ * - replace: URL is the source of truth (prevents stale keys from lingering)
294
+ * - merge: merge into current query
295
+ */
296
+ syncFromRouteMode?: 'replace' | 'merge';
297
+ }
298
+ /**
299
+ * Sync CRUD query with URL route query
300
+ */
301
+ declare function useCrudRouteSync<Query = Record<string, unknown>>(options: UseCrudRouteSyncOptions<Query>): {
302
+ syncFromRoute: () => void;
303
+ syncToRoute: () => void;
304
+ };
305
+
306
+ /**
307
+ * Core hook for CRUD selection management
308
+ */
309
+ declare function useCrudSelection<Row = any>(options: UseCrudSelectionOptions<Row>): UseCrudSelectionReturn<Row>;
310
+
311
+ /**
312
+ * Define columns with type inference
313
+ */
314
+ declare function defineColumns<Row = any, const Columns extends CrudColumn<Row>[] = CrudColumn<Row>[]>(columns: Columns): Columns;
315
+ /**
316
+ * Create columns from fields with optional overrides
317
+ */
318
+ declare function createColumnsFromFields<Row = any>(fields: CrudField<Row>[], options?: {
319
+ overrides?: Partial<Record<string, Partial<CrudColumn<Row>>>>;
320
+ defaults?: Partial<CrudColumn<Row>>;
321
+ filter?: (field: CrudField<Row>) => boolean;
322
+ }): CrudColumn<Row>[];
323
+
324
+ /**
325
+ * Define fields with type inference
326
+ */
327
+ declare function defineFields<Row = any, FormModel = Row, const Fields extends CrudField<Row, FormModel>[] = CrudField<Row, FormModel>[]>(fields: Fields): Fields;
328
+ /**
329
+ * Filter fields by surface visibility
330
+ */
331
+ declare function filterFieldsBySurface<Row = any, FormModel = Row>(fields: CrudField<Row, FormModel>[], surface: FieldContext['surface'], ctx?: Partial<FieldContext<Row, FormModel>>): CrudField<Row, FormModel>[];
332
+ /**
333
+ * Get field label (resolve function if needed)
334
+ */
335
+ declare function getFieldLabel(field: CrudField): string;
336
+
337
+ export { type ActionContext, type BatchDeleteActionOptions, type CellContext, type CreateActionOptions, type CrudAction, type CrudAdapter, type CrudColumn, type CrudField, type CrudFieldType, type CrudSort, type CrudTableCellContext, type DeleteActionOptions, type EditActionOptions, type ExportActionOptions, type ExportParams, type ExportResult, type FieldContext, type ListParams, type ListResult, type SetQueryOptions, type UseCrudActionsOptions, type UseCrudActionsReturn, type UseCrudFormOptions, type UseCrudFormReturn, type UseCrudListOptions, type UseCrudListReturn, type UseCrudRouteSyncOptions, type UseCrudSelectionOptions, type UseCrudSelectionReturn, batchDeleteAction, createAction, createColumnsFromFields, defineColumns, defineFields, deleteAction, editAction, exportAction, filterFieldsBySurface, getFieldLabel, presetActions, useCrudActions, useCrudForm, useCrudList, useCrudRouteSync, useCrudSelection };
@@ -0,0 +1,337 @@
1
+ import { Ref, Reactive, ComputedRef } from 'vue';
2
+
3
+ /**
4
+ * Sort configuration
5
+ */
6
+ interface CrudSort<Field extends string = string> {
7
+ field: Field;
8
+ order: 'ascend' | 'descend';
9
+ }
10
+ /**
11
+ * Field visibility context
12
+ */
13
+ interface FieldContext<Row = any, FormModel = Row> {
14
+ surface: 'search' | 'table' | 'form' | 'detail';
15
+ row?: Row;
16
+ formModel?: FormModel;
17
+ query?: Record<string, unknown>;
18
+ }
19
+ /**
20
+ * Cell render context for table columns
21
+ */
22
+ interface CellContext<Row = any> {
23
+ row: Row;
24
+ rowIndex: number;
25
+ value: any;
26
+ }
27
+ /** Alias for backward compatibility */
28
+ type CrudTableCellContext<Row = any> = CellContext<Row>;
29
+ /**
30
+ * Field definition - core schema for form/search/table
31
+ */
32
+ type CrudFieldType = 'text' | 'textarea' | 'select' | 'date' | 'datetime' | 'dateRange' | 'datetimeRange' | 'switch' | 'number' | 'money' | 'custom';
33
+ interface CrudField<Row = any, FormModel = Row, UiExt = unknown> {
34
+ key: string;
35
+ label: string | (() => string);
36
+ type: CrudFieldType | (string & {});
37
+ required?: boolean;
38
+ visibleIn?: {
39
+ search?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
40
+ table?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
41
+ form?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
42
+ detail?: boolean | ((ctx: FieldContext<Row, FormModel>) => boolean);
43
+ };
44
+ /** UI-specific extensions, defined by adapter layer */
45
+ ui?: UiExt;
46
+ }
47
+ /**
48
+ * Table column definition
49
+ */
50
+ interface CrudColumn<Row = any, UiExt = unknown> {
51
+ key: string;
52
+ label?: string | (() => string);
53
+ width?: number;
54
+ minWidth?: number;
55
+ fixed?: 'left' | 'right';
56
+ sortable?: boolean;
57
+ render?: (ctx: CellContext<Row>) => any;
58
+ /** UI-specific extensions */
59
+ ui?: UiExt;
60
+ }
61
+ interface ListParams<Query = Record<string, unknown>> {
62
+ page: number;
63
+ pageSize: number;
64
+ query: Query;
65
+ sort?: CrudSort | null;
66
+ signal?: AbortSignal;
67
+ }
68
+ interface ListResult<Row = any> {
69
+ items: Row[];
70
+ total: number;
71
+ }
72
+ interface ExportParams<Query = Record<string, unknown>> {
73
+ query: Query;
74
+ sort?: CrudSort | null;
75
+ signal?: AbortSignal;
76
+ }
77
+ type ExportResult = Blob | {
78
+ blob: Blob;
79
+ filename?: string;
80
+ } | {
81
+ url: string;
82
+ filename?: string;
83
+ };
84
+ /**
85
+ * CRUD data adapter interface
86
+ */
87
+ interface CrudAdapter<Row = any, Query = Record<string, unknown>> {
88
+ list: (params: ListParams<Query>) => Promise<ListResult<Row>>;
89
+ create?: (data: Partial<Row>) => Promise<Row>;
90
+ update?: (id: string | number, data: Partial<Row>) => Promise<Row>;
91
+ remove?: (id: string | number) => Promise<void>;
92
+ export?: (params: ExportParams<Query>) => Promise<ExportResult>;
93
+ getId?: (row: Row) => string | number;
94
+ }
95
+ interface UseCrudListOptions<Row = any, Query = Record<string, unknown>> {
96
+ adapter: CrudAdapter<Row, Query>;
97
+ initialQuery?: Query;
98
+ initialPage?: number;
99
+ initialPageSize?: number;
100
+ autoFetch?: boolean;
101
+ debounceMs?: number;
102
+ dedupe?: boolean;
103
+ onError?: (error: unknown) => void;
104
+ }
105
+ interface UseCrudListReturn<Row = any, Query = Record<string, unknown>> {
106
+ rows: Ref<Row[]>;
107
+ total: Ref<number>;
108
+ loading: Ref<boolean>;
109
+ error: Ref<unknown>;
110
+ page: Ref<number>;
111
+ pageSize: Ref<number>;
112
+ query: Ref<Query>;
113
+ sort: Ref<CrudSort | null>;
114
+ refresh: () => Promise<void>;
115
+ setQuery: (partial: Partial<Query>, options?: SetQueryOptions) => void;
116
+ setPage: (page: number) => void;
117
+ setPageSize: (size: number) => void;
118
+ setSort: (sort: CrudSort | null) => void;
119
+ reset: () => void;
120
+ }
121
+ interface SetQueryOptions {
122
+ /**
123
+ * How to apply the partial query update
124
+ * - merge: shallow merge into existing query (default)
125
+ * - replace: replace the whole query with partial
126
+ */
127
+ mode?: 'merge' | 'replace';
128
+ /** Keys to delete from current query before applying the update (useful for flat search forms) */
129
+ clearKeys?: string[];
130
+ /**
131
+ * Remove empty values after applying update.
132
+ * Treats `undefined | null | '' | [] | {}` as empty (deep).
133
+ * Keeps `0` / `false`.
134
+ */
135
+ pruneEmpty?: boolean;
136
+ }
137
+ interface UseCrudFormOptions<Row = any> {
138
+ fields: CrudField<Row>[];
139
+ initialData?: Partial<Row>;
140
+ }
141
+ interface UseCrudFormReturn<Row = any> {
142
+ model: Reactive<Partial<Row>>;
143
+ mode: Ref<'create' | 'edit'>;
144
+ dirty: ComputedRef<boolean>;
145
+ changedKeys: ComputedRef<string[]>;
146
+ changedData: ComputedRef<Partial<Row>>;
147
+ visibleFields: ComputedRef<CrudField<Row>[]>;
148
+ reset: (data?: Partial<Row>) => void;
149
+ setMode: (mode: 'create' | 'edit') => void;
150
+ getSubmitData: () => Partial<Row>;
151
+ }
152
+ interface UseCrudSelectionOptions<Row = any> {
153
+ rows: Ref<Row[]>;
154
+ getId?: (row: Row) => string | number;
155
+ }
156
+ interface UseCrudSelectionReturn<Row = any> {
157
+ selectedIds: Ref<Set<string | number>>;
158
+ selectedRows: ComputedRef<Row[]>;
159
+ selectedCount: ComputedRef<number>;
160
+ /** Replace the whole selectedIds set (used by UI adapters to keep cross-page selection stable) */
161
+ setSelectedIds: (ids: (string | number)[]) => void;
162
+ select: (id: string | number) => void;
163
+ deselect: (id: string | number) => void;
164
+ toggle: (id: string | number) => void;
165
+ selectAll: () => void;
166
+ clear: () => void;
167
+ isSelected: (id: string | number) => boolean;
168
+ }
169
+ interface ActionContext<Row = any> {
170
+ row?: Row;
171
+ selectedRows: Row[];
172
+ selectedIds: (string | number)[];
173
+ /** Current list query (if available) */
174
+ query?: Record<string, unknown>;
175
+ /** Current list sort (if available) */
176
+ sort?: CrudSort | null;
177
+ /** Current page (if available) */
178
+ page?: number;
179
+ /** Current page size (if available) */
180
+ pageSize?: number;
181
+ refresh: () => Promise<void>;
182
+ clearSelection: () => void;
183
+ }
184
+ interface CrudAction<Row = any> {
185
+ id: string;
186
+ label: string;
187
+ icon?: any;
188
+ type?: 'primary' | 'default' | 'success' | 'warning' | 'error';
189
+ area: 'toolbar' | 'row' | 'batch';
190
+ order?: number;
191
+ confirm?: boolean | string;
192
+ visible?: (ctx: ActionContext<Row>) => boolean;
193
+ disabled?: (ctx: ActionContext<Row>) => boolean;
194
+ onClick: (ctx: ActionContext<Row>) => Promise<void> | void;
195
+ }
196
+ interface UseCrudActionsOptions<Row = any> {
197
+ actions?: CrudAction<Row>[];
198
+ adapter?: CrudAdapter<Row>;
199
+ getId?: (row: Row) => string | number;
200
+ refresh?: () => Promise<void>;
201
+ clearSelection?: () => void;
202
+ onError?: (error: unknown) => void;
203
+ }
204
+ interface UseCrudActionsReturn<Row = any> {
205
+ actions: Ref<CrudAction<Row>[]>;
206
+ getByArea: (area: CrudAction['area']) => CrudAction<Row>[];
207
+ register: (action: CrudAction<Row>) => void;
208
+ unregister: (id: string) => void;
209
+ }
210
+
211
+ /**
212
+ * Core hook for CRUD action management
213
+ */
214
+ declare function useCrudActions<Row = any>(options?: UseCrudActionsOptions<Row>): UseCrudActionsReturn<Row>;
215
+ interface CreateActionOptions {
216
+ label?: string;
217
+ onClick: () => void;
218
+ }
219
+ declare function createAction(options: CreateActionOptions): CrudAction;
220
+ interface EditActionOptions<Row = any> {
221
+ label?: string;
222
+ onClick: (row: Row) => void;
223
+ }
224
+ declare function editAction<Row = any>(options: EditActionOptions<Row>): CrudAction<Row>;
225
+ interface DeleteActionOptions<Row = any> {
226
+ label?: string;
227
+ adapter: CrudAdapter<Row>;
228
+ getId?: (row: Row) => string | number;
229
+ confirm?: boolean | string;
230
+ onSuccess?: () => void;
231
+ onError?: (error: unknown) => void;
232
+ }
233
+ declare function deleteAction<Row = any>(options: DeleteActionOptions<Row>): CrudAction<Row>;
234
+ interface BatchDeleteActionOptions<Row = any> {
235
+ label?: string;
236
+ adapter: CrudAdapter<Row>;
237
+ getId?: (row: Row) => string | number;
238
+ confirm?: boolean | string;
239
+ onSuccess?: () => void;
240
+ onError?: (error: unknown) => void;
241
+ }
242
+ declare function batchDeleteAction<Row = any>(options: BatchDeleteActionOptions<Row>): CrudAction<Row>;
243
+ interface ExportActionOptions<Row = any> {
244
+ label?: string;
245
+ adapter: CrudAdapter<Row>;
246
+ filename?: string;
247
+ onSuccess?: () => void;
248
+ onError?: (error: unknown) => void;
249
+ /** UI layer provides download handler */
250
+ handleExport?: (result: any, filename?: string) => void;
251
+ }
252
+ declare function exportAction<Row = any>(options: ExportActionOptions<Row>): CrudAction<Row>;
253
+ /**
254
+ * Preset action factories
255
+ */
256
+ declare const presetActions: {
257
+ create: typeof createAction;
258
+ edit: typeof editAction;
259
+ delete: typeof deleteAction;
260
+ batchDelete: typeof batchDeleteAction;
261
+ export: typeof exportAction;
262
+ };
263
+
264
+ /**
265
+ * Core hook for CRUD form state management
266
+ */
267
+ declare function useCrudForm<Row = any>(options: UseCrudFormOptions<Row>): UseCrudFormReturn<Row>;
268
+
269
+ /**
270
+ * Core hook for CRUD list operations - handles pagination, sorting, query, and data fetching
271
+ */
272
+ declare function useCrudList<Row = any, Query extends object = Record<string, unknown>>(options: UseCrudListOptions<Row, Query>): UseCrudListReturn<Row, Query>;
273
+
274
+ interface UseCrudRouteSyncOptions<Query = Record<string, unknown>> {
275
+ /** Query ref from useCrudList */
276
+ query: Ref<Query>;
277
+ /** Set query function from useCrudList */
278
+ setQuery: (partial: Partial<Query>, options?: SetQueryOptions) => void;
279
+ /** Router instance (vue-router) */
280
+ router?: any;
281
+ /** Route instance (vue-router) */
282
+ route?: any;
283
+ /** Query key in URL (default: 'q') */
284
+ queryKey?: string;
285
+ /** Serialize query to string (default: JSON.stringify) */
286
+ serialize?: (query: Query) => string;
287
+ /** Deserialize string to query (default: JSON.parse) */
288
+ deserialize?: (str: string) => Partial<Query>;
289
+ /** Debounce delay in ms (default: 300) */
290
+ debounceMs?: number;
291
+ /**
292
+ * How to apply query when syncing from route (default: 'replace')
293
+ * - replace: URL is the source of truth (prevents stale keys from lingering)
294
+ * - merge: merge into current query
295
+ */
296
+ syncFromRouteMode?: 'replace' | 'merge';
297
+ }
298
+ /**
299
+ * Sync CRUD query with URL route query
300
+ */
301
+ declare function useCrudRouteSync<Query = Record<string, unknown>>(options: UseCrudRouteSyncOptions<Query>): {
302
+ syncFromRoute: () => void;
303
+ syncToRoute: () => void;
304
+ };
305
+
306
+ /**
307
+ * Core hook for CRUD selection management
308
+ */
309
+ declare function useCrudSelection<Row = any>(options: UseCrudSelectionOptions<Row>): UseCrudSelectionReturn<Row>;
310
+
311
+ /**
312
+ * Define columns with type inference
313
+ */
314
+ declare function defineColumns<Row = any, const Columns extends CrudColumn<Row>[] = CrudColumn<Row>[]>(columns: Columns): Columns;
315
+ /**
316
+ * Create columns from fields with optional overrides
317
+ */
318
+ declare function createColumnsFromFields<Row = any>(fields: CrudField<Row>[], options?: {
319
+ overrides?: Partial<Record<string, Partial<CrudColumn<Row>>>>;
320
+ defaults?: Partial<CrudColumn<Row>>;
321
+ filter?: (field: CrudField<Row>) => boolean;
322
+ }): CrudColumn<Row>[];
323
+
324
+ /**
325
+ * Define fields with type inference
326
+ */
327
+ declare function defineFields<Row = any, FormModel = Row, const Fields extends CrudField<Row, FormModel>[] = CrudField<Row, FormModel>[]>(fields: Fields): Fields;
328
+ /**
329
+ * Filter fields by surface visibility
330
+ */
331
+ declare function filterFieldsBySurface<Row = any, FormModel = Row>(fields: CrudField<Row, FormModel>[], surface: FieldContext['surface'], ctx?: Partial<FieldContext<Row, FormModel>>): CrudField<Row, FormModel>[];
332
+ /**
333
+ * Get field label (resolve function if needed)
334
+ */
335
+ declare function getFieldLabel(field: CrudField): string;
336
+
337
+ export { type ActionContext, type BatchDeleteActionOptions, type CellContext, type CreateActionOptions, type CrudAction, type CrudAdapter, type CrudColumn, type CrudField, type CrudFieldType, type CrudSort, type CrudTableCellContext, type DeleteActionOptions, type EditActionOptions, type ExportActionOptions, type ExportParams, type ExportResult, type FieldContext, type ListParams, type ListResult, type SetQueryOptions, type UseCrudActionsOptions, type UseCrudActionsReturn, type UseCrudFormOptions, type UseCrudFormReturn, type UseCrudListOptions, type UseCrudListReturn, type UseCrudRouteSyncOptions, type UseCrudSelectionOptions, type UseCrudSelectionReturn, batchDeleteAction, createAction, createColumnsFromFields, defineColumns, defineFields, deleteAction, editAction, exportAction, filterFieldsBySurface, getFieldLabel, presetActions, useCrudActions, useCrudForm, useCrudList, useCrudRouteSync, useCrudSelection };