@avora-labs/meta-forge 1.0.5
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/README.md +63 -0
- package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs +103 -0
- package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs.map +1 -0
- package/fesm2022/avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs +287 -0
- package/fesm2022/avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs.map +1 -0
- package/fesm2022/avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs +467 -0
- package/fesm2022/avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs.map +1 -0
- package/fesm2022/avora-labs-meta-forge-login.page-etTr5NqJ.mjs +181 -0
- package/fesm2022/avora-labs-meta-forge-login.page-etTr5NqJ.mjs.map +1 -0
- package/fesm2022/avora-labs-meta-forge.mjs +6544 -0
- package/fesm2022/avora-labs-meta-forge.mjs.map +1 -0
- package/package.json +37 -0
- package/styles/_palettes.scss +85 -0
- package/styles/_themes.scss +97 -0
- package/styles/_variables.scss +57 -0
- package/styles/styles.scss +296 -0
- package/types/avora-labs-meta-forge.d.ts +2528 -0
|
@@ -0,0 +1,2528 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Type, InjectionToken, OnDestroy, OnChanges, ViewContainerRef, SimpleChanges, OnInit, Signal, EventEmitter, Provider } from '@angular/core';
|
|
3
|
+
import * as rxjs from 'rxjs';
|
|
4
|
+
import { Params, Data, CanDeactivateFn, CanActivateFn, Routes, Router } from '@angular/router';
|
|
5
|
+
import { FormGroup, AbstractControl, FormArray } from '@angular/forms';
|
|
6
|
+
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
7
|
+
import { SafeHtml } from '@angular/platform-browser';
|
|
8
|
+
import { HttpInterceptorFn } from '@angular/common/http';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* AvoraMetaForge — Condition Metadata
|
|
12
|
+
*
|
|
13
|
+
* Extended condition system supporting:
|
|
14
|
+
* - 20+ comparison operators
|
|
15
|
+
* - Logical grouping (and/or/negate)
|
|
16
|
+
* - State store references
|
|
17
|
+
* - Custom evaluator functions
|
|
18
|
+
* - Date comparisons
|
|
19
|
+
* - Array operations
|
|
20
|
+
* - Type checking
|
|
21
|
+
*/
|
|
22
|
+
type ConditionOperator = '==' | '!=' | '===' | '!==' | '>' | '>=' | '<' | '<=' | 'in' | 'notIn' | 'contains' | 'startsWith' | 'endsWith' | 'truthy' | 'falsy' | 'empty' | 'notEmpty' | 'regex' | 'between' | 'notBetween' | 'hasKey' | 'isArray' | 'isObject' | 'isString' | 'isNumber' | 'isNull' | 'isNotNull' | 'lengthEquals' | 'lengthGreaterThan' | 'lengthLessThan' | 'dateBefore' | 'dateAfter' | 'dateEquals' | 'arrayContains' | 'arrayNotContains' | 'matchesAny' | 'matchesAll' | 'custom';
|
|
23
|
+
interface ConditionMeta {
|
|
24
|
+
/** Field path to evaluate (dot notation for nested, e.g., 'user.role') */
|
|
25
|
+
field?: string;
|
|
26
|
+
/** Comparison operator */
|
|
27
|
+
operator: ConditionOperator;
|
|
28
|
+
/** Value to compare against. Arrays for 'in', 'between', etc. */
|
|
29
|
+
value?: any;
|
|
30
|
+
/** Logical AND — all conditions must be true */
|
|
31
|
+
and?: ConditionMeta[];
|
|
32
|
+
/** Logical OR — at least one condition must be true */
|
|
33
|
+
or?: ConditionMeta[];
|
|
34
|
+
/** Negate the result */
|
|
35
|
+
negate?: boolean;
|
|
36
|
+
/** Custom evaluator function key */
|
|
37
|
+
custom?: string;
|
|
38
|
+
/** Source of the field value */
|
|
39
|
+
source?: 'context' | 'state' | 'route' | 'form' | 'storage';
|
|
40
|
+
/** For 'between' operator: [min, max] */
|
|
41
|
+
range?: [any, any];
|
|
42
|
+
/** Case-insensitive comparison for string operators */
|
|
43
|
+
caseInsensitive?: boolean;
|
|
44
|
+
/** Catch-all for future / plugin-specific properties */
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type FieldType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'textarea' | 'select' | 'multi-select' | 'radio' | 'checkbox' | 'toggle' | 'date' | 'datetime' | 'time' | 'file' | 'color' | 'range' | 'hidden' | 'divider' | 'heading' | 'rich-text' | 'code-editor' | 'auto-complete' | 'tags' | 'rating' | 'slider' | 'switch' | 'image-upload' | 'signature' | 'otp' | 'phone' | 'address' | 'date-range' | 'time-range' | 'currency' | 'percentage' | 'group' | 'repeater' | 'custom';
|
|
49
|
+
type FormLayout = 'vertical' | 'horizontal' | 'grid' | 'inline' | 'stepper';
|
|
50
|
+
interface FormMeta {
|
|
51
|
+
/** Unique form identifier (used by reset-form, patch-form actions) */
|
|
52
|
+
id?: string;
|
|
53
|
+
fields: FieldMeta[];
|
|
54
|
+
layout?: FormLayout;
|
|
55
|
+
columns?: number;
|
|
56
|
+
submitLabel?: string;
|
|
57
|
+
cancelLabel?: string;
|
|
58
|
+
resetLabel?: string;
|
|
59
|
+
showCancel?: boolean;
|
|
60
|
+
showReset?: boolean;
|
|
61
|
+
/** Hide the submit button (useful for button-only forms) */
|
|
62
|
+
hideSubmit?: boolean;
|
|
63
|
+
/** API endpoint for direct form submission */
|
|
64
|
+
apiEndpoint?: string;
|
|
65
|
+
apiMethod?: HttpMethod$1;
|
|
66
|
+
/** Runs when form initializes (e.g., fetch data for edit mode) */
|
|
67
|
+
onLoad?: ActionMeta;
|
|
68
|
+
/** Runs on successful submit */
|
|
69
|
+
onSubmit?: ActionMeta;
|
|
70
|
+
/** Runs when cancel is clicked */
|
|
71
|
+
onCancel?: ActionMeta;
|
|
72
|
+
/** Runs when reset is clicked */
|
|
73
|
+
onReset?: ActionMeta;
|
|
74
|
+
/** Runs whenever any field value changes */
|
|
75
|
+
onChange?: ActionMeta;
|
|
76
|
+
/** Runs when form becomes valid */
|
|
77
|
+
onValid?: ActionMeta;
|
|
78
|
+
/** Runs when form becomes invalid */
|
|
79
|
+
onInvalid?: ActionMeta;
|
|
80
|
+
validators?: ValidatorMeta[];
|
|
81
|
+
/** Cross-field validators (e.g., password must match confirm) */
|
|
82
|
+
crossFieldValidators?: CrossFieldValidatorMeta[];
|
|
83
|
+
/** Pre-populate form values */
|
|
84
|
+
initialValues?: Record<string, any>;
|
|
85
|
+
/** Load initial values from API endpoint ID */
|
|
86
|
+
initialValuesApi?: string;
|
|
87
|
+
/** Multi-step wizard configuration */
|
|
88
|
+
steps?: FormStepMeta[];
|
|
89
|
+
/** Enable autosave */
|
|
90
|
+
autosave?: AutosaveMeta;
|
|
91
|
+
/** Warn before navigating away with unsaved changes */
|
|
92
|
+
confirmUnsaved?: boolean;
|
|
93
|
+
/** Custom unsaved changes message */
|
|
94
|
+
unsavedMessage?: string;
|
|
95
|
+
/** Disable the entire form */
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
/** Make the entire form read-only */
|
|
98
|
+
readOnly?: boolean;
|
|
99
|
+
/** CSS class for form container */
|
|
100
|
+
cssClass?: string;
|
|
101
|
+
/** Whether to scroll to first error on submit */
|
|
102
|
+
scrollToError?: boolean;
|
|
103
|
+
/** Show validation summary at top of form */
|
|
104
|
+
showValidationSummary?: boolean;
|
|
105
|
+
/** Whether to validate on field change or on submit only */
|
|
106
|
+
validateOn?: 'change' | 'blur' | 'submit';
|
|
107
|
+
/** Catch-all for future / plugin-specific properties */
|
|
108
|
+
[key: string]: any;
|
|
109
|
+
}
|
|
110
|
+
interface FieldMeta {
|
|
111
|
+
/** Unique key — maps to form control name */
|
|
112
|
+
key: string;
|
|
113
|
+
type: FieldType | string;
|
|
114
|
+
label?: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
placeholder?: string;
|
|
117
|
+
defaultValue?: any;
|
|
118
|
+
validators?: ValidatorMeta[];
|
|
119
|
+
options?: OptionMeta[];
|
|
120
|
+
/** Endpoint ID to load options from API */
|
|
121
|
+
optionsApi?: string;
|
|
122
|
+
/** Key in API response to use as label */
|
|
123
|
+
optionsLabelKey?: string;
|
|
124
|
+
/** Key in API response to use as value */
|
|
125
|
+
optionsValueKey?: string;
|
|
126
|
+
/** Show/hide based on condition */
|
|
127
|
+
visibleWhen?: ConditionMeta;
|
|
128
|
+
/** Disable based on condition */
|
|
129
|
+
disabledWhen?: ConditionMeta;
|
|
130
|
+
/** Custom component key for rendering */
|
|
131
|
+
customComponent?: string;
|
|
132
|
+
cssClass?: string;
|
|
133
|
+
colSpan?: number;
|
|
134
|
+
hint?: string;
|
|
135
|
+
prefix?: string;
|
|
136
|
+
suffix?: string;
|
|
137
|
+
readOnly?: boolean;
|
|
138
|
+
/** Statically disable this field */
|
|
139
|
+
disabled?: boolean;
|
|
140
|
+
autocomplete?: string;
|
|
141
|
+
rows?: number;
|
|
142
|
+
min?: number;
|
|
143
|
+
max?: number;
|
|
144
|
+
step?: number;
|
|
145
|
+
accept?: string;
|
|
146
|
+
multiple?: boolean;
|
|
147
|
+
text?: string;
|
|
148
|
+
/** Action to dispatch when field value changes */
|
|
149
|
+
onChange?: ActionMeta;
|
|
150
|
+
/** Action to dispatch when field loses focus */
|
|
151
|
+
onBlur?: ActionMeta;
|
|
152
|
+
/** Action to dispatch when field gains focus */
|
|
153
|
+
onFocus?: ActionMeta;
|
|
154
|
+
/** Field key this field depends on (cascade selects) */
|
|
155
|
+
dependsOn?: string;
|
|
156
|
+
/** API query params derived from dependent field value */
|
|
157
|
+
dependsOnParams?: Record<string, string>;
|
|
158
|
+
/** Clear this field when dependent field changes */
|
|
159
|
+
clearOnDependencyChange?: boolean;
|
|
160
|
+
/** Input mask pattern (e.g., '(000) 000-0000', '000-00-0000') */
|
|
161
|
+
mask?: string;
|
|
162
|
+
/** Mask guide character (default: '_') */
|
|
163
|
+
maskGuide?: string;
|
|
164
|
+
/** Derive this field's value from other field values. E.g., 'fullName = firstName + " " + lastName' */
|
|
165
|
+
computeFrom?: ComputeFieldMeta;
|
|
166
|
+
/** Make this field required only when condition is met */
|
|
167
|
+
requiredWhen?: ConditionMeta;
|
|
168
|
+
/** Fields within a group/repeater */
|
|
169
|
+
children?: FieldMeta[];
|
|
170
|
+
/** Min/max items for repeater */
|
|
171
|
+
minItems?: number;
|
|
172
|
+
maxItems?: number;
|
|
173
|
+
/** Label for add button in repeater */
|
|
174
|
+
addLabel?: string;
|
|
175
|
+
/** Max file size in bytes */
|
|
176
|
+
maxFileSize?: number;
|
|
177
|
+
/** Show upload progress */
|
|
178
|
+
showProgress?: boolean;
|
|
179
|
+
/** Max number of files for multi-upload */
|
|
180
|
+
maxFiles?: number;
|
|
181
|
+
/** Show image preview */
|
|
182
|
+
showPreview?: boolean;
|
|
183
|
+
/** Drag and drop upload */
|
|
184
|
+
dragDrop?: boolean;
|
|
185
|
+
/** Button color variant */
|
|
186
|
+
color?: string;
|
|
187
|
+
/** Button style variant */
|
|
188
|
+
variant?: string;
|
|
189
|
+
/** Action to dispatch when button is clicked */
|
|
190
|
+
onClick?: ActionMeta;
|
|
191
|
+
/** Custom HTML attributes */
|
|
192
|
+
customAttributes?: Record<string, string>;
|
|
193
|
+
/** Catch-all for future / plugin-specific properties */
|
|
194
|
+
[key: string]: any;
|
|
195
|
+
}
|
|
196
|
+
interface ValidatorMeta {
|
|
197
|
+
type: 'required' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'email' | 'url' | 'number' | 'integer' | 'match' | 'notMatch' | 'unique' | 'fileType' | 'fileSize' | 'dateRange' | 'custom' | string;
|
|
198
|
+
value?: any;
|
|
199
|
+
/** Custom error message */
|
|
200
|
+
message?: string;
|
|
201
|
+
/** Custom validator function key */
|
|
202
|
+
custom?: string;
|
|
203
|
+
/** Field key for 'match'/'notMatch' validators */
|
|
204
|
+
matchField?: string;
|
|
205
|
+
/** Validate only when this condition is met */
|
|
206
|
+
when?: ConditionMeta;
|
|
207
|
+
}
|
|
208
|
+
interface CrossFieldValidatorMeta {
|
|
209
|
+
type: 'match' | 'dateOrder' | 'atLeastOne' | 'custom' | string;
|
|
210
|
+
/** Fields involved */
|
|
211
|
+
fields: string[];
|
|
212
|
+
message: string;
|
|
213
|
+
custom?: string;
|
|
214
|
+
[key: string]: any;
|
|
215
|
+
}
|
|
216
|
+
interface OptionMeta {
|
|
217
|
+
label: string;
|
|
218
|
+
value: any;
|
|
219
|
+
disabled?: boolean;
|
|
220
|
+
icon?: string;
|
|
221
|
+
group?: string;
|
|
222
|
+
description?: string;
|
|
223
|
+
color?: string;
|
|
224
|
+
[key: string]: any;
|
|
225
|
+
}
|
|
226
|
+
interface FormStepMeta {
|
|
227
|
+
/** Step title */
|
|
228
|
+
title: string;
|
|
229
|
+
/** Step description / subtitle */
|
|
230
|
+
description?: string;
|
|
231
|
+
/** Step icon */
|
|
232
|
+
icon?: string;
|
|
233
|
+
/** Field keys included in this step */
|
|
234
|
+
fields: string[];
|
|
235
|
+
/** Validate before allowing next step */
|
|
236
|
+
validate?: boolean;
|
|
237
|
+
/** Action to run when entering this step */
|
|
238
|
+
onEnter?: ActionMeta;
|
|
239
|
+
/** Action to run when leaving this step */
|
|
240
|
+
onLeave?: ActionMeta;
|
|
241
|
+
/** Condition to skip this step */
|
|
242
|
+
skipWhen?: ConditionMeta;
|
|
243
|
+
/** Whether the step can be manually skipped */
|
|
244
|
+
optional?: boolean;
|
|
245
|
+
}
|
|
246
|
+
interface AutosaveMeta {
|
|
247
|
+
/** Debounce delay in milliseconds */
|
|
248
|
+
debounceMs: number;
|
|
249
|
+
/** API endpoint to auto-save to */
|
|
250
|
+
endpointId?: string;
|
|
251
|
+
/** Action to dispatch on autosave */
|
|
252
|
+
action?: ActionMeta;
|
|
253
|
+
/** Show save indicator */
|
|
254
|
+
showIndicator?: boolean;
|
|
255
|
+
}
|
|
256
|
+
interface ComputeFieldMeta {
|
|
257
|
+
/** Field keys to watch */
|
|
258
|
+
watch: string[];
|
|
259
|
+
/** Expression template. E.g., '{{firstName}} {{lastName}}' */
|
|
260
|
+
expression?: string;
|
|
261
|
+
/** Custom compute function key */
|
|
262
|
+
custom?: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
type CellType = 'text' | 'badge' | 'avatar' | 'date' | 'datetime' | 'currency' | 'number' | 'boolean' | 'link' | 'image' | 'progress' | 'actions' | 'icon' | 'color' | 'rating' | 'tags' | 'truncate' | 'html' | 'template' | 'time-ago' | 'file-size' | 'phone' | 'email' | 'url' | 'json' | 'copy' | 'editable' | 'select' | 'toggle' | 'custom';
|
|
266
|
+
interface TableMeta {
|
|
267
|
+
/** Unique table identifier (used by reload-table action) */
|
|
268
|
+
id?: string;
|
|
269
|
+
columns: ColumnMeta[];
|
|
270
|
+
dataSource: 'api' | 'static' | 'signal';
|
|
271
|
+
apiEndpoint?: string;
|
|
272
|
+
/** Endpoint ID registered in the API service (for mock or real endpoints) */
|
|
273
|
+
endpointId?: string;
|
|
274
|
+
staticData?: any[];
|
|
275
|
+
pagination?: PaginationMeta;
|
|
276
|
+
searchable?: boolean;
|
|
277
|
+
searchPlaceholder?: string;
|
|
278
|
+
searchFields?: string[];
|
|
279
|
+
filterable?: boolean;
|
|
280
|
+
sortable?: boolean;
|
|
281
|
+
defaultSortKey?: string;
|
|
282
|
+
defaultSortDirection?: 'asc' | 'desc';
|
|
283
|
+
actions?: TableActionMeta[];
|
|
284
|
+
bulkActions?: TableActionMeta[];
|
|
285
|
+
rowClick?: ActionMeta;
|
|
286
|
+
emptyMessage?: string;
|
|
287
|
+
selectable?: boolean;
|
|
288
|
+
showRowNumbers?: boolean;
|
|
289
|
+
title?: string;
|
|
290
|
+
headerActions?: TableActionMeta[];
|
|
291
|
+
filters?: TableFilterMeta[];
|
|
292
|
+
cssClass?: string;
|
|
293
|
+
variant?: 'default' | 'striped' | 'borderless' | 'glass' | 'elevated' | 'compact' | string;
|
|
294
|
+
/** Bump this number to bust the sessionStorage cache and re-seed from staticData */
|
|
295
|
+
dataVersion?: number;
|
|
296
|
+
striped?: boolean;
|
|
297
|
+
hoverable?: boolean;
|
|
298
|
+
/** Enable server-side pagination, sort, and filter */
|
|
299
|
+
serverSide?: boolean;
|
|
300
|
+
/** API pagination config (query param names, response paths) */
|
|
301
|
+
serverPagination?: ServerPaginationConfig;
|
|
302
|
+
/** Enable data export */
|
|
303
|
+
exportable?: boolean;
|
|
304
|
+
/** Supported export formats */
|
|
305
|
+
exportFormats?: ('csv' | 'json' | 'xlsx' | 'pdf')[];
|
|
306
|
+
/** Custom export filename (without extension) */
|
|
307
|
+
exportFilename?: string;
|
|
308
|
+
/** Columns to include in export (keys). If omitted, exports all visible */
|
|
309
|
+
exportColumns?: string[];
|
|
310
|
+
/** Enable inline row editing */
|
|
311
|
+
inlineEdit?: boolean;
|
|
312
|
+
/** Action to dispatch when an inline edit is saved */
|
|
313
|
+
onInlineEditSave?: ActionMeta;
|
|
314
|
+
/** Action to dispatch when an inline edit is cancelled */
|
|
315
|
+
onInlineEditCancel?: ActionMeta;
|
|
316
|
+
/** Enable row expansion (detail sub-row) */
|
|
317
|
+
expandable?: boolean;
|
|
318
|
+
/** Component key to render in expanded area */
|
|
319
|
+
expandComponent?: string;
|
|
320
|
+
/** Section to render in expanded area (alternative to component) */
|
|
321
|
+
expandSection?: SectionMeta;
|
|
322
|
+
/** Only allow one expanded row at a time */
|
|
323
|
+
singleExpand?: boolean;
|
|
324
|
+
/** Enable virtual scroll for large datasets */
|
|
325
|
+
virtualScroll?: boolean;
|
|
326
|
+
/** Row height for virtual scroll calculation */
|
|
327
|
+
rowHeight?: number;
|
|
328
|
+
/** Enable infinite scroll (load more on scroll) */
|
|
329
|
+
infiniteScroll?: boolean;
|
|
330
|
+
/** API endpoint for loading next page in infinite scroll */
|
|
331
|
+
loadMoreEndpoint?: string;
|
|
332
|
+
/** Show column visibility toggle */
|
|
333
|
+
columnToggle?: boolean;
|
|
334
|
+
/** Allow column reorder via drag */
|
|
335
|
+
columnReorder?: boolean;
|
|
336
|
+
/** Allow column resize via drag */
|
|
337
|
+
columnResize?: boolean;
|
|
338
|
+
/** Enable row drag-to-reorder */
|
|
339
|
+
reorderable?: boolean;
|
|
340
|
+
/** Action when row order changes */
|
|
341
|
+
onReorder?: ActionMeta;
|
|
342
|
+
/** Enable multi-column sort */
|
|
343
|
+
multiSort?: boolean;
|
|
344
|
+
/** Sticky header on scroll */
|
|
345
|
+
stickyHeader?: boolean;
|
|
346
|
+
/** Group rows by this column key */
|
|
347
|
+
groupBy?: string;
|
|
348
|
+
/** Collapsible groups */
|
|
349
|
+
groupCollapsible?: boolean;
|
|
350
|
+
/** Start groups collapsed */
|
|
351
|
+
groupCollapsed?: boolean;
|
|
352
|
+
/** Aggregate row configuration (footer totals) */
|
|
353
|
+
aggregates?: AggregateRowMeta[];
|
|
354
|
+
/** Selection mode */
|
|
355
|
+
selectionMode?: 'single' | 'multi' | 'checkbox';
|
|
356
|
+
/** Action when selection changes */
|
|
357
|
+
onSelectionChange?: ActionMeta;
|
|
358
|
+
/** Show "Select All" checkbox */
|
|
359
|
+
showSelectAll?: boolean;
|
|
360
|
+
/** Conditionally style rows based on data */
|
|
361
|
+
rowClass?: RowClassMeta[];
|
|
362
|
+
/** Row context menu (right-click) */
|
|
363
|
+
contextMenu?: TableActionMeta[];
|
|
364
|
+
/** Action on data load complete */
|
|
365
|
+
onDataLoad?: ActionMeta;
|
|
366
|
+
/** Action on data load error */
|
|
367
|
+
onDataError?: ActionMeta;
|
|
368
|
+
/** Refresh interval (ms) — auto-reload data periodically */
|
|
369
|
+
refreshInterval?: number;
|
|
370
|
+
/** Catch-all for future / plugin-specific properties */
|
|
371
|
+
[key: string]: any;
|
|
372
|
+
}
|
|
373
|
+
interface ColumnMeta {
|
|
374
|
+
key: string;
|
|
375
|
+
label: string;
|
|
376
|
+
type?: CellType | string;
|
|
377
|
+
sortable?: boolean;
|
|
378
|
+
filterable?: boolean;
|
|
379
|
+
width?: string;
|
|
380
|
+
minWidth?: string;
|
|
381
|
+
maxWidth?: string;
|
|
382
|
+
align?: 'left' | 'center' | 'right';
|
|
383
|
+
template?: string;
|
|
384
|
+
pipe?: string;
|
|
385
|
+
cssClass?: string;
|
|
386
|
+
badgeMap?: Record<string, string>;
|
|
387
|
+
avatarKey?: string;
|
|
388
|
+
subtitleKey?: string;
|
|
389
|
+
linkRoute?: string;
|
|
390
|
+
currencyCode?: string;
|
|
391
|
+
currencyDisplay?: string | boolean;
|
|
392
|
+
currencyCodeKey?: string;
|
|
393
|
+
dateFormat?: string;
|
|
394
|
+
visibleWhen?: ConditionMeta;
|
|
395
|
+
hidden?: boolean;
|
|
396
|
+
/** Pin/freeze column to left or right */
|
|
397
|
+
pin?: 'left' | 'right';
|
|
398
|
+
/** Column is resizable */
|
|
399
|
+
resizable?: boolean;
|
|
400
|
+
/** Column is reorderable */
|
|
401
|
+
reorderable?: boolean;
|
|
402
|
+
/** Tooltip text or template */
|
|
403
|
+
tooltip?: string;
|
|
404
|
+
/** Cell-level click action */
|
|
405
|
+
cellClick?: ActionMeta;
|
|
406
|
+
/** Wrap text in cell */
|
|
407
|
+
wrap?: boolean;
|
|
408
|
+
/** Max truncation length */
|
|
409
|
+
truncateAt?: number;
|
|
410
|
+
/** Header tooltip */
|
|
411
|
+
headerTooltip?: string;
|
|
412
|
+
/** Editable configuration (for inline edit) */
|
|
413
|
+
editable?: boolean;
|
|
414
|
+
editType?: 'text' | 'number' | 'select' | 'date' | 'toggle';
|
|
415
|
+
editOptions?: {
|
|
416
|
+
label: string;
|
|
417
|
+
value: any;
|
|
418
|
+
}[];
|
|
419
|
+
/** Cell format function key (for custom formatting) */
|
|
420
|
+
format?: string;
|
|
421
|
+
/** Aggregate function for this column */
|
|
422
|
+
aggregate?: 'sum' | 'avg' | 'min' | 'max' | 'count' | 'custom';
|
|
423
|
+
aggregateLabel?: string;
|
|
424
|
+
/** Validators applied to inline-edit input before committing */
|
|
425
|
+
editValidators?: ColumnEditValidatorMeta[];
|
|
426
|
+
/** Catch-all */
|
|
427
|
+
[key: string]: any;
|
|
428
|
+
}
|
|
429
|
+
interface PaginationMeta {
|
|
430
|
+
enabled: boolean;
|
|
431
|
+
pageSize?: number;
|
|
432
|
+
pageSizeOptions?: number[];
|
|
433
|
+
showPageSizeSelector?: boolean;
|
|
434
|
+
showTotal?: boolean;
|
|
435
|
+
/** Show first/last page buttons */
|
|
436
|
+
showFirstLast?: boolean;
|
|
437
|
+
/** Max page buttons to show */
|
|
438
|
+
maxPages?: number;
|
|
439
|
+
/** Show "Showing X-Y of Z" text */
|
|
440
|
+
showRange?: boolean;
|
|
441
|
+
}
|
|
442
|
+
interface ServerPaginationConfig {
|
|
443
|
+
/** Query param name for page number (default: 'page') */
|
|
444
|
+
pageParam?: string;
|
|
445
|
+
/** Query param name for page size (default: 'size') */
|
|
446
|
+
sizeParam?: string;
|
|
447
|
+
/** Query param name for sort field (default: 'sort') */
|
|
448
|
+
sortParam?: string;
|
|
449
|
+
/** Query param name for sort direction (default: 'direction') */
|
|
450
|
+
directionParam?: string;
|
|
451
|
+
/** Query param name for search (default: 'search') */
|
|
452
|
+
searchParam?: string;
|
|
453
|
+
/** Query param name for filter (default uses filter key) */
|
|
454
|
+
filterParams?: Record<string, string>;
|
|
455
|
+
/** Path in response to data array (default: 'data') */
|
|
456
|
+
dataPath?: string;
|
|
457
|
+
/** Path in response to total count (default: 'total') */
|
|
458
|
+
totalPath?: string;
|
|
459
|
+
/** Path in response to total pages */
|
|
460
|
+
totalPagesPath?: string;
|
|
461
|
+
}
|
|
462
|
+
interface TableActionMeta {
|
|
463
|
+
id: string;
|
|
464
|
+
label: string;
|
|
465
|
+
icon?: string;
|
|
466
|
+
variant?: 'primary' | 'secondary' | 'danger' | 'ghost' | 'success' | 'warning' | string;
|
|
467
|
+
action: ActionMeta;
|
|
468
|
+
visibleWhen?: ConditionMeta;
|
|
469
|
+
disabledWhen?: ConditionMeta;
|
|
470
|
+
confirm?: string;
|
|
471
|
+
/** Tooltip for the action button */
|
|
472
|
+
tooltip?: string;
|
|
473
|
+
/** Show as dropdown menu item instead of inline button */
|
|
474
|
+
menuItem?: boolean;
|
|
475
|
+
/** Keyboard shortcut hint */
|
|
476
|
+
shortcut?: string;
|
|
477
|
+
[key: string]: any;
|
|
478
|
+
}
|
|
479
|
+
interface TableFilterMeta {
|
|
480
|
+
key: string;
|
|
481
|
+
label: string;
|
|
482
|
+
type?: 'select' | 'text' | 'date' | 'date-range' | 'number-range' | 'multi-select' | 'toggle';
|
|
483
|
+
options?: {
|
|
484
|
+
label: string;
|
|
485
|
+
value: any;
|
|
486
|
+
}[];
|
|
487
|
+
defaultValue?: any;
|
|
488
|
+
placeholder?: string;
|
|
489
|
+
/** For server-side: query param name */
|
|
490
|
+
queryParam?: string;
|
|
491
|
+
}
|
|
492
|
+
interface AggregateRowMeta {
|
|
493
|
+
/** Column key to aggregate */
|
|
494
|
+
columnKey: string;
|
|
495
|
+
/** Aggregate function */
|
|
496
|
+
type: 'sum' | 'avg' | 'min' | 'max' | 'count' | 'custom';
|
|
497
|
+
/** Display label */
|
|
498
|
+
label?: string;
|
|
499
|
+
/** Format (e.g., currency, percentage) */
|
|
500
|
+
format?: string;
|
|
501
|
+
/** Custom aggregate function key */
|
|
502
|
+
custom?: string;
|
|
503
|
+
}
|
|
504
|
+
interface RowClassMeta {
|
|
505
|
+
/** Condition to evaluate for each row */
|
|
506
|
+
condition: ConditionMeta;
|
|
507
|
+
/** CSS class to apply when condition is true */
|
|
508
|
+
cssClass: string;
|
|
509
|
+
}
|
|
510
|
+
interface ColumnEditValidatorMeta {
|
|
511
|
+
type: 'required' | 'minLength' | 'maxLength' | 'min' | 'max' | 'pattern' | 'email' | 'number' | string;
|
|
512
|
+
/** Validator parameter (e.g., minLength: 3, pattern: '^[A-Z]') */
|
|
513
|
+
value?: any;
|
|
514
|
+
/** Custom error message shown below the inline input */
|
|
515
|
+
message?: string;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* AvoraMetaForge — Section Metadata
|
|
520
|
+
*
|
|
521
|
+
* Sections are the building blocks within a page. Each section has a type
|
|
522
|
+
* and configuration. Extended with new section types for drawers, modals,
|
|
523
|
+
* tabs, accordions, and more.
|
|
524
|
+
*/
|
|
525
|
+
|
|
526
|
+
interface SectionMeta {
|
|
527
|
+
type: 'form' | 'table' | 'card' | 'stats-grid' | 'page-header' | 'html' | 'stepper-form' | 'tabs' | 'accordion' | 'timeline' | 'steps' | 'chart' | 'map' | 'calendar' | 'kanban' | 'tree' | 'gallery' | 'markdown' | 'iframe' | 'divider' | 'spacer' | 'alert' | 'empty-state' | 'skeleton' | 'custom' | string;
|
|
528
|
+
config: FormMeta | TableMeta | CardMeta | StatsGridMeta | PageHeaderMeta | HtmlMeta | TabsMeta | AccordionMeta | TimelineMeta | AlertMeta | EmptyStateMeta | IframeMeta | DividerMeta | SpacerMeta | Record<string, any>;
|
|
529
|
+
/** Section ID (referenced by actions like reload-table, reset-form) */
|
|
530
|
+
id?: string;
|
|
531
|
+
visibleWhen?: ConditionMeta;
|
|
532
|
+
cssClass?: string;
|
|
533
|
+
style?: Record<string, string>;
|
|
534
|
+
gridArea?: string;
|
|
535
|
+
gridColumn?: string;
|
|
536
|
+
gridRow?: string;
|
|
537
|
+
/** Section title (rendered as a header above the section) */
|
|
538
|
+
title?: string;
|
|
539
|
+
/** Section subtitle */
|
|
540
|
+
subtitle?: string;
|
|
541
|
+
/** Collapsible section */
|
|
542
|
+
collapsible?: boolean;
|
|
543
|
+
/** Start collapsed */
|
|
544
|
+
collapsed?: boolean;
|
|
545
|
+
/** Section-level loading state */
|
|
546
|
+
loading?: boolean;
|
|
547
|
+
/** Action to dispatch when section becomes visible (lazy-load) */
|
|
548
|
+
onVisible?: ActionMeta;
|
|
549
|
+
/** Animation for section entrance */
|
|
550
|
+
animation?: 'fade-in' | 'slide-up' | 'slide-left' | 'zoom-in' | 'none' | string;
|
|
551
|
+
/** Animation delay (ms) */
|
|
552
|
+
animationDelay?: number;
|
|
553
|
+
/** Catch-all */
|
|
554
|
+
[key: string]: any;
|
|
555
|
+
}
|
|
556
|
+
interface PageHeaderMeta {
|
|
557
|
+
title: string;
|
|
558
|
+
subtitle?: string;
|
|
559
|
+
titleTemplate?: string;
|
|
560
|
+
actions?: PageHeaderActionMeta[];
|
|
561
|
+
showBack?: boolean;
|
|
562
|
+
/** Breadcrumbs in header */
|
|
563
|
+
breadcrumbs?: {
|
|
564
|
+
label: string;
|
|
565
|
+
path?: string;
|
|
566
|
+
}[];
|
|
567
|
+
/** Avatar/icon next to title */
|
|
568
|
+
avatar?: string;
|
|
569
|
+
/** Status badge */
|
|
570
|
+
status?: {
|
|
571
|
+
label: string;
|
|
572
|
+
color: string;
|
|
573
|
+
};
|
|
574
|
+
[key: string]: any;
|
|
575
|
+
}
|
|
576
|
+
interface PageHeaderActionMeta {
|
|
577
|
+
label: string;
|
|
578
|
+
icon?: string;
|
|
579
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'success' | string;
|
|
580
|
+
action: ActionMeta;
|
|
581
|
+
visibleWhen?: ConditionMeta;
|
|
582
|
+
disabledWhen?: ConditionMeta;
|
|
583
|
+
tooltip?: string;
|
|
584
|
+
/** Show as dropdown menu */
|
|
585
|
+
children?: PageHeaderActionMeta[];
|
|
586
|
+
}
|
|
587
|
+
interface CardMeta {
|
|
588
|
+
title?: string;
|
|
589
|
+
content?: string;
|
|
590
|
+
template?: string;
|
|
591
|
+
actions?: PageHeaderActionMeta[];
|
|
592
|
+
variant?: 'default' | 'glass' | 'outlined' | 'elevated' | 'gradient' | string;
|
|
593
|
+
/** Card header icon */
|
|
594
|
+
icon?: string;
|
|
595
|
+
/** Image at top of card */
|
|
596
|
+
image?: string;
|
|
597
|
+
/** Footer content */
|
|
598
|
+
footer?: string;
|
|
599
|
+
/** Click action on the card */
|
|
600
|
+
onClick?: ActionMeta;
|
|
601
|
+
/** Nested sections inside the card */
|
|
602
|
+
sections?: SectionMeta[];
|
|
603
|
+
[key: string]: any;
|
|
604
|
+
}
|
|
605
|
+
interface StatsGridMeta {
|
|
606
|
+
stats: StatCardMeta[];
|
|
607
|
+
columns?: number;
|
|
608
|
+
variant?: 'default' | 'glass' | 'compact' | 'outlined' | 'elevated' | string;
|
|
609
|
+
[key: string]: any;
|
|
610
|
+
}
|
|
611
|
+
interface StatCardMeta {
|
|
612
|
+
label: string;
|
|
613
|
+
value: string;
|
|
614
|
+
trend?: string;
|
|
615
|
+
trendPositive?: boolean;
|
|
616
|
+
icon?: string;
|
|
617
|
+
color?: string;
|
|
618
|
+
bgColor?: string;
|
|
619
|
+
glowColor?: string;
|
|
620
|
+
action?: ActionMeta;
|
|
621
|
+
/** Sparkline data points */
|
|
622
|
+
sparkline?: number[];
|
|
623
|
+
/** Suffix text (e.g., '%', 'users') */
|
|
624
|
+
suffix?: string;
|
|
625
|
+
/** Prefix text (e.g., '$') */
|
|
626
|
+
prefix?: string;
|
|
627
|
+
/** Load value from API endpoint */
|
|
628
|
+
apiEndpoint?: string;
|
|
629
|
+
[key: string]: any;
|
|
630
|
+
}
|
|
631
|
+
interface HtmlMeta {
|
|
632
|
+
html: string;
|
|
633
|
+
/** Sanitize HTML (default: true) */
|
|
634
|
+
sanitize?: boolean;
|
|
635
|
+
}
|
|
636
|
+
interface CustomComponentMeta {
|
|
637
|
+
componentKey: string;
|
|
638
|
+
inputs?: Record<string, any>;
|
|
639
|
+
outputs?: Record<string, ActionMeta>;
|
|
640
|
+
[key: string]: any;
|
|
641
|
+
}
|
|
642
|
+
interface TabsMeta {
|
|
643
|
+
tabs: TabMeta[];
|
|
644
|
+
variant?: 'default' | 'pills' | 'underline' | 'vertical' | string;
|
|
645
|
+
defaultTab?: number;
|
|
646
|
+
/** Lazy load tab content */
|
|
647
|
+
lazy?: boolean;
|
|
648
|
+
/** Action when tab changes */
|
|
649
|
+
onChange?: ActionMeta;
|
|
650
|
+
}
|
|
651
|
+
interface TabMeta {
|
|
652
|
+
label: string;
|
|
653
|
+
icon?: string;
|
|
654
|
+
badge?: string;
|
|
655
|
+
sections: SectionMeta[];
|
|
656
|
+
visibleWhen?: ConditionMeta;
|
|
657
|
+
disabled?: boolean;
|
|
658
|
+
}
|
|
659
|
+
interface AccordionMeta {
|
|
660
|
+
panels: AccordionPanelMeta[];
|
|
661
|
+
/** Allow multiple panels open */
|
|
662
|
+
multi?: boolean;
|
|
663
|
+
variant?: 'default' | 'bordered' | 'flush' | string;
|
|
664
|
+
}
|
|
665
|
+
interface AccordionPanelMeta {
|
|
666
|
+
title: string;
|
|
667
|
+
icon?: string;
|
|
668
|
+
sections: SectionMeta[];
|
|
669
|
+
expanded?: boolean;
|
|
670
|
+
visibleWhen?: ConditionMeta;
|
|
671
|
+
disabled?: boolean;
|
|
672
|
+
}
|
|
673
|
+
interface TimelineMeta {
|
|
674
|
+
items: TimelineItemMeta[];
|
|
675
|
+
variant?: 'default' | 'alternating' | 'compact' | string;
|
|
676
|
+
/** Load items from API */
|
|
677
|
+
apiEndpoint?: string;
|
|
678
|
+
}
|
|
679
|
+
interface TimelineItemMeta {
|
|
680
|
+
title: string;
|
|
681
|
+
description?: string;
|
|
682
|
+
date?: string;
|
|
683
|
+
icon?: string;
|
|
684
|
+
color?: string;
|
|
685
|
+
action?: ActionMeta;
|
|
686
|
+
[key: string]: any;
|
|
687
|
+
}
|
|
688
|
+
interface AlertMeta {
|
|
689
|
+
type: 'info' | 'success' | 'warning' | 'error';
|
|
690
|
+
title?: string;
|
|
691
|
+
message: string;
|
|
692
|
+
dismissible?: boolean;
|
|
693
|
+
icon?: string;
|
|
694
|
+
action?: ActionMeta;
|
|
695
|
+
actionLabel?: string;
|
|
696
|
+
}
|
|
697
|
+
interface EmptyStateMeta {
|
|
698
|
+
icon?: string;
|
|
699
|
+
title: string;
|
|
700
|
+
description?: string;
|
|
701
|
+
action?: ActionMeta;
|
|
702
|
+
actionLabel?: string;
|
|
703
|
+
image?: string;
|
|
704
|
+
}
|
|
705
|
+
interface IframeMeta {
|
|
706
|
+
src: string;
|
|
707
|
+
height?: string;
|
|
708
|
+
width?: string;
|
|
709
|
+
allowFullscreen?: boolean;
|
|
710
|
+
sandbox?: string;
|
|
711
|
+
title?: string;
|
|
712
|
+
}
|
|
713
|
+
interface DividerMeta {
|
|
714
|
+
label?: string;
|
|
715
|
+
variant?: 'solid' | 'dashed' | 'dotted';
|
|
716
|
+
color?: string;
|
|
717
|
+
spacing?: string;
|
|
718
|
+
}
|
|
719
|
+
interface SpacerMeta {
|
|
720
|
+
height?: string;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* AvoraMetaForge — Action Metadata
|
|
725
|
+
*
|
|
726
|
+
* Comprehensive action system supporting 25+ action types covering:
|
|
727
|
+
* - Navigation, API calls, UI state, modals/drawers
|
|
728
|
+
* - Form manipulation, table control, clipboard, downloads
|
|
729
|
+
* - State management, storage, conditional branching, scripting
|
|
730
|
+
* - Parallel dispatch, delay, logging, context transforms
|
|
731
|
+
*/
|
|
732
|
+
/** HTTP methods — all standard methods supported */
|
|
733
|
+
type HttpMethod$1 = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
734
|
+
/** All built-in action types */
|
|
735
|
+
type ActionType = 'navigate' | 'api' | 'notify' | 'emit' | 'confirm' | 'open-modal' | 'close-modal' | 'open-drawer' | 'close-drawer' | 'set-state' | 'clear-state' | 'reset-form' | 'patch-form' | 'submit-form' | 'reload-table' | 'scroll-to' | 'set-loading' | 'clear-loading' | 'download-file' | 'copy-to-clipboard' | 'open-url' | 'set-storage' | 'remove-storage' | 'dispatch-multiple' | 'delay' | 'conditional' | 'for-each' | 'transform-context' | 'log' | 'print' | 'focus' | 'blur' | 'toggle-class' | 'set-title' | 'go-back' | 'go-forward' | 'reload-page' | 'store-data' | 'custom';
|
|
736
|
+
/**
|
|
737
|
+
* Represents a declarative action that the framework can execute.
|
|
738
|
+
* Actions are chainable via `then` and `onError`, and can fan-out via `dispatch-multiple`.
|
|
739
|
+
*/
|
|
740
|
+
interface ActionMeta {
|
|
741
|
+
/** The action type — built-in or custom string */
|
|
742
|
+
type: ActionType | string;
|
|
743
|
+
/** Configuration object — shape depends on `type` */
|
|
744
|
+
config: NavigateActionConfig | ApiActionConfig | NotifyActionConfig | EmitActionConfig | ConfirmActionConfig | ModalActionConfig | DrawerActionConfig | SetStateActionConfig | ClearStateActionConfig | ResetFormActionConfig | PatchFormActionConfig | SubmitFormActionConfig | ReloadTableActionConfig | ScrollToActionConfig | LoadingActionConfig | DownloadFileActionConfig | CopyToClipboardActionConfig | OpenUrlActionConfig | StorageActionConfig | DispatchMultipleActionConfig | DelayActionConfig | ConditionalActionConfig | ForEachActionConfig | TransformContextActionConfig | LogActionConfig | PrintActionConfig | FocusActionConfig | ToggleClassActionConfig | SetTitleActionConfig | Record<string, any>;
|
|
745
|
+
/** Action to execute after this one succeeds */
|
|
746
|
+
then?: ActionMeta;
|
|
747
|
+
/** Action to execute if this one fails */
|
|
748
|
+
onError?: ActionMeta;
|
|
749
|
+
/** Human-readable description for devtools / debugging */
|
|
750
|
+
description?: string;
|
|
751
|
+
/** Catch-all for future / plugin-specific properties */
|
|
752
|
+
[key: string]: any;
|
|
753
|
+
}
|
|
754
|
+
interface NavigateActionConfig {
|
|
755
|
+
path: string;
|
|
756
|
+
params?: Record<string, string>;
|
|
757
|
+
queryParams?: Record<string, string>;
|
|
758
|
+
replaceUrl?: boolean;
|
|
759
|
+
fragment?: string;
|
|
760
|
+
relativeTo?: boolean;
|
|
761
|
+
skipLocationChange?: boolean;
|
|
762
|
+
/** Pass state data via navigation extras */
|
|
763
|
+
state?: Record<string, any>;
|
|
764
|
+
}
|
|
765
|
+
interface ApiActionConfig {
|
|
766
|
+
/** Reference to registered endpoint by ID */
|
|
767
|
+
endpointId?: string;
|
|
768
|
+
/** Inline URL (alternative to endpointId) */
|
|
769
|
+
url?: string;
|
|
770
|
+
method?: HttpMethod$1;
|
|
771
|
+
body?: Record<string, any> | string | 'formValue';
|
|
772
|
+
headers?: Record<string, string>;
|
|
773
|
+
queryParams?: Record<string, string>;
|
|
774
|
+
pathParams?: Record<string, string>;
|
|
775
|
+
/** Response type control */
|
|
776
|
+
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
|
|
777
|
+
/** Store response in context under this key */
|
|
778
|
+
storeResultAs?: string;
|
|
779
|
+
/** Store response in MetaStateService under this key */
|
|
780
|
+
storeInState?: string;
|
|
781
|
+
/** Map status codes to error actions */
|
|
782
|
+
errorMap?: Record<number, ActionMeta>;
|
|
783
|
+
/** Use mock data instead of live call */
|
|
784
|
+
mock?: boolean;
|
|
785
|
+
mockData?: any;
|
|
786
|
+
}
|
|
787
|
+
interface NotifyActionConfig {
|
|
788
|
+
type: 'success' | 'error' | 'warning' | 'info';
|
|
789
|
+
message: string;
|
|
790
|
+
title?: string;
|
|
791
|
+
duration?: number;
|
|
792
|
+
dismissible?: boolean;
|
|
793
|
+
/** Action to run when notification is clicked */
|
|
794
|
+
onClick?: ActionMeta;
|
|
795
|
+
}
|
|
796
|
+
interface EmitActionConfig {
|
|
797
|
+
event: string;
|
|
798
|
+
payload?: any;
|
|
799
|
+
/** Whether to include current context as payload automatically */
|
|
800
|
+
includeContext?: boolean;
|
|
801
|
+
}
|
|
802
|
+
interface ConfirmActionConfig {
|
|
803
|
+
title?: string;
|
|
804
|
+
message: string;
|
|
805
|
+
confirmLabel?: string;
|
|
806
|
+
cancelLabel?: string;
|
|
807
|
+
variant?: 'info' | 'warning' | 'danger';
|
|
808
|
+
onConfirm: ActionMeta;
|
|
809
|
+
onCancel?: ActionMeta;
|
|
810
|
+
}
|
|
811
|
+
interface ModalActionConfig {
|
|
812
|
+
modalId?: string;
|
|
813
|
+
title?: string;
|
|
814
|
+
/** Section to render inside the modal */
|
|
815
|
+
section?: SectionMeta;
|
|
816
|
+
/** Custom component key to render */
|
|
817
|
+
componentKey?: string;
|
|
818
|
+
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
819
|
+
closable?: boolean;
|
|
820
|
+
data?: Record<string, any>;
|
|
821
|
+
onClose?: ActionMeta;
|
|
822
|
+
}
|
|
823
|
+
interface DrawerActionConfig {
|
|
824
|
+
drawerId?: string;
|
|
825
|
+
title?: string;
|
|
826
|
+
section?: SectionMeta;
|
|
827
|
+
componentKey?: string;
|
|
828
|
+
position?: 'left' | 'right';
|
|
829
|
+
width?: string;
|
|
830
|
+
closable?: boolean;
|
|
831
|
+
data?: Record<string, any>;
|
|
832
|
+
onClose?: ActionMeta;
|
|
833
|
+
}
|
|
834
|
+
interface SetStateActionConfig {
|
|
835
|
+
key: string;
|
|
836
|
+
/** Value to set — can be literal or 'fromContext:path.to.value' */
|
|
837
|
+
value: any;
|
|
838
|
+
/** Merge with existing value (for objects) instead of replacing */
|
|
839
|
+
merge?: boolean;
|
|
840
|
+
/** Persist to localStorage */
|
|
841
|
+
persist?: boolean;
|
|
842
|
+
}
|
|
843
|
+
interface ClearStateActionConfig {
|
|
844
|
+
key: string;
|
|
845
|
+
/** Clear from persistence too */
|
|
846
|
+
clearPersisted?: boolean;
|
|
847
|
+
}
|
|
848
|
+
interface ResetFormActionConfig {
|
|
849
|
+
/** ID of the form to reset — matches SectionMeta id or form container */
|
|
850
|
+
formId?: string;
|
|
851
|
+
/** Reset to initial values instead of empty */
|
|
852
|
+
toInitialValues?: boolean;
|
|
853
|
+
}
|
|
854
|
+
interface PatchFormActionConfig {
|
|
855
|
+
formId?: string;
|
|
856
|
+
/** Key-value pairs to patch into the form */
|
|
857
|
+
values: Record<string, any>;
|
|
858
|
+
/** If true, values come from state store keys */
|
|
859
|
+
fromState?: boolean;
|
|
860
|
+
}
|
|
861
|
+
interface SubmitFormActionConfig {
|
|
862
|
+
formId?: string;
|
|
863
|
+
/** Force submit even if invalid */
|
|
864
|
+
force?: boolean;
|
|
865
|
+
}
|
|
866
|
+
interface ReloadTableActionConfig {
|
|
867
|
+
tableId?: string;
|
|
868
|
+
/** Reset page to 1 on reload */
|
|
869
|
+
resetPage?: boolean;
|
|
870
|
+
/** Clear search/filter on reload */
|
|
871
|
+
clearFilters?: boolean;
|
|
872
|
+
}
|
|
873
|
+
interface ScrollToActionConfig {
|
|
874
|
+
/** CSS selector or element ID */
|
|
875
|
+
target?: string;
|
|
876
|
+
/** Pixel offset from top */
|
|
877
|
+
top?: number;
|
|
878
|
+
behavior?: 'smooth' | 'instant' | 'auto';
|
|
879
|
+
block?: 'start' | 'center' | 'end' | 'nearest';
|
|
880
|
+
}
|
|
881
|
+
interface LoadingActionConfig {
|
|
882
|
+
/** Loading key (allows multiple concurrent loaders) */
|
|
883
|
+
key?: string;
|
|
884
|
+
message?: string;
|
|
885
|
+
}
|
|
886
|
+
interface FocusActionConfig {
|
|
887
|
+
/** CSS selector or element ID */
|
|
888
|
+
target: string;
|
|
889
|
+
}
|
|
890
|
+
interface ToggleClassActionConfig {
|
|
891
|
+
/** CSS selector or element ID */
|
|
892
|
+
target: string;
|
|
893
|
+
className: string;
|
|
894
|
+
action: 'add' | 'remove' | 'toggle';
|
|
895
|
+
}
|
|
896
|
+
interface SetTitleActionConfig {
|
|
897
|
+
title: string;
|
|
898
|
+
}
|
|
899
|
+
interface DownloadFileActionConfig {
|
|
900
|
+
/** URL to download from */
|
|
901
|
+
url?: string;
|
|
902
|
+
/** Endpoint ID to call (returns blob) */
|
|
903
|
+
endpointId?: string;
|
|
904
|
+
/** Filename for the downloaded file */
|
|
905
|
+
filename?: string;
|
|
906
|
+
/** MIME type hint */
|
|
907
|
+
mimeType?: string;
|
|
908
|
+
/** Content to download as string (for generated files) */
|
|
909
|
+
content?: string;
|
|
910
|
+
}
|
|
911
|
+
interface CopyToClipboardActionConfig {
|
|
912
|
+
/** Literal text, or 'fromContext:path.to.value' to extract from context */
|
|
913
|
+
text: string;
|
|
914
|
+
/** Notification on success */
|
|
915
|
+
successMessage?: string;
|
|
916
|
+
}
|
|
917
|
+
interface OpenUrlActionConfig {
|
|
918
|
+
url: string;
|
|
919
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
920
|
+
features?: string;
|
|
921
|
+
}
|
|
922
|
+
interface StorageActionConfig {
|
|
923
|
+
storage: 'local' | 'session';
|
|
924
|
+
key: string;
|
|
925
|
+
/** Value to store. 'fromContext:path' to extract from context */
|
|
926
|
+
value?: any;
|
|
927
|
+
}
|
|
928
|
+
interface DispatchMultipleActionConfig {
|
|
929
|
+
actions: ActionMeta[];
|
|
930
|
+
/** Run in parallel or sequentially */
|
|
931
|
+
mode?: 'parallel' | 'sequential';
|
|
932
|
+
/** Stop on first error (sequential mode only) */
|
|
933
|
+
stopOnError?: boolean;
|
|
934
|
+
}
|
|
935
|
+
interface DelayActionConfig {
|
|
936
|
+
/** Delay in milliseconds */
|
|
937
|
+
duration: number;
|
|
938
|
+
}
|
|
939
|
+
interface ConditionalActionConfig {
|
|
940
|
+
condition: ConditionMeta;
|
|
941
|
+
onTrue: ActionMeta;
|
|
942
|
+
onFalse?: ActionMeta;
|
|
943
|
+
}
|
|
944
|
+
interface ForEachActionConfig {
|
|
945
|
+
/** Path in context to the array to iterate */
|
|
946
|
+
items: string;
|
|
947
|
+
/** Action to dispatch per item. Item is available as context.item */
|
|
948
|
+
action: ActionMeta;
|
|
949
|
+
/** Run in parallel or sequentially */
|
|
950
|
+
mode?: 'parallel' | 'sequential';
|
|
951
|
+
}
|
|
952
|
+
interface TransformContextActionConfig {
|
|
953
|
+
/** Map of new context keys to source paths */
|
|
954
|
+
map: Record<string, string>;
|
|
955
|
+
/** If true, merge with existing context. If false, replace */
|
|
956
|
+
merge?: boolean;
|
|
957
|
+
}
|
|
958
|
+
interface LogActionConfig {
|
|
959
|
+
level?: 'log' | 'info' | 'warn' | 'error' | 'debug';
|
|
960
|
+
message?: string;
|
|
961
|
+
/** Log the full context */
|
|
962
|
+
logContext?: boolean;
|
|
963
|
+
/** Specific path in context to log */
|
|
964
|
+
path?: string;
|
|
965
|
+
}
|
|
966
|
+
interface PrintActionConfig {
|
|
967
|
+
/** CSS selector to print. If omitted, prints whole page */
|
|
968
|
+
target?: string;
|
|
969
|
+
title?: string;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* AvoraMetaForge — Guard & Resolver Metadata
|
|
974
|
+
*
|
|
975
|
+
* Extended with:
|
|
976
|
+
* - canDeactivate support
|
|
977
|
+
* - Token refresh hints
|
|
978
|
+
* - Per-endpoint auth override
|
|
979
|
+
* - Permission-based guards
|
|
980
|
+
* - IP/geo restrictions
|
|
981
|
+
* - Time-based access
|
|
982
|
+
*/
|
|
983
|
+
|
|
984
|
+
interface GuardMeta {
|
|
985
|
+
/** Require authentication */
|
|
986
|
+
requireAuth?: boolean;
|
|
987
|
+
/** Required roles (user must have at least one) */
|
|
988
|
+
roles?: string[];
|
|
989
|
+
/** Required permissions (user must have ALL) */
|
|
990
|
+
permissions?: string[];
|
|
991
|
+
/** Redirect path when guard fails */
|
|
992
|
+
redirectTo?: string;
|
|
993
|
+
/** Custom guard function key */
|
|
994
|
+
custom?: string;
|
|
995
|
+
/** Condition-based guard */
|
|
996
|
+
condition?: ConditionMeta;
|
|
997
|
+
/** Action to dispatch on guard failure (alternative to redirect) */
|
|
998
|
+
onFail?: ActionMeta;
|
|
999
|
+
/** Show a notification on guard failure */
|
|
1000
|
+
failMessage?: string;
|
|
1001
|
+
/** Can deactivate guard (show unsaved changes warning) */
|
|
1002
|
+
canDeactivate?: boolean;
|
|
1003
|
+
/** Custom deactivation message */
|
|
1004
|
+
deactivateMessage?: string;
|
|
1005
|
+
/** Feature flag key — page accessible only if flag is on */
|
|
1006
|
+
featureFlag?: string;
|
|
1007
|
+
/** Time-based access window */
|
|
1008
|
+
accessWindow?: {
|
|
1009
|
+
from?: string;
|
|
1010
|
+
to?: string;
|
|
1011
|
+
timezone?: string;
|
|
1012
|
+
};
|
|
1013
|
+
/** Catch-all */
|
|
1014
|
+
[key: string]: any;
|
|
1015
|
+
}
|
|
1016
|
+
interface ResolverMeta {
|
|
1017
|
+
/** Data source */
|
|
1018
|
+
source: 'api' | 'static' | 'state' | 'custom';
|
|
1019
|
+
/** API endpoint ID to resolve from */
|
|
1020
|
+
endpointId?: string;
|
|
1021
|
+
/** Direct URL (alternative to endpointId) */
|
|
1022
|
+
url?: string;
|
|
1023
|
+
/** Params to pass (supports :param references from route) */
|
|
1024
|
+
params?: Record<string, string>;
|
|
1025
|
+
/** Static data to resolve */
|
|
1026
|
+
staticData?: any;
|
|
1027
|
+
/** State key to read from MetaStateService */
|
|
1028
|
+
stateKey?: string;
|
|
1029
|
+
/** Custom resolver function key */
|
|
1030
|
+
custom?: string;
|
|
1031
|
+
/** Transform the resolved data */
|
|
1032
|
+
transform?: {
|
|
1033
|
+
root?: string;
|
|
1034
|
+
map?: Record<string, string>;
|
|
1035
|
+
};
|
|
1036
|
+
/** Key to store resolved data under in route data */
|
|
1037
|
+
key?: string;
|
|
1038
|
+
/** Show loading indicator while resolving */
|
|
1039
|
+
showLoading?: boolean;
|
|
1040
|
+
/** Action on resolve failure */
|
|
1041
|
+
onError?: ActionMeta;
|
|
1042
|
+
/** Catch-all */
|
|
1043
|
+
[key: string]: any;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* AvoraMetaForge — API Metadata
|
|
1048
|
+
*
|
|
1049
|
+
* Comprehensive API endpoint configuration supporting:
|
|
1050
|
+
* - All HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
|
|
1051
|
+
* - Auth strategies (Bearer, Basic, API Key, custom)
|
|
1052
|
+
* - Response transforms, caching, retry with exponential backoff
|
|
1053
|
+
* - Mock mode for development/testing without a backend
|
|
1054
|
+
* - Timeout, abort, response type control
|
|
1055
|
+
* - Status code → action error mapping
|
|
1056
|
+
* - Environment-based base URL overrides
|
|
1057
|
+
* - File upload (multipart/form-data) support
|
|
1058
|
+
* - Pagination hints for server-side pagination
|
|
1059
|
+
*/
|
|
1060
|
+
|
|
1061
|
+
interface ApiEndpointMeta {
|
|
1062
|
+
/** Unique identifier for this endpoint */
|
|
1063
|
+
id: string;
|
|
1064
|
+
/** Base URL (e.g., 'https://api.example.com'). Can be overridden by environment config */
|
|
1065
|
+
baseUrl?: string;
|
|
1066
|
+
/** Path template (e.g., '/users/:id/posts'). Supports :param placeholders */
|
|
1067
|
+
path: string;
|
|
1068
|
+
/** HTTP method */
|
|
1069
|
+
method: HttpMethod$1;
|
|
1070
|
+
/** Static headers merged with default headers */
|
|
1071
|
+
headers?: Record<string, string>;
|
|
1072
|
+
/** Static path/query params merged with dynamic params */
|
|
1073
|
+
params?: Record<string, string>;
|
|
1074
|
+
/** Static request body — can be overridden dynamically */
|
|
1075
|
+
body?: Record<string, any> | string;
|
|
1076
|
+
/** Response transform pipeline */
|
|
1077
|
+
transform?: TransformMeta;
|
|
1078
|
+
/** Response caching configuration */
|
|
1079
|
+
cache?: CacheMeta;
|
|
1080
|
+
/** Retry configuration */
|
|
1081
|
+
retry?: RetryMeta;
|
|
1082
|
+
/** Custom error handler key */
|
|
1083
|
+
errorHandler?: string;
|
|
1084
|
+
/** Authentication strategy for this endpoint */
|
|
1085
|
+
auth?: ApiAuthMeta;
|
|
1086
|
+
/** Timeout in milliseconds. 0 = no timeout */
|
|
1087
|
+
timeout?: number;
|
|
1088
|
+
/** Content type override. Default: 'application/json' */
|
|
1089
|
+
contentType?: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded' | 'text/plain' | string;
|
|
1090
|
+
/** Expected response type */
|
|
1091
|
+
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
|
|
1092
|
+
/** If true, show loading indicator during this call */
|
|
1093
|
+
showLoading?: boolean;
|
|
1094
|
+
/** Loading message to display */
|
|
1095
|
+
loadingMessage?: string;
|
|
1096
|
+
/** Map HTTP status codes to specific actions */
|
|
1097
|
+
errorMap?: Record<number, ActionMeta>;
|
|
1098
|
+
/** Default error notification message */
|
|
1099
|
+
errorMessage?: string;
|
|
1100
|
+
/** Suppress automatic error notifications */
|
|
1101
|
+
silentErrors?: boolean;
|
|
1102
|
+
/** If true, return mockData without making a real HTTP call */
|
|
1103
|
+
mock?: boolean;
|
|
1104
|
+
/** Static data to return in mock mode */
|
|
1105
|
+
mockData?: any;
|
|
1106
|
+
/** Simulated delay (ms) in mock mode */
|
|
1107
|
+
mockDelay?: number;
|
|
1108
|
+
/** Simulated error in mock mode */
|
|
1109
|
+
mockError?: {
|
|
1110
|
+
status: number;
|
|
1111
|
+
message: string;
|
|
1112
|
+
};
|
|
1113
|
+
/** Pagination configuration for server-side pagination */
|
|
1114
|
+
pagination?: ApiPaginationMeta;
|
|
1115
|
+
/** Environment key to resolve baseUrl from config (e.g., 'production', 'staging') */
|
|
1116
|
+
environment?: string;
|
|
1117
|
+
/** Catch-all for future / plugin-specific properties */
|
|
1118
|
+
[key: string]: any;
|
|
1119
|
+
}
|
|
1120
|
+
interface ApiAuthMeta {
|
|
1121
|
+
/** Auth strategy */
|
|
1122
|
+
type: 'bearer' | 'basic' | 'apiKey' | 'custom' | 'none';
|
|
1123
|
+
/** For bearer: the token string or state key (e.g., 'state:auth.token') */
|
|
1124
|
+
token?: string;
|
|
1125
|
+
/** For basic: username */
|
|
1126
|
+
username?: string;
|
|
1127
|
+
/** For basic: password */
|
|
1128
|
+
password?: string;
|
|
1129
|
+
/** For apiKey: header name (e.g., 'X-API-Key') */
|
|
1130
|
+
headerName?: string;
|
|
1131
|
+
/** For apiKey: the key value or state key */
|
|
1132
|
+
apiKey?: string;
|
|
1133
|
+
/** For custom: header name and value */
|
|
1134
|
+
customHeader?: {
|
|
1135
|
+
name: string;
|
|
1136
|
+
value: string;
|
|
1137
|
+
};
|
|
1138
|
+
/** Whether to skip auth for this specific endpoint (override global) */
|
|
1139
|
+
skip?: boolean;
|
|
1140
|
+
}
|
|
1141
|
+
interface TransformMeta {
|
|
1142
|
+
/** Dot-notation path to unwrap (e.g., 'data.results') */
|
|
1143
|
+
root?: string;
|
|
1144
|
+
/** Map response keys (target ← source). Applied per item if array */
|
|
1145
|
+
map?: Record<string, string>;
|
|
1146
|
+
/** Custom transform function key */
|
|
1147
|
+
custom?: string;
|
|
1148
|
+
/** Flatten nested objects */
|
|
1149
|
+
flatten?: boolean;
|
|
1150
|
+
/** Pick only these keys from the response */
|
|
1151
|
+
pick?: string[];
|
|
1152
|
+
/** Omit these keys from the response */
|
|
1153
|
+
omit?: string[];
|
|
1154
|
+
/** Sort the response array */
|
|
1155
|
+
sort?: {
|
|
1156
|
+
key: string;
|
|
1157
|
+
direction?: 'asc' | 'desc';
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
interface CacheMeta {
|
|
1161
|
+
/** Enable caching for this endpoint */
|
|
1162
|
+
enabled: boolean;
|
|
1163
|
+
/** Time-to-live in milliseconds */
|
|
1164
|
+
ttl?: number;
|
|
1165
|
+
/** Custom cache key. If omitted, auto-generated from URL + params */
|
|
1166
|
+
key?: string;
|
|
1167
|
+
/** Cache storage: memory (default), sessionStorage, localStorage */
|
|
1168
|
+
storage?: 'memory' | 'session' | 'local';
|
|
1169
|
+
/** If true, return stale data while revalidating (SWR pattern) */
|
|
1170
|
+
staleWhileRevalidate?: boolean;
|
|
1171
|
+
/** Invalidate cache when these endpoint IDs are called successfully */
|
|
1172
|
+
invalidateOn?: string[];
|
|
1173
|
+
}
|
|
1174
|
+
interface RetryMeta {
|
|
1175
|
+
/** Maximum number of retry attempts */
|
|
1176
|
+
maxRetries: number;
|
|
1177
|
+
/** Initial delay between retries (ms) */
|
|
1178
|
+
delay?: number;
|
|
1179
|
+
/** Use exponential backoff */
|
|
1180
|
+
exponential?: boolean;
|
|
1181
|
+
/** Only retry on these HTTP status codes */
|
|
1182
|
+
retryOn?: number[];
|
|
1183
|
+
/** Do NOT retry on these status codes */
|
|
1184
|
+
skipOn?: number[];
|
|
1185
|
+
/** Maximum total delay cap (ms) */
|
|
1186
|
+
maxDelay?: number;
|
|
1187
|
+
}
|
|
1188
|
+
interface ApiPaginationMeta {
|
|
1189
|
+
/** Query param name for page number */
|
|
1190
|
+
pageParam?: string;
|
|
1191
|
+
/** Query param name for page size */
|
|
1192
|
+
sizeParam?: string;
|
|
1193
|
+
/** Query param name for sort field */
|
|
1194
|
+
sortParam?: string;
|
|
1195
|
+
/** Query param name for sort direction */
|
|
1196
|
+
directionParam?: string;
|
|
1197
|
+
/** Query param name for search term */
|
|
1198
|
+
searchParam?: string;
|
|
1199
|
+
/** Path in response to the data array */
|
|
1200
|
+
dataPath?: string;
|
|
1201
|
+
/** Path in response to total count */
|
|
1202
|
+
totalPath?: string;
|
|
1203
|
+
/** Path in response to total pages */
|
|
1204
|
+
totalPagesPath?: string;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* AvoraMetaForge — Plugin Metadata
|
|
1209
|
+
*
|
|
1210
|
+
* Extended plugin system with lifecycle hooks, interceptors,
|
|
1211
|
+
* custom transforms, and more extension points.
|
|
1212
|
+
*/
|
|
1213
|
+
|
|
1214
|
+
interface AvoraMetaForgePlugin {
|
|
1215
|
+
/** Unique plugin name */
|
|
1216
|
+
name: string;
|
|
1217
|
+
/** Plugin version */
|
|
1218
|
+
version?: string;
|
|
1219
|
+
/** Plugin description */
|
|
1220
|
+
description?: string;
|
|
1221
|
+
/** Custom section components (rendered by MetaRendererComponent) */
|
|
1222
|
+
components?: Record<string, Type<any>>;
|
|
1223
|
+
/** Custom validator functions */
|
|
1224
|
+
validators?: Record<string, (...args: any[]) => any>;
|
|
1225
|
+
/** Custom guard functions */
|
|
1226
|
+
guards?: Record<string, (...args: any[]) => any>;
|
|
1227
|
+
/** Custom field type components */
|
|
1228
|
+
fieldTypes?: Record<string, Type<any>>;
|
|
1229
|
+
/** Custom cell type components */
|
|
1230
|
+
cellTypes?: Record<string, Type<any>>;
|
|
1231
|
+
/** Custom condition evaluators */
|
|
1232
|
+
conditions?: Record<string, (context: any, condition: any) => boolean>;
|
|
1233
|
+
/** Custom action handlers */
|
|
1234
|
+
actions?: Record<string, (config: any, context: any) => any>;
|
|
1235
|
+
/** Custom response transforms */
|
|
1236
|
+
transforms?: Record<string, (data: any, config: any) => any>;
|
|
1237
|
+
/** Custom resolver functions */
|
|
1238
|
+
resolvers?: Record<string, (params: any) => Promise<any>>;
|
|
1239
|
+
/** Custom formatters (for table cells, display values) */
|
|
1240
|
+
formatters?: Record<string, (value: any, options?: any) => string>;
|
|
1241
|
+
/** Custom pipes */
|
|
1242
|
+
pipes?: Record<string, (value: any, ...args: any[]) => any>;
|
|
1243
|
+
/** API interceptors */
|
|
1244
|
+
interceptors?: {
|
|
1245
|
+
request?: (config: any) => any;
|
|
1246
|
+
response?: (response: any) => any;
|
|
1247
|
+
error?: (error: any) => any;
|
|
1248
|
+
};
|
|
1249
|
+
/** Action middleware — runs before every action dispatch */
|
|
1250
|
+
actionMiddleware?: (action: ActionMeta, context: any) => ActionMeta | null;
|
|
1251
|
+
/** Called when plugin is registered */
|
|
1252
|
+
initialize?: () => void;
|
|
1253
|
+
/** Called when plugin is destroyed */
|
|
1254
|
+
destroy?: () => void;
|
|
1255
|
+
/** Called after all plugins are registered */
|
|
1256
|
+
afterInit?: () => void;
|
|
1257
|
+
/** Catch-all */
|
|
1258
|
+
[key: string]: any;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
/**
|
|
1262
|
+
* AvoraMetaForge — Page Metadata
|
|
1263
|
+
*
|
|
1264
|
+
* Comprehensive page configuration supporting:
|
|
1265
|
+
* - Lifecycle hooks: onInit, onDestroy, onParamChange, onQueryChange
|
|
1266
|
+
* - Breadcrumbs with dynamic segments
|
|
1267
|
+
* - Deactivation guards (unsaved changes warning)
|
|
1268
|
+
* - SEO meta tags
|
|
1269
|
+
* - Page-level animations and transitions
|
|
1270
|
+
* - Deep link support with route param context
|
|
1271
|
+
*/
|
|
1272
|
+
|
|
1273
|
+
interface PageMeta {
|
|
1274
|
+
id: string;
|
|
1275
|
+
path: string;
|
|
1276
|
+
title?: string;
|
|
1277
|
+
layout?: LayoutTypeKey | string;
|
|
1278
|
+
layoutConfig?: LayoutConfigMeta;
|
|
1279
|
+
icon?: string;
|
|
1280
|
+
guard?: GuardMeta;
|
|
1281
|
+
resolve?: Record<string, ResolverMeta>;
|
|
1282
|
+
sections: SectionMeta[];
|
|
1283
|
+
data?: Record<string, any>;
|
|
1284
|
+
children?: PageMeta[];
|
|
1285
|
+
lazyModule?: () => Promise<any>;
|
|
1286
|
+
showInNav?: boolean;
|
|
1287
|
+
navGroup?: string;
|
|
1288
|
+
navBadge?: string;
|
|
1289
|
+
navBadgeColor?: string;
|
|
1290
|
+
navOrder?: number;
|
|
1291
|
+
pathMatch?: 'full' | 'prefix';
|
|
1292
|
+
redirectTo?: string;
|
|
1293
|
+
cssClass?: string;
|
|
1294
|
+
customComponent?: () => Promise<any>;
|
|
1295
|
+
/** Action to dispatch when the page initializes (e.g., load data) */
|
|
1296
|
+
onInit?: ActionMeta;
|
|
1297
|
+
/** Action to dispatch when the page is destroyed (e.g., cleanup) */
|
|
1298
|
+
onDestroy?: ActionMeta;
|
|
1299
|
+
/** Action to dispatch when route params change (for reusable pages) */
|
|
1300
|
+
onParamChange?: ActionMeta;
|
|
1301
|
+
/** Action to dispatch when query params change */
|
|
1302
|
+
onQueryChange?: ActionMeta;
|
|
1303
|
+
/** Action to dispatch when the page becomes visible (tab focus) */
|
|
1304
|
+
onActivate?: ActionMeta;
|
|
1305
|
+
/** Action to dispatch when the page loses visibility (tab blur) */
|
|
1306
|
+
onDeactivate?: ActionMeta;
|
|
1307
|
+
/** Whether to warn when leaving with unsaved changes */
|
|
1308
|
+
canDeactivate?: boolean;
|
|
1309
|
+
/** Custom deactivation message */
|
|
1310
|
+
deactivateMessage?: string;
|
|
1311
|
+
/** Condition that must be true to allow deactivation without prompt */
|
|
1312
|
+
deactivateWhen?: ConditionMeta;
|
|
1313
|
+
/** Breadcrumb configuration. Auto-generated from route hierarchy if not specified */
|
|
1314
|
+
breadcrumbs?: BreadcrumbMeta[];
|
|
1315
|
+
/** Override parent breadcrumbs (don't inherit) */
|
|
1316
|
+
breadcrumbOverride?: boolean;
|
|
1317
|
+
/** Hide breadcrumbs on this page */
|
|
1318
|
+
hideBreadcrumbs?: boolean;
|
|
1319
|
+
/** Meta description for search engines */
|
|
1320
|
+
metaDescription?: string;
|
|
1321
|
+
/** Meta keywords */
|
|
1322
|
+
metaKeywords?: string[];
|
|
1323
|
+
/** Open Graph meta tags */
|
|
1324
|
+
og?: {
|
|
1325
|
+
title?: string;
|
|
1326
|
+
description?: string;
|
|
1327
|
+
image?: string;
|
|
1328
|
+
type?: string;
|
|
1329
|
+
};
|
|
1330
|
+
/** Page transition animation */
|
|
1331
|
+
animation?: 'fade' | 'slide-left' | 'slide-right' | 'slide-up' | 'zoom' | 'none' | string;
|
|
1332
|
+
/** Auto-refresh page data at this interval (ms) */
|
|
1333
|
+
refreshInterval?: number;
|
|
1334
|
+
/** Show loading skeleton while resolving data */
|
|
1335
|
+
showSkeleton?: boolean;
|
|
1336
|
+
/** Scroll to top on navigation */
|
|
1337
|
+
scrollToTop?: boolean;
|
|
1338
|
+
/** Page-level permissions (finer than guard) */
|
|
1339
|
+
permissions?: string[];
|
|
1340
|
+
/** Whether this page is a full-screen overlay */
|
|
1341
|
+
fullScreen?: boolean;
|
|
1342
|
+
/** Background color/gradient override */
|
|
1343
|
+
background?: string;
|
|
1344
|
+
/** Catch-all for future / plugin-specific properties */
|
|
1345
|
+
[key: string]: any;
|
|
1346
|
+
}
|
|
1347
|
+
interface BreadcrumbMeta {
|
|
1348
|
+
/** Display label. Supports template: '{{params.name}}' */
|
|
1349
|
+
label: string;
|
|
1350
|
+
/** Route path. If omitted, breadcrumb is not clickable */
|
|
1351
|
+
path?: string;
|
|
1352
|
+
/** Icon for the breadcrumb */
|
|
1353
|
+
icon?: string;
|
|
1354
|
+
/** Whether this is the active/current breadcrumb */
|
|
1355
|
+
active?: boolean;
|
|
1356
|
+
/** Action to dispatch on click (alternative to path) */
|
|
1357
|
+
action?: ActionMeta;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
type LayoutTypeKey = 'vertical' | 'horizontal' | 'empty' | 'centered' | 'two-column' | 'dashboard-grid' | 'compact' | 'sidebar-left' | 'sidebar-right' | 'split' | 'stacked' | 'masonry' | 'holy-grail';
|
|
1361
|
+
interface AppMeta {
|
|
1362
|
+
app: AppBrandingMeta;
|
|
1363
|
+
navigation: NavGroupMeta[];
|
|
1364
|
+
pages: PageMeta[];
|
|
1365
|
+
apis?: ApiEndpointMeta[];
|
|
1366
|
+
/** Environment-based base URL mapping */
|
|
1367
|
+
environments?: Record<string, EnvironmentConfig>;
|
|
1368
|
+
/** Current active environment */
|
|
1369
|
+
activeEnvironment?: string;
|
|
1370
|
+
/** Global default headers for all API calls */
|
|
1371
|
+
defaultHeaders?: Record<string, string>;
|
|
1372
|
+
/** Global auth configuration */
|
|
1373
|
+
auth?: GlobalAuthMeta;
|
|
1374
|
+
/** Enable devtools overlay */
|
|
1375
|
+
devtools?: boolean;
|
|
1376
|
+
/** Global loading indicator configuration */
|
|
1377
|
+
loading?: {
|
|
1378
|
+
type?: 'spinner' | 'bar' | 'skeleton';
|
|
1379
|
+
color?: string;
|
|
1380
|
+
delay?: number;
|
|
1381
|
+
};
|
|
1382
|
+
/** Global error handler action */
|
|
1383
|
+
onError?: ActionMeta;
|
|
1384
|
+
/** Plugin configurations */
|
|
1385
|
+
plugins?: AvoraMetaForgePlugin[];
|
|
1386
|
+
/** Catch-all */
|
|
1387
|
+
[key: string]: any;
|
|
1388
|
+
}
|
|
1389
|
+
interface EnvironmentConfig {
|
|
1390
|
+
/** Base URL for API calls */
|
|
1391
|
+
baseUrl: string;
|
|
1392
|
+
/** Debug mode */
|
|
1393
|
+
debug?: boolean;
|
|
1394
|
+
/** Force mock mode for all endpoints */
|
|
1395
|
+
mockAll?: boolean;
|
|
1396
|
+
/** Additional config */
|
|
1397
|
+
[key: string]: any;
|
|
1398
|
+
}
|
|
1399
|
+
interface GlobalAuthMeta {
|
|
1400
|
+
/** Auth provider type */
|
|
1401
|
+
type: 'jwt' | 'oauth2' | 'session' | 'apiKey' | 'custom';
|
|
1402
|
+
/** Login endpoint ID */
|
|
1403
|
+
loginEndpoint?: string;
|
|
1404
|
+
/** Token refresh endpoint ID */
|
|
1405
|
+
refreshEndpoint?: string;
|
|
1406
|
+
/** Logout endpoint ID */
|
|
1407
|
+
logoutEndpoint?: string;
|
|
1408
|
+
/** Token storage location */
|
|
1409
|
+
tokenStorage?: 'localStorage' | 'sessionStorage' | 'memory';
|
|
1410
|
+
/** Token key in storage */
|
|
1411
|
+
tokenKey?: string;
|
|
1412
|
+
/** Refresh token key in storage */
|
|
1413
|
+
refreshTokenKey?: string;
|
|
1414
|
+
/** Auto-refresh token before expiry */
|
|
1415
|
+
autoRefresh?: boolean;
|
|
1416
|
+
/** Login redirect path */
|
|
1417
|
+
loginRedirect?: string;
|
|
1418
|
+
/** After-login default path */
|
|
1419
|
+
afterLoginRedirect?: string;
|
|
1420
|
+
/** Header name for token (default: 'Authorization') */
|
|
1421
|
+
headerName?: string;
|
|
1422
|
+
/** Token prefix (default: 'Bearer ') */
|
|
1423
|
+
tokenPrefix?: string;
|
|
1424
|
+
/**
|
|
1425
|
+
* AvoraMetaForge Built-in Native Auth UI
|
|
1426
|
+
* Let the framework handle auth screens for you using the AmfAuthShell.
|
|
1427
|
+
*/
|
|
1428
|
+
builtInUI?: {
|
|
1429
|
+
enabled: boolean;
|
|
1430
|
+
/** Specific pages to enable. If omitted, all defaults are enabled. */
|
|
1431
|
+
pages?: ('login' | 'forgot-password' | 'contact-support')[];
|
|
1432
|
+
/** Custom brand name for auth pages. Fallbacks to app.name */
|
|
1433
|
+
brandName?: string;
|
|
1434
|
+
/** Custom tagline for auth pages */
|
|
1435
|
+
brandTagline?: string;
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
interface AppBrandingMeta {
|
|
1439
|
+
name: string;
|
|
1440
|
+
logo?: string;
|
|
1441
|
+
/** Logo for dark mode */
|
|
1442
|
+
logoDark?: string;
|
|
1443
|
+
/** Favicon URL */
|
|
1444
|
+
favicon?: string;
|
|
1445
|
+
defaultLayout?: LayoutTypeKey | string;
|
|
1446
|
+
defaultGuard?: GuardMeta;
|
|
1447
|
+
copyright?: string;
|
|
1448
|
+
footerLinks?: FooterLinkMeta[];
|
|
1449
|
+
/** Theme configuration */
|
|
1450
|
+
theme?: ThemeMeta;
|
|
1451
|
+
/** App version */
|
|
1452
|
+
version?: string;
|
|
1453
|
+
/** Support URL or email */
|
|
1454
|
+
support?: string;
|
|
1455
|
+
[key: string]: any;
|
|
1456
|
+
}
|
|
1457
|
+
interface ThemeMeta {
|
|
1458
|
+
/** Primary color (hex or HSL) */
|
|
1459
|
+
primary?: string;
|
|
1460
|
+
/** Accent color */
|
|
1461
|
+
accent?: string;
|
|
1462
|
+
/** Default mode */
|
|
1463
|
+
mode?: 'light' | 'dark' | 'auto';
|
|
1464
|
+
/** Custom CSS variables */
|
|
1465
|
+
variables?: Record<string, string>;
|
|
1466
|
+
/** Font family */
|
|
1467
|
+
fontFamily?: string;
|
|
1468
|
+
/** Border radius scale */
|
|
1469
|
+
borderRadius?: string;
|
|
1470
|
+
}
|
|
1471
|
+
interface LayoutMeta {
|
|
1472
|
+
type: LayoutTypeKey | string;
|
|
1473
|
+
config?: LayoutConfigMeta;
|
|
1474
|
+
}
|
|
1475
|
+
interface LayoutConfigMeta {
|
|
1476
|
+
maxWidth?: string;
|
|
1477
|
+
verticalCenter?: boolean;
|
|
1478
|
+
leftWidth?: string;
|
|
1479
|
+
rightWidth?: string;
|
|
1480
|
+
collapsible?: boolean;
|
|
1481
|
+
gridColumns?: number;
|
|
1482
|
+
gridGap?: string;
|
|
1483
|
+
hideHeader?: boolean;
|
|
1484
|
+
hideFooter?: boolean;
|
|
1485
|
+
headerHeight?: string;
|
|
1486
|
+
showBreadcrumbs?: boolean;
|
|
1487
|
+
showPageTitle?: boolean;
|
|
1488
|
+
customCssClass?: string;
|
|
1489
|
+
/** Sidebar config */
|
|
1490
|
+
sidebar?: {
|
|
1491
|
+
width?: string;
|
|
1492
|
+
collapsible?: boolean;
|
|
1493
|
+
defaultCollapsed?: boolean;
|
|
1494
|
+
breakpoint?: number;
|
|
1495
|
+
};
|
|
1496
|
+
/** Padding */
|
|
1497
|
+
padding?: string;
|
|
1498
|
+
[key: string]: any;
|
|
1499
|
+
}
|
|
1500
|
+
interface NavGroupMeta {
|
|
1501
|
+
label: string;
|
|
1502
|
+
items: NavItemMeta[];
|
|
1503
|
+
visibleWhen?: ConditionMeta;
|
|
1504
|
+
/** Collapsed by default */
|
|
1505
|
+
collapsed?: boolean;
|
|
1506
|
+
/** Group icon */
|
|
1507
|
+
icon?: string;
|
|
1508
|
+
}
|
|
1509
|
+
interface NavItemMeta {
|
|
1510
|
+
label: string;
|
|
1511
|
+
icon?: string;
|
|
1512
|
+
route?: string;
|
|
1513
|
+
children?: NavItemMeta[];
|
|
1514
|
+
badge?: string;
|
|
1515
|
+
badgeColor?: string;
|
|
1516
|
+
visibleWhen?: ConditionMeta;
|
|
1517
|
+
roles?: string[];
|
|
1518
|
+
permissions?: string[];
|
|
1519
|
+
action?: ActionMeta;
|
|
1520
|
+
/** Open in new tab */
|
|
1521
|
+
external?: boolean;
|
|
1522
|
+
/** External URL */
|
|
1523
|
+
url?: string;
|
|
1524
|
+
/** Tooltip */
|
|
1525
|
+
tooltip?: string;
|
|
1526
|
+
/** Disabled state */
|
|
1527
|
+
disabled?: boolean;
|
|
1528
|
+
/** Divider after this item */
|
|
1529
|
+
divider?: boolean;
|
|
1530
|
+
[key: string]: any;
|
|
1531
|
+
}
|
|
1532
|
+
interface FooterLinkMeta {
|
|
1533
|
+
label: string;
|
|
1534
|
+
url?: string;
|
|
1535
|
+
route?: string;
|
|
1536
|
+
external?: boolean;
|
|
1537
|
+
icon?: string;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
interface DialogConfig {
|
|
1541
|
+
title?: string;
|
|
1542
|
+
message: string;
|
|
1543
|
+
icon?: string;
|
|
1544
|
+
variant?: 'info' | 'success' | 'warning' | 'danger';
|
|
1545
|
+
confirmLabel?: string;
|
|
1546
|
+
cancelLabel?: string;
|
|
1547
|
+
showCancel?: boolean;
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
type CustomActionFn = (config: any, context: any) => any;
|
|
1551
|
+
declare class ActionDispatcherService {
|
|
1552
|
+
private readonly router;
|
|
1553
|
+
private readonly titleService;
|
|
1554
|
+
private readonly notifications;
|
|
1555
|
+
private readonly apiService;
|
|
1556
|
+
private readonly stateService;
|
|
1557
|
+
private readonly conditionEvaluator;
|
|
1558
|
+
private readonly dialogService;
|
|
1559
|
+
private readonly customHandlers;
|
|
1560
|
+
private readonly _events$;
|
|
1561
|
+
private readonly _modalEvents$;
|
|
1562
|
+
private readonly _drawerEvents$;
|
|
1563
|
+
private readonly _formEvents$;
|
|
1564
|
+
private readonly _tableEvents$;
|
|
1565
|
+
private readonly _loadingState;
|
|
1566
|
+
/** General event bus */
|
|
1567
|
+
readonly events$: rxjs.Observable<{
|
|
1568
|
+
event: string;
|
|
1569
|
+
payload: any;
|
|
1570
|
+
}>;
|
|
1571
|
+
/** Modal open/close events */
|
|
1572
|
+
readonly modalEvents$: rxjs.Observable<{
|
|
1573
|
+
action: "open" | "close";
|
|
1574
|
+
config: any;
|
|
1575
|
+
}>;
|
|
1576
|
+
/** Drawer open/close events */
|
|
1577
|
+
readonly drawerEvents$: rxjs.Observable<{
|
|
1578
|
+
action: "open" | "close";
|
|
1579
|
+
config: any;
|
|
1580
|
+
}>;
|
|
1581
|
+
/** Form manipulation events */
|
|
1582
|
+
readonly formEvents$: rxjs.Observable<{
|
|
1583
|
+
action: "reset" | "patch" | "submit";
|
|
1584
|
+
config: any;
|
|
1585
|
+
}>;
|
|
1586
|
+
/** Table reload events */
|
|
1587
|
+
readonly tableEvents$: rxjs.Observable<{
|
|
1588
|
+
action: "reload";
|
|
1589
|
+
config: any;
|
|
1590
|
+
}>;
|
|
1591
|
+
/** Register a custom action handler */
|
|
1592
|
+
registerHandler(type: string, handler: CustomActionFn): void;
|
|
1593
|
+
/** Check loading state */
|
|
1594
|
+
isLoading(key?: string): boolean;
|
|
1595
|
+
dispatch(action: ActionMeta, context?: any): Promise<any>;
|
|
1596
|
+
private handleNavigate;
|
|
1597
|
+
private handleApi;
|
|
1598
|
+
private handleNotify;
|
|
1599
|
+
/** Replace {{key}} and {{key.nested}} tokens with values from context */
|
|
1600
|
+
private interpolateTemplate;
|
|
1601
|
+
private handleEmit;
|
|
1602
|
+
private handleConfirm;
|
|
1603
|
+
private handleSetState;
|
|
1604
|
+
private handleClearState;
|
|
1605
|
+
private handleScrollTo;
|
|
1606
|
+
private handleFocus;
|
|
1607
|
+
private handleBlur;
|
|
1608
|
+
private handleToggleClass;
|
|
1609
|
+
private handleSetLoading;
|
|
1610
|
+
private handleDownloadFile;
|
|
1611
|
+
private handleCopyToClipboard;
|
|
1612
|
+
private handleOpenUrl;
|
|
1613
|
+
private handleSetStorage;
|
|
1614
|
+
private handleRemoveStorage;
|
|
1615
|
+
private handleDispatchMultiple;
|
|
1616
|
+
private handleDelay;
|
|
1617
|
+
private handleConditional;
|
|
1618
|
+
private handleForEach;
|
|
1619
|
+
private handleTransformContext;
|
|
1620
|
+
private handleLog;
|
|
1621
|
+
private handlePrint;
|
|
1622
|
+
/**
|
|
1623
|
+
* Built-in CLIENT-SIDE CRUD SIMULATOR — for demos and testbeds only.
|
|
1624
|
+
*
|
|
1625
|
+
* This action uses `sessionStorage` as a temporary in-memory database so that
|
|
1626
|
+
* CRUD operations (add / edit / delete) work without any backend connection.
|
|
1627
|
+
* Data does NOT persist across browser sessions or tabs.
|
|
1628
|
+
*
|
|
1629
|
+
* ## When to use this
|
|
1630
|
+
* Use `store-data` when you want to demonstrate or test a complete CRUD flow
|
|
1631
|
+
* (Add → Edit → Delete) entirely in the browser, with zero backend setup.
|
|
1632
|
+
* It is intentionally available to any AvoraMetaForge user for rapid prototyping.
|
|
1633
|
+
*
|
|
1634
|
+
* ## How to switch to a real backend
|
|
1635
|
+
* Replace the `store-data` action with an `api` action pointing to your endpoint:
|
|
1636
|
+
*
|
|
1637
|
+
* ```ts
|
|
1638
|
+
* // BEFORE (client-side mock):
|
|
1639
|
+
* { type: 'store-data', config: { storageKey: 'amf_table_users', action: 'add' } }
|
|
1640
|
+
*
|
|
1641
|
+
* // AFTER (real backend):
|
|
1642
|
+
* { type: 'api', config: { endpointId: 'create-user', body: 'formValue',
|
|
1643
|
+
* storeResultAs: 'newUser' } }
|
|
1644
|
+
* ```
|
|
1645
|
+
*
|
|
1646
|
+
* ## Config options
|
|
1647
|
+
* - `storageKey` — sessionStorage key (default: 'amf_demo_data')
|
|
1648
|
+
* - `action` — 'add' | 'edit' | 'delete'
|
|
1649
|
+
* - `identifierKey` — row identity field (default: 'id')
|
|
1650
|
+
* - `computedFields` — derived string fields interpolated from formValue
|
|
1651
|
+
* - `autoTimestampField`— if set, auto-stamps this field with an ISO date on 'add'
|
|
1652
|
+
*/
|
|
1653
|
+
private handleStoreData;
|
|
1654
|
+
private resolveContextPath;
|
|
1655
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ActionDispatcherService, never>;
|
|
1656
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ActionDispatcherService>;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
type CustomEvaluatorFn = (context: any, condition: ConditionMeta) => boolean;
|
|
1660
|
+
declare class ConditionEvaluatorService {
|
|
1661
|
+
private customEvaluators;
|
|
1662
|
+
/** Register a custom evaluator function (from plugins or app code) */
|
|
1663
|
+
registerEvaluator(key: string, fn: CustomEvaluatorFn): void;
|
|
1664
|
+
/** Evaluate a condition against a context object */
|
|
1665
|
+
evaluate(condition: ConditionMeta | undefined, context: Record<string, any>): boolean;
|
|
1666
|
+
private resolveFieldValue;
|
|
1667
|
+
private compare;
|
|
1668
|
+
private getLength;
|
|
1669
|
+
private getNestedValue;
|
|
1670
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ConditionEvaluatorService, never>;
|
|
1671
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ConditionEvaluatorService>;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
/**
|
|
1675
|
+
* AvoraMetaForge — Component Registry Service
|
|
1676
|
+
*/
|
|
1677
|
+
|
|
1678
|
+
declare class ComponentRegistryService {
|
|
1679
|
+
private readonly registry;
|
|
1680
|
+
register(key: string, component: Type<any>): void;
|
|
1681
|
+
registerAll(entries: Record<string, Type<any>>): void;
|
|
1682
|
+
get(key: string): Type<any> | undefined;
|
|
1683
|
+
has(key: string): boolean;
|
|
1684
|
+
keys(): string[];
|
|
1685
|
+
unregister(key: string): boolean;
|
|
1686
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ComponentRegistryService, never>;
|
|
1687
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ComponentRegistryService>;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
declare class MetaRouterService {
|
|
1691
|
+
private readonly router;
|
|
1692
|
+
/**
|
|
1693
|
+
* Called during APP_INITIALIZER to register all metadata-driven routes.
|
|
1694
|
+
* Preserves any existing static routes (e.g. login) already registered
|
|
1695
|
+
* via app.routes.ts, then appends dynamically generated routes.
|
|
1696
|
+
*/
|
|
1697
|
+
registerApp(appMeta: AppMeta): void;
|
|
1698
|
+
/**
|
|
1699
|
+
* Recursively converts PageMeta[] into Angular Route[].
|
|
1700
|
+
*/
|
|
1701
|
+
private buildPageRoutes;
|
|
1702
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaRouterService, never>;
|
|
1703
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MetaRouterService>;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
/**
|
|
1707
|
+
* AvoraMetaForge — Meta Section Interface
|
|
1708
|
+
*/
|
|
1709
|
+
|
|
1710
|
+
declare const META_SECTION_CONFIG: InjectionToken<any>;
|
|
1711
|
+
declare const META_SECTION_CONTEXT: InjectionToken<any>;
|
|
1712
|
+
interface MetaSectionComponent<T = any> {
|
|
1713
|
+
config: T;
|
|
1714
|
+
context?: any;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
declare class MetaPageComponent implements OnDestroy {
|
|
1718
|
+
private readonly route;
|
|
1719
|
+
private readonly router;
|
|
1720
|
+
private readonly titleService;
|
|
1721
|
+
private readonly actionDispatcher;
|
|
1722
|
+
private readonly dialogService;
|
|
1723
|
+
private readonly destroyRef;
|
|
1724
|
+
private subscriptions;
|
|
1725
|
+
private previousParams;
|
|
1726
|
+
private previousQueryParams;
|
|
1727
|
+
private initDispatched;
|
|
1728
|
+
/** Reactive route data — updates automatically on navigation */
|
|
1729
|
+
private readonly routeData;
|
|
1730
|
+
/** Computed PageMeta from route data */
|
|
1731
|
+
readonly pageMeta: i0.Signal<PageMeta>;
|
|
1732
|
+
/** Computed context from route data */
|
|
1733
|
+
readonly context: i0.Signal<{
|
|
1734
|
+
params: Params;
|
|
1735
|
+
queryParams: Params;
|
|
1736
|
+
state: any;
|
|
1737
|
+
data: Data;
|
|
1738
|
+
pageMeta: PageMeta;
|
|
1739
|
+
}>;
|
|
1740
|
+
constructor();
|
|
1741
|
+
private onPageMetaChange;
|
|
1742
|
+
ngOnDestroy(): void;
|
|
1743
|
+
/**
|
|
1744
|
+
* canDeactivate check — called by the router guard.
|
|
1745
|
+
* Returns true if safe to navigate away, or a confirm dialog if dirty.
|
|
1746
|
+
*/
|
|
1747
|
+
canDeactivate(): boolean | Promise<boolean>;
|
|
1748
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaPageComponent, never>;
|
|
1749
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MetaPageComponent, "amf-page", never, {}, {}, never, never, true, never>;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
/**
|
|
1753
|
+
* CanActivate guard — controls whether a page can be accessed
|
|
1754
|
+
*/
|
|
1755
|
+
declare const metaGuard: CanActivateFn;
|
|
1756
|
+
/**
|
|
1757
|
+
* CanDeactivate guard — warns before leaving if page has unsaved changes
|
|
1758
|
+
*/
|
|
1759
|
+
declare const metaCanDeactivateGuard: CanDeactivateFn<MetaPageComponent>;
|
|
1760
|
+
|
|
1761
|
+
/**
|
|
1762
|
+
* Returns the routing configuration for AvoraMetaForge's built-in auth UI.
|
|
1763
|
+
* Connect this output to your main `app.routes.ts`.
|
|
1764
|
+
*/
|
|
1765
|
+
declare function getAmfAuthRoutes(meta: AppMeta): Routes;
|
|
1766
|
+
|
|
1767
|
+
/**
|
|
1768
|
+
* AvoraMetaForge — Meta Renderer Component
|
|
1769
|
+
*/
|
|
1770
|
+
|
|
1771
|
+
declare class MetaRendererComponent implements OnChanges, OnDestroy {
|
|
1772
|
+
section: SectionMeta;
|
|
1773
|
+
context: any;
|
|
1774
|
+
outlet: ViewContainerRef;
|
|
1775
|
+
private readonly registry;
|
|
1776
|
+
private readonly conditionEvaluator;
|
|
1777
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
1778
|
+
ngOnDestroy(): void;
|
|
1779
|
+
private render;
|
|
1780
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaRendererComponent, never>;
|
|
1781
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MetaRendererComponent, "amf-renderer", never, { "section": { "alias": "section"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
declare class AccordionSectionComponent implements MetaSectionComponent<AccordionMeta>, OnChanges {
|
|
1785
|
+
config: AccordionMeta;
|
|
1786
|
+
context: any;
|
|
1787
|
+
private readonly conditionEvaluator;
|
|
1788
|
+
/** Set of open panel indices */
|
|
1789
|
+
openPanels: i0.WritableSignal<Set<number>>;
|
|
1790
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
1791
|
+
visiblePanels(): AccordionPanelMeta[];
|
|
1792
|
+
isOpen(index: number): boolean;
|
|
1793
|
+
togglePanel(index: number): void;
|
|
1794
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AccordionSectionComponent, never>;
|
|
1795
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AccordionSectionComponent, "amf-accordion-section", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
declare class MetaModalHostComponent implements OnInit, OnDestroy {
|
|
1799
|
+
private dispatcher;
|
|
1800
|
+
private sub?;
|
|
1801
|
+
isOpen: i0.WritableSignal<boolean>;
|
|
1802
|
+
config: i0.WritableSignal<any>;
|
|
1803
|
+
ngOnInit(): void;
|
|
1804
|
+
ngOnDestroy(): void;
|
|
1805
|
+
close(): void;
|
|
1806
|
+
closeOnBackdrop(e: Event): void;
|
|
1807
|
+
dispatchAction(actionMeta: any): void;
|
|
1808
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaModalHostComponent, never>;
|
|
1809
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MetaModalHostComponent, "amf-modal-host", never, {}, {}, never, never, true, never>;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
interface DialogRequest {
|
|
1813
|
+
config: DialogConfig;
|
|
1814
|
+
resolve: (value: boolean) => void;
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
/**
|
|
1818
|
+
* A simple SVG icon registry so the template doesn't depend on external icon fonts.
|
|
1819
|
+
* Icons are registered as inline SVG path data keyed by name.
|
|
1820
|
+
*/
|
|
1821
|
+
declare class IconRegistryService {
|
|
1822
|
+
private icons;
|
|
1823
|
+
constructor();
|
|
1824
|
+
/** Register a named SVG icon (viewBox 0 0 24 24) */
|
|
1825
|
+
register(name: string, svgPath: string): void;
|
|
1826
|
+
/** Get SVG path data for a named icon */
|
|
1827
|
+
getIcon(name: string): string;
|
|
1828
|
+
/** Check if an icon exists */
|
|
1829
|
+
has(name: string): boolean;
|
|
1830
|
+
private registerDefaults;
|
|
1831
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<IconRegistryService, never>;
|
|
1832
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<IconRegistryService>;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
declare class AmfDialogHostComponent implements OnInit, OnDestroy {
|
|
1836
|
+
readonly iconRegistry: IconRegistryService;
|
|
1837
|
+
private readonly dialogService;
|
|
1838
|
+
private sub?;
|
|
1839
|
+
currentDialog: i0.WritableSignal<DialogRequest | null>;
|
|
1840
|
+
get iconPath(): string | undefined;
|
|
1841
|
+
ngOnInit(): void;
|
|
1842
|
+
ngOnDestroy(): void;
|
|
1843
|
+
onBackdropClick(): void;
|
|
1844
|
+
close(result: boolean): void;
|
|
1845
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AmfDialogHostComponent, never>;
|
|
1846
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AmfDialogHostComponent, "amf-dialog-host", never, {}, {}, never, never, true, never>;
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
declare class AmfDrawerHostComponent implements OnInit, OnDestroy {
|
|
1850
|
+
private readonly dispatcher;
|
|
1851
|
+
private sub?;
|
|
1852
|
+
isOpen: i0.WritableSignal<boolean>;
|
|
1853
|
+
config: i0.WritableSignal<any>;
|
|
1854
|
+
ngOnInit(): void;
|
|
1855
|
+
ngOnDestroy(): void;
|
|
1856
|
+
close(): void;
|
|
1857
|
+
closeOnBackdrop(): void;
|
|
1858
|
+
dispatchAction(actionMeta: any): void;
|
|
1859
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AmfDrawerHostComponent, never>;
|
|
1860
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AmfDrawerHostComponent, "amf-drawer-host", never, {}, {}, never, never, true, never>;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
declare class MetaApiService {
|
|
1864
|
+
private readonly http;
|
|
1865
|
+
private readonly state;
|
|
1866
|
+
private endpoints;
|
|
1867
|
+
private cache;
|
|
1868
|
+
private environments;
|
|
1869
|
+
private activeEnvironment;
|
|
1870
|
+
private globalHeaders;
|
|
1871
|
+
private customTransforms;
|
|
1872
|
+
registerEndpoints(apis: ApiEndpointMeta[]): void;
|
|
1873
|
+
registerEnvironments(envs: Record<string, {
|
|
1874
|
+
baseUrl: string;
|
|
1875
|
+
[key: string]: any;
|
|
1876
|
+
}>, active?: string): void;
|
|
1877
|
+
setActiveEnvironment(env: string): void;
|
|
1878
|
+
setGlobalHeaders(headers: Record<string, string>): void;
|
|
1879
|
+
registerTransform(key: string, fn: (data: any, config: any) => any): void;
|
|
1880
|
+
getEndpoint(id: string): ApiEndpointMeta | undefined;
|
|
1881
|
+
call(id: string, dynamicParams?: Record<string, string>, dynamicBody?: any, options?: {
|
|
1882
|
+
headers?: Record<string, string>;
|
|
1883
|
+
queryParams?: Record<string, string>;
|
|
1884
|
+
paginationParams?: Record<string, string>;
|
|
1885
|
+
}): Promise<any>;
|
|
1886
|
+
/**
|
|
1887
|
+
* Direct call without registered endpoint — supports inline config
|
|
1888
|
+
*/
|
|
1889
|
+
callDirect(config: {
|
|
1890
|
+
url: string;
|
|
1891
|
+
method: HttpMethod;
|
|
1892
|
+
body?: any;
|
|
1893
|
+
headers?: Record<string, string>;
|
|
1894
|
+
queryParams?: Record<string, string>;
|
|
1895
|
+
responseType?: 'json' | 'text' | 'blob' | 'arraybuffer';
|
|
1896
|
+
timeout?: number;
|
|
1897
|
+
}): Promise<any>;
|
|
1898
|
+
/** Invalidate cache for a specific endpoint */
|
|
1899
|
+
invalidateCache(endpointId: string): void;
|
|
1900
|
+
/** Invalidate all caches */
|
|
1901
|
+
invalidateAllCache(): void;
|
|
1902
|
+
/** Invalidate caches linked via invalidateOn */
|
|
1903
|
+
invalidateLinkedCaches(triggeredEndpointId: string): void;
|
|
1904
|
+
private injectAuth;
|
|
1905
|
+
private handleMock;
|
|
1906
|
+
private applyTransform;
|
|
1907
|
+
private pickKeys;
|
|
1908
|
+
private omitKeys;
|
|
1909
|
+
private getCacheKey;
|
|
1910
|
+
private getCached;
|
|
1911
|
+
private storeInCache;
|
|
1912
|
+
private retryWithBackoff;
|
|
1913
|
+
private resolveBaseUrl;
|
|
1914
|
+
private toFormData;
|
|
1915
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaApiService, never>;
|
|
1916
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MetaApiService>;
|
|
1917
|
+
}
|
|
1918
|
+
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
1919
|
+
|
|
1920
|
+
interface StateChange {
|
|
1921
|
+
key: string;
|
|
1922
|
+
previousValue: any;
|
|
1923
|
+
newValue: any;
|
|
1924
|
+
timestamp: number;
|
|
1925
|
+
}
|
|
1926
|
+
declare class MetaStateService {
|
|
1927
|
+
/** Internal state map — each key holds a signal */
|
|
1928
|
+
private readonly store;
|
|
1929
|
+
private readonly persistedKeys;
|
|
1930
|
+
private readonly _changes$;
|
|
1931
|
+
/** Observable stream of all state changes */
|
|
1932
|
+
readonly changes$: rxjs.Observable<StateChange>;
|
|
1933
|
+
/** Set a value in the store */
|
|
1934
|
+
set(key: string, value: any, persist?: boolean): void;
|
|
1935
|
+
/** Get current value of a key */
|
|
1936
|
+
get(key: string): any;
|
|
1937
|
+
/** Get a signal for reactive binding */
|
|
1938
|
+
select(key: string): Signal<any>;
|
|
1939
|
+
/** Computed signal derived from one or more keys */
|
|
1940
|
+
selectComputed(keys: string[], fn: (...values: any[]) => any): Signal<any>;
|
|
1941
|
+
/** Merge value with existing (for objects) */
|
|
1942
|
+
merge(key: string, partial: Record<string, any>, persist?: boolean): void;
|
|
1943
|
+
/** Patch a nested path within a stored object */
|
|
1944
|
+
patch(key: string, path: string, value: any, persist?: boolean): void;
|
|
1945
|
+
/** Check if a key exists */
|
|
1946
|
+
has(key: string): boolean;
|
|
1947
|
+
/** Remove a key from the store */
|
|
1948
|
+
clear(key: string, clearPersisted?: boolean): void;
|
|
1949
|
+
/** Reset entire store */
|
|
1950
|
+
resetAll(clearPersisted?: boolean): void;
|
|
1951
|
+
/** Reset specific namespace (e.g., clear all 'page.users.*' keys) */
|
|
1952
|
+
clearNamespace(namespace: string, clearPersisted?: boolean): void;
|
|
1953
|
+
/** Get all keys under a namespace as an object */
|
|
1954
|
+
getNamespace(namespace: string): Record<string, any>;
|
|
1955
|
+
/** Set multiple keys at once */
|
|
1956
|
+
setMany(entries: Record<string, any>, persist?: boolean): void;
|
|
1957
|
+
/** Get all keys and values as a plain object */
|
|
1958
|
+
snapshot(): Record<string, any>;
|
|
1959
|
+
/** Resolve a value that might be prefixed with 'state:' */
|
|
1960
|
+
resolveValue(value: any): any;
|
|
1961
|
+
private getOrCreateSignal;
|
|
1962
|
+
private storageKey;
|
|
1963
|
+
private persistToStorage;
|
|
1964
|
+
private loadFromStorage;
|
|
1965
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaStateService, never>;
|
|
1966
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MetaStateService>;
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
interface AuthUser {
|
|
1970
|
+
id?: string;
|
|
1971
|
+
email?: string;
|
|
1972
|
+
name?: string;
|
|
1973
|
+
roles?: string[];
|
|
1974
|
+
permissions?: string[];
|
|
1975
|
+
avatar?: string;
|
|
1976
|
+
[key: string]: any;
|
|
1977
|
+
}
|
|
1978
|
+
declare class MetaAuthService {
|
|
1979
|
+
private readonly state;
|
|
1980
|
+
private readonly apiService;
|
|
1981
|
+
private config;
|
|
1982
|
+
private refreshTimer;
|
|
1983
|
+
/** Initialize auth from AppMeta config */
|
|
1984
|
+
configure(authConfig: GlobalAuthMeta): void;
|
|
1985
|
+
/** Store auth token and update state */
|
|
1986
|
+
setToken(token: string, refreshToken?: string): void;
|
|
1987
|
+
/** Get current token */
|
|
1988
|
+
getToken(): string | null;
|
|
1989
|
+
/** Get current refresh token */
|
|
1990
|
+
getRefreshToken(): string | null;
|
|
1991
|
+
/** Check if user is authenticated */
|
|
1992
|
+
isAuthenticated(): boolean;
|
|
1993
|
+
/** Set the current user */
|
|
1994
|
+
setUser(user: AuthUser): void;
|
|
1995
|
+
/** Get current user */
|
|
1996
|
+
getUser(): AuthUser | null;
|
|
1997
|
+
/** Check if user has a specific role */
|
|
1998
|
+
hasRole(role: string): boolean;
|
|
1999
|
+
/** Check if user has ANY of the specified roles */
|
|
2000
|
+
hasAnyRole(roles: string[]): boolean;
|
|
2001
|
+
/** Check if user has a specific permission */
|
|
2002
|
+
hasPermission(permission: string): boolean;
|
|
2003
|
+
/** Check if user has ALL specified permissions */
|
|
2004
|
+
hasAllPermissions(permissions: string[]): boolean;
|
|
2005
|
+
/** Perform login via configured endpoint */
|
|
2006
|
+
login(credentials: Record<string, any>): Promise<any>;
|
|
2007
|
+
/** Perform logout */
|
|
2008
|
+
logout(): Promise<void>;
|
|
2009
|
+
/** Refresh the auth token */
|
|
2010
|
+
refreshAuthToken(): Promise<string | null>;
|
|
2011
|
+
private scheduleTokenRefresh;
|
|
2012
|
+
private getStorage;
|
|
2013
|
+
private getStoredToken;
|
|
2014
|
+
private getFromStorage;
|
|
2015
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetaAuthService, never>;
|
|
2016
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MetaAuthService>;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
declare class PluginRegistryService {
|
|
2020
|
+
private plugins;
|
|
2021
|
+
register(plugin: AvoraMetaForgePlugin): void;
|
|
2022
|
+
getAll(): AvoraMetaForgePlugin[];
|
|
2023
|
+
get(name: string): AvoraMetaForgePlugin | undefined;
|
|
2024
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PluginRegistryService, never>;
|
|
2025
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PluginRegistryService>;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
/**
|
|
2029
|
+
* AvoraMetaForge — Form Renderer Component
|
|
2030
|
+
*/
|
|
2031
|
+
|
|
2032
|
+
declare class FormRendererComponent implements MetaSectionComponent<FormMeta>, OnInit, OnChanges, OnDestroy {
|
|
2033
|
+
config: FormMeta;
|
|
2034
|
+
context: any;
|
|
2035
|
+
formSubmit: EventEmitter<any>;
|
|
2036
|
+
formCancel: EventEmitter<void>;
|
|
2037
|
+
formChange: EventEmitter<any>;
|
|
2038
|
+
formGroup: FormGroup;
|
|
2039
|
+
private readonly validatorFactory;
|
|
2040
|
+
private readonly conditionEvaluator;
|
|
2041
|
+
readonly actionDispatcher: ActionDispatcherService;
|
|
2042
|
+
private readonly stateService;
|
|
2043
|
+
private sub?;
|
|
2044
|
+
ngOnInit(): void;
|
|
2045
|
+
ngOnDestroy(): void;
|
|
2046
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
2047
|
+
get visibleFields(): FieldMeta[];
|
|
2048
|
+
/** Normalize fields: ensure every field has a `key` (falling back to `name` for backward compat) */
|
|
2049
|
+
private get normalizedFields();
|
|
2050
|
+
get layoutClass(): string;
|
|
2051
|
+
get gridColumns(): string | null;
|
|
2052
|
+
onSubmit(): void;
|
|
2053
|
+
handleCancel(): void;
|
|
2054
|
+
private buildForm;
|
|
2055
|
+
buildControls(fields: FieldMeta[], rowData: any, statePrefix: string): Record<string, AbstractControl>;
|
|
2056
|
+
private markAllTouched;
|
|
2057
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FormRendererComponent, never>;
|
|
2058
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FormRendererComponent, "amf-form-renderer", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; "formChange": "formChange"; }, never, never, true, never>;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
declare class StepperFormRendererComponent implements MetaSectionComponent<FormMeta>, OnInit, OnChanges, OnDestroy {
|
|
2062
|
+
config: FormMeta;
|
|
2063
|
+
context: any;
|
|
2064
|
+
formSubmit: EventEmitter<any>;
|
|
2065
|
+
formCancel: EventEmitter<void>;
|
|
2066
|
+
formGroup: FormGroup;
|
|
2067
|
+
private readonly validatorFactory;
|
|
2068
|
+
private readonly conditionEvaluator;
|
|
2069
|
+
readonly actionDispatcher: ActionDispatcherService;
|
|
2070
|
+
private readonly stateService;
|
|
2071
|
+
private sub?;
|
|
2072
|
+
currentStep: i0.WritableSignal<number>;
|
|
2073
|
+
completedSteps: i0.WritableSignal<Set<number>>;
|
|
2074
|
+
skippedSteps: i0.WritableSignal<Set<number>>;
|
|
2075
|
+
stepErrors: i0.WritableSignal<string[]>;
|
|
2076
|
+
resolvedSteps: i0.Signal<FormStepMeta[]>;
|
|
2077
|
+
progressPercent: i0.Signal<number>;
|
|
2078
|
+
currentGridColumns: i0.Signal<string>;
|
|
2079
|
+
ngOnInit(): void;
|
|
2080
|
+
resetForm(): void;
|
|
2081
|
+
ngOnDestroy(): void;
|
|
2082
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
2083
|
+
currentStepVisibleFields: i0.Signal<FieldMeta[]>;
|
|
2084
|
+
private get normalizedFields();
|
|
2085
|
+
isCompleted(index: number): boolean;
|
|
2086
|
+
isSkipped(index: number): boolean;
|
|
2087
|
+
canNavigateTo(index: number): boolean;
|
|
2088
|
+
goToStep(index: number): void;
|
|
2089
|
+
goNext(): void;
|
|
2090
|
+
goBack(): void;
|
|
2091
|
+
skipStep(): void;
|
|
2092
|
+
onSubmit(): void;
|
|
2093
|
+
private buildForm;
|
|
2094
|
+
private buildControls;
|
|
2095
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StepperFormRendererComponent, never>;
|
|
2096
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StepperFormRendererComponent, "amf-stepper-form-renderer", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, { "formSubmit": "formSubmit"; "formCancel": "formCancel"; }, never, never, true, never>;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
declare class RepeaterFieldComponent {
|
|
2100
|
+
field: FieldMeta;
|
|
2101
|
+
formArray: FormArray;
|
|
2102
|
+
formDisabled: boolean;
|
|
2103
|
+
actionDispatcher: any;
|
|
2104
|
+
context: any;
|
|
2105
|
+
private readonly validatorFactory;
|
|
2106
|
+
get canAdd(): boolean;
|
|
2107
|
+
get canRemove(): boolean;
|
|
2108
|
+
getFormGroup(ctrl: any): FormGroup;
|
|
2109
|
+
getGridStyle(field: FieldMeta): string;
|
|
2110
|
+
addItem(): void;
|
|
2111
|
+
removeItem(index: number): void;
|
|
2112
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RepeaterFieldComponent, never>;
|
|
2113
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RepeaterFieldComponent, "amf-repeater-field", never, { "field": { "alias": "field"; "required": false; }; "formArray": { "alias": "formArray"; "required": false; }; "formDisabled": { "alias": "formDisabled"; "required": false; }; "actionDispatcher": { "alias": "actionDispatcher"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
declare class TableRendererComponent implements MetaSectionComponent<TableMeta>, OnInit, OnDestroy {
|
|
2117
|
+
config: TableMeta;
|
|
2118
|
+
context: any;
|
|
2119
|
+
rowAction: EventEmitter<{
|
|
2120
|
+
actionId: string;
|
|
2121
|
+
row: any;
|
|
2122
|
+
}>;
|
|
2123
|
+
readonly iconRegistry: IconRegistryService;
|
|
2124
|
+
private readonly actionDispatcher;
|
|
2125
|
+
private readonly apiService;
|
|
2126
|
+
private readonly dialogService;
|
|
2127
|
+
searchQuery: i0.WritableSignal<string>;
|
|
2128
|
+
sortKey: i0.WritableSignal<string | null>;
|
|
2129
|
+
sortDirection: i0.WritableSignal<"asc" | "desc">;
|
|
2130
|
+
currentPage: i0.WritableSignal<number>;
|
|
2131
|
+
exportMenuOpen: i0.WritableSignal<boolean>;
|
|
2132
|
+
selectedRows: i0.WritableSignal<Set<any>>;
|
|
2133
|
+
expandedRows: i0.WritableSignal<Set<any>>;
|
|
2134
|
+
collapsedGroups: i0.WritableSignal<Set<string>>;
|
|
2135
|
+
localColumns: i0.WritableSignal<ColumnMeta[]>;
|
|
2136
|
+
editingCell: i0.WritableSignal<{
|
|
2137
|
+
row: any;
|
|
2138
|
+
key: string;
|
|
2139
|
+
} | null>;
|
|
2140
|
+
editBuffer: Record<string, any>;
|
|
2141
|
+
editError: i0.WritableSignal<string | null>;
|
|
2142
|
+
pageSizeOverride: i0.WritableSignal<number | null>;
|
|
2143
|
+
private filterValues;
|
|
2144
|
+
allData: i0.WritableSignal<any[]>;
|
|
2145
|
+
private tableEventsSub?;
|
|
2146
|
+
private sectionId?;
|
|
2147
|
+
ngOnInit(): void;
|
|
2148
|
+
ngOnDestroy(): void;
|
|
2149
|
+
private loadData;
|
|
2150
|
+
private getStorageKey;
|
|
2151
|
+
visibleColumns: i0.Signal<ColumnMeta[]>;
|
|
2152
|
+
filteredData: i0.Signal<any[]>;
|
|
2153
|
+
/** Flat list with injected group-header sentinel objects for @for rendering */
|
|
2154
|
+
groupedRows: i0.Signal<any[]>;
|
|
2155
|
+
activePageSize: i0.Signal<number>;
|
|
2156
|
+
setPageSize(size: number | string): void;
|
|
2157
|
+
paginatedData: i0.Signal<any[]>;
|
|
2158
|
+
totalPages: i0.Signal<number>;
|
|
2159
|
+
pageNumbers: i0.Signal<number[]>;
|
|
2160
|
+
toggleSort(key: string): void;
|
|
2161
|
+
getCellValue(row: any, key: string): any;
|
|
2162
|
+
getFilterValue(key: string): string;
|
|
2163
|
+
setFilterValue(key: string, value: string): void;
|
|
2164
|
+
handleAction(action: TableActionMeta, row: any): Promise<void>;
|
|
2165
|
+
handleRowClick(row: any): void;
|
|
2166
|
+
toggleSelection(row: any): void;
|
|
2167
|
+
toggleAllSelection(event: Event): void;
|
|
2168
|
+
private emitSelectionChange;
|
|
2169
|
+
isEditing(row: any, key: string): boolean;
|
|
2170
|
+
startEdit(row: any, key: string, event: MouseEvent): void;
|
|
2171
|
+
commitEdit(row: any, key: string): void;
|
|
2172
|
+
/** Runs all validators for an inline-edit value. Returns the first error message, or null if valid. */
|
|
2173
|
+
private runInlineValidators;
|
|
2174
|
+
cancelEdit(): void;
|
|
2175
|
+
toggleRowExpand(row: any): void;
|
|
2176
|
+
toggleGroup(key: string): void;
|
|
2177
|
+
getAggregate(colKey: string): {
|
|
2178
|
+
label?: string;
|
|
2179
|
+
value: string | number;
|
|
2180
|
+
} | null;
|
|
2181
|
+
exportData(format: string): void;
|
|
2182
|
+
dropColumn(event: CdkDragDrop<string[]>): void;
|
|
2183
|
+
dropRow(event: CdkDragDrop<any[]>): void;
|
|
2184
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TableRendererComponent, never>;
|
|
2185
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TableRendererComponent, "amf-table-renderer", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, { "rowAction": "rowAction"; }, never, never, true, never>;
|
|
2186
|
+
}
|
|
2187
|
+
|
|
2188
|
+
declare class CardSectionComponent implements MetaSectionComponent<CardMeta> {
|
|
2189
|
+
config: CardMeta;
|
|
2190
|
+
context: any;
|
|
2191
|
+
readonly actionDispatcher: ActionDispatcherService;
|
|
2192
|
+
private readonly sanitizer;
|
|
2193
|
+
get trustedContent(): SafeHtml;
|
|
2194
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CardSectionComponent, never>;
|
|
2195
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CardSectionComponent, "amf-card", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
declare class StatsGridSectionComponent implements MetaSectionComponent<StatsGridMeta> {
|
|
2199
|
+
config: StatsGridMeta;
|
|
2200
|
+
context: any;
|
|
2201
|
+
readonly iconRegistry: IconRegistryService;
|
|
2202
|
+
get gridCols(): string;
|
|
2203
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StatsGridSectionComponent, never>;
|
|
2204
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StatsGridSectionComponent, "amf-stats-grid", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
declare class PageHeaderSectionComponent implements MetaSectionComponent<PageHeaderMeta> {
|
|
2208
|
+
config: PageHeaderMeta;
|
|
2209
|
+
context: any;
|
|
2210
|
+
readonly actionDispatcher: ActionDispatcherService;
|
|
2211
|
+
readonly iconRegistry: IconRegistryService;
|
|
2212
|
+
get resolvedTitle(): string;
|
|
2213
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PageHeaderSectionComponent, never>;
|
|
2214
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PageHeaderSectionComponent, "amf-page-header", never, { "config": { "alias": "config"; "required": false; }; "context": { "alias": "context"; "required": false; }; }, {}, never, never, true, never>;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
interface NavItem {
|
|
2218
|
+
label: string;
|
|
2219
|
+
icon?: string;
|
|
2220
|
+
route?: string;
|
|
2221
|
+
children?: NavItem[];
|
|
2222
|
+
badge?: string;
|
|
2223
|
+
badgeColor?: string;
|
|
2224
|
+
}
|
|
2225
|
+
interface NavGroup {
|
|
2226
|
+
label: string;
|
|
2227
|
+
items: NavItem[];
|
|
2228
|
+
}
|
|
2229
|
+
declare class NavigationService {
|
|
2230
|
+
private readonly metaConfig;
|
|
2231
|
+
readonly menuItems: i0.WritableSignal<NavGroup[]>;
|
|
2232
|
+
setMenuItems(groups: NavGroup[]): void;
|
|
2233
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NavigationService, never>;
|
|
2234
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<NavigationService>;
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
/**
|
|
2238
|
+
* Defines the available layout types for the application shell.
|
|
2239
|
+
* Used in route data to determine which layout wraps a given page.
|
|
2240
|
+
*/
|
|
2241
|
+
declare enum LayoutType {
|
|
2242
|
+
/** Classic admin: sidebar left, header top */
|
|
2243
|
+
VERTICAL = "vertical",
|
|
2244
|
+
/** Modern admin: horizontal menu in header */
|
|
2245
|
+
HORIZONTAL = "horizontal",
|
|
2246
|
+
/** Blank wrapper for login, error, and standalone pages */
|
|
2247
|
+
EMPTY = "empty",
|
|
2248
|
+
/** Centered content card — wizards, onboarding, standalone forms */
|
|
2249
|
+
CENTERED = "centered",
|
|
2250
|
+
/** Split-pane master-detail — settings, detail views */
|
|
2251
|
+
TWO_COLUMN = "two-column",
|
|
2252
|
+
/** CSS Grid widget layout — analytics, monitoring dashboards */
|
|
2253
|
+
DASHBOARD_GRID = "dashboard-grid",
|
|
2254
|
+
/** Minimal chrome, auto-hiding header — data-dense, mobile-first */
|
|
2255
|
+
COMPACT = "compact"
|
|
2256
|
+
}
|
|
2257
|
+
|
|
2258
|
+
/**
|
|
2259
|
+
* Central configuration service for the application shell.
|
|
2260
|
+
* Manages layout state, branding, and global settings using Angular Signals.
|
|
2261
|
+
*/
|
|
2262
|
+
declare class AppConfigService implements OnDestroy {
|
|
2263
|
+
private router;
|
|
2264
|
+
/**
|
|
2265
|
+
* Current active layout type.
|
|
2266
|
+
* Initialized from the browser URL *before* Angular's first navigation so
|
|
2267
|
+
* the correct layout shell renders on the very first frame, preventing the
|
|
2268
|
+
* brief flash of the sidebar/navbar chrome on pages like /login.
|
|
2269
|
+
*/
|
|
2270
|
+
private readonly _currentLayout;
|
|
2271
|
+
/** Application display name */
|
|
2272
|
+
readonly appName: i0.WritableSignal<string>;
|
|
2273
|
+
/** Copyright text for the footer */
|
|
2274
|
+
readonly copyrightText: i0.WritableSignal<string>;
|
|
2275
|
+
/** Sidebar collapsed state */
|
|
2276
|
+
readonly sidebarCollapsed: i0.WritableSignal<boolean>;
|
|
2277
|
+
/** Public read-only accessor for the current layout */
|
|
2278
|
+
readonly currentLayout: i0.Signal<LayoutType>;
|
|
2279
|
+
private readonly stateService;
|
|
2280
|
+
private readonly titleService;
|
|
2281
|
+
private _settingsSub?;
|
|
2282
|
+
/**
|
|
2283
|
+
* Reads window.location.pathname before Angular's first navigation to
|
|
2284
|
+
* determine the correct initial layout. Prevents the one-frame flash of
|
|
2285
|
+
* the sidebar/navbar shell when refreshing on an auth-only page like /login.
|
|
2286
|
+
*/
|
|
2287
|
+
private getInitialLayout;
|
|
2288
|
+
constructor(router: Router);
|
|
2289
|
+
ngOnDestroy(): void;
|
|
2290
|
+
/** Update layout based on the current activated route data */
|
|
2291
|
+
private updateLayoutFromUrl;
|
|
2292
|
+
/** Set the layout type programmatically */
|
|
2293
|
+
setLayout(type: LayoutType): void;
|
|
2294
|
+
/** Toggle sidebar collapsed state */
|
|
2295
|
+
toggleSidebar(): void;
|
|
2296
|
+
/** Walk the route tree to find the deepest activated child */
|
|
2297
|
+
private getDeepestRoute;
|
|
2298
|
+
/** Apply settings persisted across sessions on startup */
|
|
2299
|
+
private applyPersistedSettings;
|
|
2300
|
+
/**
|
|
2301
|
+
* Called whenever a settings.* state key changes (e.g. after the Settings
|
|
2302
|
+
* form is submitted). Maps each key to the appropriate runtime effect.
|
|
2303
|
+
*/
|
|
2304
|
+
private applySettingChange;
|
|
2305
|
+
/**
|
|
2306
|
+
* Toggles dark / light mode by setting data-color-scheme on <html>.
|
|
2307
|
+
* Dark mode = no attribute (uses :root CSS vars from _variables.scss).
|
|
2308
|
+
* Light mode = data-color-scheme="light" (overrides via _themes.scss).
|
|
2309
|
+
*/
|
|
2310
|
+
private applyColorScheme;
|
|
2311
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AppConfigService, never>;
|
|
2312
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AppConfigService>;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
/**
|
|
2316
|
+
* AvoraMetaForge — Provider Initialization
|
|
2317
|
+
*
|
|
2318
|
+
* Provides the APP_INITIALIZER factory that bootstraps the framework:
|
|
2319
|
+
* 1. Registers built-in section components (form, table, card, etc.)
|
|
2320
|
+
* 2. Registers API endpoint definitions
|
|
2321
|
+
* 3. Registers environments and auth configuration
|
|
2322
|
+
* 4. Generates and registers dynamic routes from metadata
|
|
2323
|
+
* 5. Registers plugins (custom actions, validators, conditions, etc.)
|
|
2324
|
+
* 6. Initializes MetaStateService and MetaAuthService
|
|
2325
|
+
*/
|
|
2326
|
+
|
|
2327
|
+
declare const APP_META_CONFIG_TOKEN: InjectionToken<AppMeta>;
|
|
2328
|
+
|
|
2329
|
+
/**
|
|
2330
|
+
* Factory function invoked by APP_INITIALIZER before the app renders.
|
|
2331
|
+
* Returns a synchronous function — Angular waits for it to complete
|
|
2332
|
+
* before performing the initial navigation.
|
|
2333
|
+
*/
|
|
2334
|
+
declare function initializeAvoraMetaForge(registry: ComponentRegistryService, routerService: MetaRouterService, apiService: MetaApiService, stateService: MetaStateService, authService: MetaAuthService, actionDispatcher: ActionDispatcherService, conditionEvaluator: ConditionEvaluatorService, pluginRegistry: PluginRegistryService, navService: NavigationService, appConfigService: AppConfigService, config: AppMeta): () => void;
|
|
2335
|
+
/**
|
|
2336
|
+
* Call this in app.config.ts to wire up AvoraMetaForge:
|
|
2337
|
+
*
|
|
2338
|
+
* provideAvoraMetaForge(APP_META)
|
|
2339
|
+
*/
|
|
2340
|
+
declare function provideAvoraMetaForge(config: AppMeta): Provider[];
|
|
2341
|
+
|
|
2342
|
+
interface UserProfile {
|
|
2343
|
+
id: string;
|
|
2344
|
+
name: string;
|
|
2345
|
+
email: string;
|
|
2346
|
+
avatar: string;
|
|
2347
|
+
role: string;
|
|
2348
|
+
company: string;
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* ╔══════════════════════════════════════════════════════════════════╗
|
|
2352
|
+
* ║ DEMO / PROTOTYPE AUTH SERVICE — NOT FOR PRODUCTION ║
|
|
2353
|
+
* ╠══════════════════════════════════════════════════════════════════╣
|
|
2354
|
+
* ║ This service simulates authentication entirely on the client. ║
|
|
2355
|
+
* ║ The login() method accepts ANY email and password and creates ║
|
|
2356
|
+
* ║ a fake JWT-shaped token. There is NO real credential check. ║
|
|
2357
|
+
* ║ ║
|
|
2358
|
+
* ║ Purpose: let framework developers demo the full auth UI flow ║
|
|
2359
|
+
* ║ (login → guard → interceptor → logout) without a live backend. ║
|
|
2360
|
+
* ║ ║
|
|
2361
|
+
* ║ ── TO SWITCH TO REAL AUTH ─────────────────────────────────── ║
|
|
2362
|
+
* ║ Option A (recommended): Use MetaAuthService directly. ║
|
|
2363
|
+
* ║ • Configure `auth.loginEndpoint` in AppMeta to a real endpoint ║
|
|
2364
|
+
* ║ • Remove mock:true from that endpoint definition ║
|
|
2365
|
+
* ║ • MetaAuthService handles token storage + auto-refresh ║
|
|
2366
|
+
* ║ ║
|
|
2367
|
+
* ║ Option B: Keep this service but replace _mockLogin() body with ║
|
|
2368
|
+
* ║ a real HTTP call (e.g. via HttpClient or MetaApiService). ║
|
|
2369
|
+
* ║ ║
|
|
2370
|
+
* ║ See FRAMEWORK_GUIDE.md §3 for a step-by-step migration guide. ║
|
|
2371
|
+
* ╚══════════════════════════════════════════════════════════════════╝
|
|
2372
|
+
*/
|
|
2373
|
+
declare class AuthService {
|
|
2374
|
+
private router;
|
|
2375
|
+
/**
|
|
2376
|
+
* Sentinel flag — always `true` on this demo implementation.
|
|
2377
|
+
* Production code can check `AuthService.IS_MOCK_AUTH` to detect
|
|
2378
|
+
* whether real authentication is wired up.
|
|
2379
|
+
*/
|
|
2380
|
+
static readonly IS_MOCK_AUTH = true;
|
|
2381
|
+
private readonly TOKEN_KEY;
|
|
2382
|
+
private readonly USER_KEY;
|
|
2383
|
+
private readonly REDIRECT_KEY;
|
|
2384
|
+
private readonly _user;
|
|
2385
|
+
readonly user: i0.Signal<UserProfile | null>;
|
|
2386
|
+
readonly isAuthenticated: i0.Signal<boolean>;
|
|
2387
|
+
constructor(router: Router);
|
|
2388
|
+
private getInitialUser;
|
|
2389
|
+
/**
|
|
2390
|
+
* Authenticate a user.
|
|
2391
|
+
*
|
|
2392
|
+
* ⚠️ DEMO IMPLEMENTATION — accepts any credentials.
|
|
2393
|
+
* Internally delegates to `_mockLogin()` which fabricates a JWT-shaped
|
|
2394
|
+
* token without contacting any server.
|
|
2395
|
+
*
|
|
2396
|
+
* To use real auth, replace the body of `_mockLogin()` (or this method)
|
|
2397
|
+
* with an actual API call. See FRAMEWORK_GUIDE.md §3.
|
|
2398
|
+
*/
|
|
2399
|
+
login(email: string, password: string): boolean;
|
|
2400
|
+
/**
|
|
2401
|
+
* ── MOCK IMPLEMENTATION ──────────────────────────────────────────
|
|
2402
|
+
* Generates a fake JWT-shaped token and stores a fabricated user profile.
|
|
2403
|
+
* This method has NO security — it accepts any email/password pair.
|
|
2404
|
+
* It exists purely to allow testing the auth UI flow without a backend.
|
|
2405
|
+
* ─────────────────────────────────────────────────────────────────
|
|
2406
|
+
*/
|
|
2407
|
+
private _mockLogin;
|
|
2408
|
+
/** Clear session and navigate to login */
|
|
2409
|
+
logout(): void;
|
|
2410
|
+
/** Get the raw token string */
|
|
2411
|
+
getToken(): string | null;
|
|
2412
|
+
/** Get the current user profile */
|
|
2413
|
+
getUserProfile(): UserProfile | null;
|
|
2414
|
+
/** Check if the current user has a specific role */
|
|
2415
|
+
hasRole(role: string | string[]): boolean;
|
|
2416
|
+
/** Store the URL the user was trying to access before being redirected to login */
|
|
2417
|
+
storeRedirectUrl(url: string): void;
|
|
2418
|
+
/** Check if the mock token is expired */
|
|
2419
|
+
isTokenExpired(token?: string | null): boolean;
|
|
2420
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthService, never>;
|
|
2421
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<AuthService>;
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
/**
|
|
2425
|
+
* Functional auth guard (CanActivateFn).
|
|
2426
|
+
* - Checks if a valid (non-expired) token exists via AuthService.
|
|
2427
|
+
* - Stores the attempted URL for post-login redirect.
|
|
2428
|
+
* - Redirects unauthenticated users to /login.
|
|
2429
|
+
*
|
|
2430
|
+
* \u2500\u2500 CURRENT (DEMO) BEHAVIOUR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2431
|
+
* Delegates to `AuthService` (the demo/mock auth service).
|
|
2432
|
+
* The token it checks is a locally-generated fake JWT \u2014 no server
|
|
2433
|
+
* validation occurs. The guard correctly protects routes in the demo
|
|
2434
|
+
* but will let any fabricated token through.
|
|
2435
|
+
*
|
|
2436
|
+
* \u2500\u2500 PRODUCTION MIGRATION PATH \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2437
|
+
* Option A \u2014 Use the framework\u2019s built-in MetaGuard:
|
|
2438
|
+
* Set `guard: { requireAuth: true, redirectTo: '/login' }` on any
|
|
2439
|
+
* PageMeta definition. MetaGuard already reads from MetaAuthService
|
|
2440
|
+
* and handles role/permission checks declaratively.
|
|
2441
|
+
*
|
|
2442
|
+
* Option B \u2014 Keep this guard but swap the auth service:
|
|
2443
|
+
* Replace `inject(AuthService)` with `inject(MetaAuthService)` and
|
|
2444
|
+
* call `.isAuthenticated()` on it once real tokens are in flight.
|
|
2445
|
+
*
|
|
2446
|
+
* See FRAMEWORK_GUIDE.md \u00a73 for step-by-step migration instructions.
|
|
2447
|
+
*/
|
|
2448
|
+
declare const authGuard: CanActivateFn;
|
|
2449
|
+
|
|
2450
|
+
/**
|
|
2451
|
+
* HTTP Interceptor — Bearer token injection + 401 global logout.
|
|
2452
|
+
*
|
|
2453
|
+
* ── CURRENT (DEMO) BEHAVIOUR ──────────────────────────────────────────────
|
|
2454
|
+
* Reads the Bearer token from `AuthService` (the demo/mock service).
|
|
2455
|
+
* The token is a fake JWT-shaped string generated locally — it will be
|
|
2456
|
+
* rejected by any real API server that validates JWT signatures.
|
|
2457
|
+
*
|
|
2458
|
+
* ── PRODUCTION MIGRATION PATH ────────────────────────────────────────────
|
|
2459
|
+
* Option A — Swap the token source (minimal change):
|
|
2460
|
+
* Replace `authService.getToken()` with a call to `MetaAuthService.getToken()`
|
|
2461
|
+
* once you have a real login endpoint producing real JWTs.
|
|
2462
|
+
*
|
|
2463
|
+
* Option B — Remove this interceptor entirely:
|
|
2464
|
+
* Use AvoraMetaForge’s built-in auth injection via `ApiEndpointMeta.auth`.
|
|
2465
|
+
* Set `auth: { type: 'bearer', token: 'state:auth.token' }` on each endpoint
|
|
2466
|
+
* and MetaApiService will inject it automatically. No interceptor needed.
|
|
2467
|
+
*
|
|
2468
|
+
* See FRAMEWORK_GUIDE.md §3 for step-by-step instructions.
|
|
2469
|
+
*/
|
|
2470
|
+
declare const authInterceptor: HttpInterceptorFn;
|
|
2471
|
+
|
|
2472
|
+
/**
|
|
2473
|
+
* Manages runtime theming by toggling the `data-theme` attribute on the <body> element.
|
|
2474
|
+
* Allows switching brand skins without recompiling styles.
|
|
2475
|
+
*/
|
|
2476
|
+
declare class ThemeService {
|
|
2477
|
+
/** Currently active theme name */
|
|
2478
|
+
readonly currentTheme: i0.WritableSignal<string>;
|
|
2479
|
+
/** Available theme names */
|
|
2480
|
+
readonly availableThemes: ReadonlyArray<{
|
|
2481
|
+
name: string;
|
|
2482
|
+
label: string;
|
|
2483
|
+
}>;
|
|
2484
|
+
constructor();
|
|
2485
|
+
/** Switch to a named theme */
|
|
2486
|
+
setTheme(themeName: string): void;
|
|
2487
|
+
/** Cycle to the next theme */
|
|
2488
|
+
cycleTheme(): void;
|
|
2489
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ThemeService, never>;
|
|
2490
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ThemeService>;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
type NotificationType = 'success' | 'error' | 'info' | 'warning';
|
|
2494
|
+
interface Notification {
|
|
2495
|
+
id: number;
|
|
2496
|
+
type: NotificationType;
|
|
2497
|
+
message: string;
|
|
2498
|
+
timeout?: number;
|
|
2499
|
+
}
|
|
2500
|
+
declare class NotificationService {
|
|
2501
|
+
private _notifications;
|
|
2502
|
+
readonly notifications: i0.Signal<Notification[]>;
|
|
2503
|
+
private _counter;
|
|
2504
|
+
/** Add a notification to the stack */
|
|
2505
|
+
show(type: NotificationType, message: string, timeout?: number): void;
|
|
2506
|
+
success(message: string): void;
|
|
2507
|
+
error(message: string): void;
|
|
2508
|
+
info(message: string): void;
|
|
2509
|
+
warning(message: string): void;
|
|
2510
|
+
/** Remove a notification by ID */
|
|
2511
|
+
remove(id: number): void;
|
|
2512
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NotificationService, never>;
|
|
2513
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<NotificationService>;
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
/**
|
|
2517
|
+
* The Root Renderer (Traffic Controller).
|
|
2518
|
+
* Decides which layout to load based on the currentLayout signal from AppConfigService.
|
|
2519
|
+
*/
|
|
2520
|
+
declare class LayoutComponent {
|
|
2521
|
+
readonly config: AppConfigService;
|
|
2522
|
+
readonly LayoutType: typeof LayoutType;
|
|
2523
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<LayoutComponent, never>;
|
|
2524
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<LayoutComponent, "app-layout", never, {}, {}, never, never, true, never>;
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
export { APP_META_CONFIG_TOKEN, AccordionSectionComponent, ActionDispatcherService, AmfDialogHostComponent, AmfDrawerHostComponent, AppConfigService, AuthService, CardSectionComponent, ComponentRegistryService, ConditionEvaluatorService, FormRendererComponent, LayoutComponent, LayoutType, META_SECTION_CONFIG, META_SECTION_CONTEXT, MetaApiService, MetaAuthService, MetaModalHostComponent, MetaPageComponent, MetaRendererComponent, MetaRouterService, MetaStateService, NotificationService, PageHeaderSectionComponent, PluginRegistryService, RepeaterFieldComponent, StatsGridSectionComponent, StepperFormRendererComponent, TableRendererComponent, ThemeService, authGuard, authInterceptor, getAmfAuthRoutes, initializeAvoraMetaForge, metaCanDeactivateGuard, metaGuard, provideAvoraMetaForge };
|
|
2528
|
+
export type { AccordionMeta, AccordionPanelMeta, ActionMeta, ActionType, AggregateRowMeta, AlertMeta, ApiActionConfig, ApiAuthMeta, ApiEndpointMeta, ApiPaginationMeta, AppBrandingMeta, AppMeta, AuthUser, AutosaveMeta, AvoraMetaForgePlugin, BreadcrumbMeta, CacheMeta, CardMeta, CellType, ClearStateActionConfig, ColumnEditValidatorMeta, ColumnMeta, ComputeFieldMeta, ConditionMeta, ConditionOperator, ConditionalActionConfig, ConfirmActionConfig, CopyToClipboardActionConfig, CrossFieldValidatorMeta, CustomComponentMeta, DelayActionConfig, DialogConfig, DispatchMultipleActionConfig, DividerMeta, DownloadFileActionConfig, DrawerActionConfig, EmitActionConfig, EmptyStateMeta, EnvironmentConfig, FieldMeta, FieldType, FocusActionConfig, FooterLinkMeta, ForEachActionConfig, FormLayout, FormMeta, FormStepMeta, GlobalAuthMeta, GuardMeta, HtmlMeta, HttpMethod$1 as HttpMethod, IframeMeta, LayoutConfigMeta, LayoutMeta, LayoutTypeKey, LoadingActionConfig, LogActionConfig, MetaSectionComponent, ModalActionConfig, NavGroupMeta, NavItemMeta, NavigateActionConfig, Notification, NotificationType, NotifyActionConfig, OpenUrlActionConfig, OptionMeta, PageHeaderActionMeta, PageHeaderMeta, PageMeta, PaginationMeta, PatchFormActionConfig, PrintActionConfig, ReloadTableActionConfig, ResetFormActionConfig, ResolverMeta, RetryMeta, RowClassMeta, ScrollToActionConfig, SectionMeta, ServerPaginationConfig, SetStateActionConfig, SetTitleActionConfig, SpacerMeta, StatCardMeta, StateChange, StatsGridMeta, StorageActionConfig, SubmitFormActionConfig, TabMeta, TableActionMeta, TableFilterMeta, TableMeta, TabsMeta, ThemeMeta, TimelineItemMeta, TimelineMeta, ToggleClassActionConfig, TransformContextActionConfig, TransformMeta, UserProfile, ValidatorMeta };
|