@praxisui/settings-panel 10.0.0-rc.40 → 10.0.0-rc.42

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 CHANGED
@@ -22,6 +22,7 @@
22
22
  - Abrir editores de configuracao com UX autoral consistente
23
23
  - Padronizar `Apply`, `Save`, `Reset` e `Cancel` em flows de authoring
24
24
  - Reutilizar uma base neutra de side panel para drawers runtime do `surface.open`
25
+ - Abrir o editor global de configuracoes (`openGlobalConfigEditor(settingsPanel, opts?)`) para governar `crud`, `dynamicFields`, `table`, `dialog`, `pages.defaults` (presets de layout, tema, moldura de widget e grade padrao das paginas dinamicas) e `ai`
25
26
 
26
27
  ## Instalacao
27
28
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-26T18:09:20.136Z",
3
+ "generatedAt": "2026-11-01T13:59:56.156Z",
4
4
  "packageName": "@praxisui/settings-panel",
5
- "packageVersion": "10.0.0-rc.40",
5
+ "packageVersion": "10.0.0-rc.42",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -35,6 +35,8 @@ const PRAXIS_SETTINGS_PANEL_GLOBAL_CONFIG_EDITOR_PT_BR = {
35
35
  'Cache & Persistence': 'Cache & Persistência',
36
36
  Table: 'Tabela',
37
37
  Dialog: 'Dialog',
38
+ 'Dynamic Pages': 'Páginas Dinâmicas',
39
+ 'Global presets for layout, theme, widget shell and canvas grid': 'Presets globais de layout, tema, moldura de widgets e grade de canvas',
38
40
  'Settings saved': 'Configurações salvas',
39
41
  'Save failed.': 'Falha ao salvar configurações.',
40
42
  'Global settings': 'Configurações globais',
@@ -220,6 +222,8 @@ const PRAXIS_SETTINGS_PANEL_GLOBAL_CONFIG_EDITOR_PT_BR = {
220
222
  'Toolbar visível': 'Toolbar visível',
221
223
  'Cache & Persistência': 'Cache & Persistence',
222
224
  Tabela: 'Table',
225
+ 'Páginas Dinâmicas': 'Páginas Dinâmicas',
226
+ 'Definido pela página (sem preset forçado)': 'Definido pela página (sem preset forçado)',
223
227
  Salvar: 'Save',
224
228
  Cancelar: 'Cancel',
225
229
  Redefinir: 'Reset',
@@ -230,6 +234,8 @@ const PRAXIS_SETTINGS_PANEL_GLOBAL_CONFIG_EDITOR_EN_US = {
230
234
  'Cache & Persistence': 'Cache & Persistence',
231
235
  Table: 'Table',
232
236
  Dialog: 'Dialog',
237
+ 'Dynamic Pages': 'Dynamic Pages',
238
+ 'Global presets for layout, theme, widget shell and canvas grid': 'Global presets for layout, theme, widget shell and canvas grid',
233
239
  'Settings saved': 'Settings saved',
234
240
  'Save failed.': 'Save failed.',
235
241
  'Global settings': 'Global settings',
@@ -415,6 +421,8 @@ const PRAXIS_SETTINGS_PANEL_GLOBAL_CONFIG_EDITOR_EN_US = {
415
421
  'Toolbar visível': 'Toolbar visible',
416
422
  'Cache & Persistência': 'Cache & Persistence',
417
423
  Tabela: 'Table',
424
+ 'Páginas Dinâmicas': 'Dynamic Pages',
425
+ 'Definido pela página (sem preset forçado)': 'Page-defined (no forced preset)',
418
426
  Salvar: 'Save',
419
427
  Cancelar: 'Cancel',
420
428
  Redefinir: 'Reset',
@@ -2854,6 +2862,7 @@ class GlobalConfigAdminService {
2854
2862
  dynamicFields: this.global.getDynamicFields(),
2855
2863
  table: this.global.getTable(),
2856
2864
  dialog: this.global.getDialog(),
2865
+ pages: this.global.getPages(),
2857
2866
  ai: this.global.get('ai'),
2858
2867
  cache: this.global.get('cache'),
2859
2868
  };
@@ -3438,6 +3447,96 @@ function buildGlobalConfigFormConfig(translate = (text) => text) {
3438
3447
  { name: safeName('dialog.variants.error.actions'), label: tx('Variant error - actions (JSON array)'), controlType: FieldControlType.TEXTAREA, dataAttributes: { globalPath: 'dialog.variants.error.actions', monospace: true } },
3439
3448
  { name: safeName('dialog.variants.error.styles'), label: tx('Variant error - styles (JSON)'), controlType: FieldControlType.TEXTAREA, dataAttributes: { globalPath: 'dialog.variants.error.styles', monospace: true }, hint: tx('Example JSON: {"containerColor":"var(--md-sys-color-surface)","containerBorderColor":"var(--md-sys-color-outline-variant)","backdropColor":"var(--md-sys-color-scrim)","actionButtonRadius":"8px"}') },
3440
3449
  { name: safeName('dialog.variants.error.animation'), label: tx('Variant error - animation (JSON/boolean)'), controlType: FieldControlType.TEXTAREA, dataAttributes: { globalPath: 'dialog.variants.error.animation', monospace: true } },
3450
+ // Dynamic Pages - Defaults
3451
+ {
3452
+ name: safeName('pages.defaults.layoutPreset'),
3453
+ label: tx('Preset de layout padrão'),
3454
+ controlType: FieldControlType.SELECT,
3455
+ selectOptions: [
3456
+ { text: tx('Definido pela página (sem preset forçado)'), value: '' },
3457
+ { text: tx('KPI + Tabela Operacional (kpi-plus-table)'), value: 'kpi-plus-table' },
3458
+ { text: tx('Visão Analítica (analytics-overview)'), value: 'analytics-overview' },
3459
+ { text: tx('Master-Detail Dashboard (master-detail-dashboard)'), value: 'master-detail-dashboard' },
3460
+ { text: tx('Monitoramento Operacional (ops-monitoring)'), value: 'ops-monitoring' },
3461
+ ],
3462
+ hint: tx('Preset estrutural aplicado quando a página não define layoutPreset próprio.'),
3463
+ dataAttributes: { globalPath: 'pages.defaults.layoutPreset' },
3464
+ },
3465
+ {
3466
+ name: safeName('pages.defaults.themePreset'),
3467
+ label: tx('Preset de tema padrão da página'),
3468
+ controlType: FieldControlType.SELECT,
3469
+ selectOptions: [
3470
+ { text: tx('Workspace Equilibrado (workspace-balanced)'), value: 'workspace-balanced' },
3471
+ { text: tx('Analítico Calmo (analytics-calm)'), value: 'analytics-calm' },
3472
+ { text: tx('Monitoramento Operacional (ops-monitoring)'), value: 'ops-monitoring' },
3473
+ { text: tx('Centro de Comando Executivo (executive-command-center)'), value: 'executive-command-center' },
3474
+ ],
3475
+ hint: tx('Define densidade, superfície e atmosfera padrão das páginas dinâmicas.'),
3476
+ dataAttributes: { globalPath: 'pages.defaults.themePreset' },
3477
+ },
3478
+ {
3479
+ name: safeName('pages.defaults.shellPreset'),
3480
+ label: tx('Preset padrão de moldura (Widget Shell)'),
3481
+ controlType: FieldControlType.SELECT,
3482
+ selectOptions: [
3483
+ { text: tx('Card Integrado (integrated-card)'), value: 'integrated-card' },
3484
+ { text: tx('Card com Contorno (outlined-card)'), value: 'outlined-card' },
3485
+ { text: tx('Card Elevado (elevated-card)'), value: 'elevated-card' },
3486
+ { text: tx('Card Tonal (tonal-card)'), value: 'tonal-card' },
3487
+ { text: tx('Card Seccionado (sectioned-card)'), value: 'sectioned-card' },
3488
+ { text: tx('Sem Moldura (frameless)'), value: 'frameless' },
3489
+ { text: tx('Painel de Dados (data-panel)'), value: 'data-panel' },
3490
+ { text: tx('Painel de Gráfico (chart-panel)'), value: 'chart-panel' },
3491
+ { text: tx('Painel de Métrica (metric-panel)'), value: 'metric-panel' },
3492
+ { text: tx('Card Executivo (executive-card)'), value: 'executive-card' },
3493
+ { text: tx('Barra de Filtro (filter-bar)'), value: 'filter-bar' },
3494
+ { text: tx('Vidro Escuro (dark-glass)'), value: 'dark-glass' },
3495
+ { text: tx('Vidro Claro (glass-light)'), value: 'glass-light' },
3496
+ { text: tx('Neutro Claro (light-neutral)'), value: 'light-neutral' },
3497
+ { text: tx('Grafite (graphite)'), value: 'graphite' },
3498
+ ],
3499
+ hint: tx('Usado quando nem o widget nem o tema da página definem um preset de shell.'),
3500
+ dataAttributes: { globalPath: 'pages.defaults.shellPreset' },
3501
+ },
3502
+ {
3503
+ name: safeName('pages.defaults.columns'),
3504
+ label: tx('Colunas padrão da grade'),
3505
+ controlType: FieldControlType.INPUT,
3506
+ numericFormat: 'integer',
3507
+ min: 1,
3508
+ max: 12,
3509
+ numericStep: 1,
3510
+ hint: tx('Quantidade padrão de colunas em layouts colunares ou canvas (1 a 12).'),
3511
+ dataAttributes: { globalPath: 'pages.defaults.columns' },
3512
+ },
3513
+ {
3514
+ name: safeName('pages.defaults.gap'),
3515
+ label: tx('Espaçamento padrão entre widgets (gap)'),
3516
+ controlType: FieldControlType.INPUT,
3517
+ placeholder: '16px',
3518
+ hint: tx('Ex.: 12px, 16px, 20px, 1.25rem.'),
3519
+ dataAttributes: { globalPath: 'pages.defaults.gap' },
3520
+ },
3521
+ {
3522
+ name: safeName('pages.defaults.paddingInline'),
3523
+ label: tx('Recuo horizontal padrão (paddingInline)'),
3524
+ controlType: FieldControlType.INPUT,
3525
+ placeholder: '0px',
3526
+ hint: tx('Ex.: 0px, 16px, 24px.'),
3527
+ dataAttributes: { globalPath: 'pages.defaults.paddingInline' },
3528
+ },
3529
+ {
3530
+ name: safeName('pages.defaults.autoRows'),
3531
+ label: tx('Modo padrão de altura de linhas no Canvas'),
3532
+ controlType: FieldControlType.SELECT,
3533
+ selectOptions: [
3534
+ { text: tx('Adaptado ao conteúdo (content)'), value: 'content' },
3535
+ { text: tx('Altura de linha fixa (fixed)'), value: 'fixed' },
3536
+ ],
3537
+ hint: tx('Controla se os blocos no canvas crescem conforme o conteúdo ou seguem rowUnit fixo.'),
3538
+ dataAttributes: { globalPath: 'pages.defaults.autoRows' },
3539
+ },
3441
3540
  ];
3442
3541
  const cfg = {
3443
3542
  sections: [
@@ -3725,6 +3824,34 @@ function buildGlobalConfigFormConfig(translate = (text) => text) {
3725
3824
  },
3726
3825
  ],
3727
3826
  },
3827
+ {
3828
+ id: 'dynamic-pages',
3829
+ title: tx('Dynamic Pages'),
3830
+ rows: [
3831
+ {
3832
+ id: 'pages-row-presets',
3833
+ columns: [
3834
+ {
3835
+ id: 'pages-col-presets-1',
3836
+ fields: [
3837
+ safeName('pages.defaults.layoutPreset'),
3838
+ safeName('pages.defaults.themePreset'),
3839
+ safeName('pages.defaults.shellPreset'),
3840
+ ],
3841
+ },
3842
+ {
3843
+ id: 'pages-col-presets-2',
3844
+ fields: [
3845
+ safeName('pages.defaults.columns'),
3846
+ safeName('pages.defaults.gap'),
3847
+ safeName('pages.defaults.paddingInline'),
3848
+ safeName('pages.defaults.autoRows'),
3849
+ ],
3850
+ },
3851
+ ],
3852
+ },
3853
+ ],
3854
+ },
3728
3855
  ],
3729
3856
  actions: {
3730
3857
  placement: 'afterSections',
@@ -3773,7 +3900,7 @@ class GlobalConfigEditorComponent {
3773
3900
  currentValues = {};
3774
3901
  pathMap = {};
3775
3902
  bootstrappedSections = new Set();
3776
- allSections = ['crud', 'dynamic-fields', 'cache', 'table', 'dialog', 'ai-credentials', 'ai-model', 'ai-embedding'];
3903
+ allSections = ['crud', 'dynamic-fields', 'cache', 'table', 'dialog', 'dynamic-pages', 'ai-credentials', 'ai-model', 'ai-embedding'];
3777
3904
  // SettingsPanel integration signals
3778
3905
  isDirty$ = new BehaviorSubject(false);
3779
3906
  isValid$ = new BehaviorSubject(true);
@@ -3783,6 +3910,7 @@ class GlobalConfigEditorComponent {
3783
3910
  hostCache;
3784
3911
  hostTable;
3785
3912
  hostDialog;
3913
+ hostPages;
3786
3914
  hostAiCredentials;
3787
3915
  hostAiModel;
3788
3916
  hostAiEmbedding;
@@ -3797,7 +3925,10 @@ class GlobalConfigEditorComponent {
3797
3925
  component: 'GlobalConfigEditorComponent',
3798
3926
  };
3799
3927
  providedDynamicFormCtor = inject(GLOBAL_CONFIG_DYNAMIC_FORM_COMPONENT, { optional: true });
3800
- dynamicFormCtor = this.providedDynamicFormCtor ?? null;
3928
+ componentMetadata = inject(ComponentMetadataRegistry, { optional: true });
3929
+ dynamicFormCtor = this.providedDynamicFormCtor ??
3930
+ this.componentMetadata?.get('praxis-dynamic-form')?.component ??
3931
+ null;
3801
3932
  loggedMissingDynamicForm = false;
3802
3933
  // Guardar instância do form da seção 'dialog' para atualizar controles diretamente
3803
3934
  dialogFormInst = null;
@@ -3845,6 +3976,7 @@ class GlobalConfigEditorComponent {
3845
3976
  this.snack = snack;
3846
3977
  }
3847
3978
  async ngOnInit() {
3979
+ await this.refreshStoredConfigState();
3848
3980
  const cfg = this.admin.getEffectiveConfig();
3849
3981
  const flat = this.flatten(cfg);
3850
3982
  this.formConfig = buildGlobalConfigFormConfig(this.tx.bind(this));
@@ -3867,7 +3999,6 @@ class GlobalConfigEditorComponent {
3867
3999
  this.syncEmbeddingDefaults(false);
3868
4000
  this.ensureEmbeddingModelDefaults(false);
3869
4001
  this.ensureEmbeddingDimensionsDefaults(false);
3870
- await this.refreshStoredConfigState();
3871
4002
  // Monitor API Key changes to auto-fetch
3872
4003
  this.apiKeyChanged$.pipe(debounceTime(1500), // Wait for typing to stop
3873
4004
  distinctUntilChanged((prev, curr) => prev.apiKey === curr.apiKey && prev.provider === curr.provider), filter(({ apiKey, provider }) => this.canAutoRefreshModels(provider, apiKey))).subscribe(() => {
@@ -3957,7 +4088,12 @@ class GlobalConfigEditorComponent {
3957
4088
  }
3958
4089
  }
3959
4090
  const fms = (this.formConfig.fieldMetadata || []).filter((f) => names.has(f.name));
3960
- return { sections: [sec], fieldMetadata: fms };
4091
+ const framelessSection = { ...sec, title: '' };
4092
+ return {
4093
+ sections: [framelessSection],
4094
+ fieldMetadata: fms,
4095
+ actions: this.formConfig.actions,
4096
+ };
3961
4097
  }
3962
4098
  bootstrapDynamicForms() {
3963
4099
  if (!this.dynamicFormCtor) {
@@ -3973,6 +4109,7 @@ class GlobalConfigEditorComponent {
3973
4109
  { id: 'cache', host: this.hostCache, cfg: this.buildSectionConfig('cache') },
3974
4110
  { id: 'table', host: this.hostTable, cfg: this.buildSectionConfig('table') },
3975
4111
  { id: 'dialog', host: this.hostDialog, cfg: this.buildSectionConfig('dialog') },
4112
+ { id: 'dynamic-pages', host: this.hostPages, cfg: this.buildSectionConfig('dynamic-pages') },
3976
4113
  { id: 'ai-credentials', host: this.hostAiCredentials, cfg: this.buildSectionConfig('ai-credentials') },
3977
4114
  { id: 'ai-embedding', host: this.hostAiEmbedding, cfg: this.buildSectionConfig('ai-embedding') },
3978
4115
  ];
@@ -4441,15 +4578,23 @@ class GlobalConfigEditorComponent {
4441
4578
  }
4442
4579
  // SettingsPanel expects these methods
4443
4580
  reset() {
4444
- const flat = {};
4445
- for (const safe of Object.keys(this.initialValues))
4446
- flat[safe] = this.initialValues[safe];
4447
- for (const fm of this.formConfig.fieldMetadata || []) {
4448
- const v = flat[fm.name];
4581
+ const resetValues = {};
4582
+ for (const safe of Object.keys(this.pathMap)) {
4583
+ if (safe in this.initialValues) {
4584
+ resetValues[safe] = this.initialValues[safe];
4585
+ }
4586
+ else {
4587
+ resetValues[safe] = null;
4588
+ }
4589
+ }
4590
+ for (const fm of this.formConfig?.fieldMetadata || []) {
4591
+ const v = this.initialValues[fm.name];
4449
4592
  fm.defaultValue = v;
4450
4593
  }
4451
4594
  this.currentValues = { ...this.initialValues };
4595
+ this.patchFormsWithValues(resetValues);
4452
4596
  this.isDirty$.next(false);
4597
+ this.cdr.detectChanges();
4453
4598
  }
4454
4599
  getSettingsValue() {
4455
4600
  const flat = this.buildChangedValues();
@@ -4457,7 +4602,8 @@ class GlobalConfigEditorComponent {
4457
4602
  }
4458
4603
  async onSave() {
4459
4604
  const partial = this.getSettingsValue();
4460
- const validationMessage = this.validateCompactTableAppearancePayload(partial);
4605
+ const validationMessage = this.validateCompactTableAppearancePayload(partial) ||
4606
+ this.validatePagesDefaultsPayload(partial);
4461
4607
  if (validationMessage) {
4462
4608
  try {
4463
4609
  this.snack.open(validationMessage, undefined, { duration: 5000 });
@@ -4471,6 +4617,8 @@ class GlobalConfigEditorComponent {
4471
4617
  // Update baseline after save
4472
4618
  this.initialValues = { ...this.currentValues };
4473
4619
  this.isDirty$.next(false);
4620
+ await this.refreshStoredConfigState();
4621
+ this.cdr.detectChanges();
4474
4622
  try {
4475
4623
  this.snack.open(this.tx('Settings saved'), undefined, { duration: 2000 });
4476
4624
  }
@@ -4661,8 +4809,26 @@ class GlobalConfigEditorComponent {
4661
4809
  return this.tx('Save failed.');
4662
4810
  }
4663
4811
  normalizeFieldValue(path, value) {
4812
+ if (path === 'pages.defaults.columns') {
4813
+ if (typeof value === 'number' && Number.isFinite(value)) {
4814
+ return Math.max(1, Math.min(12, Math.round(value)));
4815
+ }
4816
+ if (typeof value === 'string') {
4817
+ const trimmed = value.trim();
4818
+ if (!trimmed)
4819
+ return null;
4820
+ const parsed = Number(trimmed);
4821
+ return Number.isFinite(parsed)
4822
+ ? Math.max(1, Math.min(12, Math.round(parsed)))
4823
+ : value;
4824
+ }
4825
+ return value;
4826
+ }
4664
4827
  if (typeof value !== 'string')
4665
4828
  return value;
4829
+ if (path === 'pages.defaults.gap' || path === 'pages.defaults.paddingInline') {
4830
+ return value.trim();
4831
+ }
4666
4832
  if (!TABLE_COMPACT_SPACING_PATHS.has(path) && !TABLE_COMPACT_FONT_SIZE_PATHS.has(path)) {
4667
4833
  return value;
4668
4834
  }
@@ -4710,6 +4876,36 @@ class GlobalConfigEditorComponent {
4710
4876
  }
4711
4877
  return null;
4712
4878
  }
4879
+ validatePagesDefaultsPayload(partial) {
4880
+ const defaults = partial?.pages?.defaults;
4881
+ if (!defaults || typeof defaults !== 'object')
4882
+ return null;
4883
+ const checks = [
4884
+ {
4885
+ path: 'pages.defaults.gap',
4886
+ label: 'pages.defaults.gap',
4887
+ value: defaults.gap,
4888
+ example: '16px',
4889
+ },
4890
+ {
4891
+ path: 'pages.defaults.paddingInline',
4892
+ label: 'pages.defaults.paddingInline',
4893
+ value: defaults.paddingInline,
4894
+ example: '0px',
4895
+ },
4896
+ ];
4897
+ for (const check of checks) {
4898
+ if (typeof check.value !== 'string')
4899
+ continue;
4900
+ const normalized = this.normalizeFieldValue(check.path, check.value);
4901
+ if (!normalized)
4902
+ continue;
4903
+ if (!TABLE_COMPACT_SPACING_REGEX.test(normalized)) {
4904
+ return `Invalid value in ${check.label}. Use a valid CSS measure, such as ${check.example}.`;
4905
+ }
4906
+ }
4907
+ return null;
4908
+ }
4713
4909
  getVariantIcon(key) {
4714
4910
  const safe = this.safeName(`dialog.variants.${key}.icon`);
4715
4911
  return this.currentValues[safe];
@@ -4809,7 +5005,7 @@ class GlobalConfigEditorComponent {
4809
5005
  return true;
4810
5006
  }
4811
5007
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: GlobalConfigEditorComponent, deps: [{ token: GlobalConfigAdminService }, { token: i2$1.MatSnackBar }], target: i0.ɵɵFactoryTarget.Component });
4812
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: GlobalConfigEditorComponent, isStandalone: true, selector: "praxis-global-config-editor", viewQueries: [{ propertyName: "hostCrud", first: true, predicate: ["hostCrud"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostFields", first: true, predicate: ["hostFields"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostCache", first: true, predicate: ["hostCache"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostTable", first: true, predicate: ["hostTable"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostDialog", first: true, predicate: ["hostDialog"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostAiCredentials", first: true, predicate: ["hostAiCredentials"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostAiModel", first: true, predicate: ["hostAiModel"], descendants: true, read: ViewContainerRef }, { propertyName: "hostAiEmbedding", first: true, predicate: ["hostAiEmbedding"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
5008
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: GlobalConfigEditorComponent, isStandalone: true, selector: "praxis-global-config-editor", viewQueries: [{ propertyName: "hostCrud", first: true, predicate: ["hostCrud"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostFields", first: true, predicate: ["hostFields"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostCache", first: true, predicate: ["hostCache"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostTable", first: true, predicate: ["hostTable"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostDialog", first: true, predicate: ["hostDialog"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostPages", first: true, predicate: ["hostPages"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostAiCredentials", first: true, predicate: ["hostAiCredentials"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "hostAiModel", first: true, predicate: ["hostAiModel"], descendants: true, read: ViewContainerRef }, { propertyName: "hostAiEmbedding", first: true, predicate: ["hostAiEmbedding"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
4813
5009
  <mat-accordion multi>
4814
5010
  <mat-expansion-panel>
4815
5011
  <mat-expansion-panel-header>
@@ -5107,8 +5303,18 @@ class GlobalConfigEditorComponent {
5107
5303
  <div class="dlg-icon-helpers__hint">{{ tx('The text field above remains editable. These buttons only help with selection/clear preview.') }}</div>
5108
5304
  </div>
5109
5305
  </mat-expansion-panel>
5306
+ <mat-expansion-panel>
5307
+ <mat-expansion-panel-header>
5308
+ <mat-panel-title>
5309
+ <mat-icon class="panel-icon">dashboard_customize</mat-icon>
5310
+ {{ tx('Dynamic Pages') }}
5311
+ </mat-panel-title>
5312
+ <mat-panel-description>{{ tx('Global presets for layout, theme, widget shell and canvas grid') }}</mat-panel-description>
5313
+ </mat-expansion-panel-header>
5314
+ <ng-template #hostPages></ng-template>
5315
+ </mat-expansion-panel>
5110
5316
  </mat-accordion>
5111
- `, isInline: true, styles: [".dlg-icon-helpers{margin:12px 16px 4px;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:var(--md-sys-shape-corner-small, 8px)}.dlg-icon-helpers__head{font-weight:600;margin-bottom:8px;opacity:.8}.dlg-icon-helpers__row{display:flex;align-items:center;gap:12px;padding:6px 0}.dlg-icon-helpers__label{text-transform:capitalize;width:96px;opacity:.8}.dlg-icon-helpers__preview{width:24px;height:24px}.dlg-icon-helpers__value{font-family:monospace;font-size:12px;opacity:.8}.dlg-icon-helpers__hint{margin-top:8px;font-size:12px;opacity:.7}.panel-icon{margin-right:12px;color:var(--md-sys-color-primary)}.ai-config-container{padding:16px;display:flex;flex-direction:column;gap:24px}.ai-config-source{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);font-size:12px;color:var(--md-sys-color-on-surface-variant);flex-wrap:wrap}.ai-config-source__meta{display:inline-flex;align-items:center;gap:8px}.ai-action-btn--clear{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);--mdc-outlined-button-container-color: var(--md-sys-color-error-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-error-container);--mdc-outlined-button-outline-color: var(--md-sys-color-error);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-error-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-error-container)}.ai-action-btn--clear:hover{background:var(--md-sys-color-error-container)}.ai-group-title{display:flex;align-items:center;gap:8px;font-weight:500;font-size:14px;color:var(--md-sys-color-primary);margin-bottom:12px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:4px}.ai-group-title mat-icon{font-size:20px;width:20px;height:20px}.ai-group ::ng-deep .form-actions,.ai-group ::ng-deep button[type=submit]{display:none!important}.ai-credentials-row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.ai-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.ai-provider-summary{display:flex;align-items:center;gap:12px;padding:8px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant);margin:8px 0 4px;flex-wrap:wrap}.ai-provider-icon{width:32px;height:32px;border-radius:var(--md-sys-shape-corner-small, 8px);border:1px solid var(--md-sys-color-outline-variant);display:flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface);color:var(--md-sys-color-primary);flex:0 0 auto}.provider-svg{width:18px;height:18px}.ai-provider-meta{display:flex;flex-direction:column;gap:2px;min-width:200px;flex:1 1 auto}.ai-provider-name{font-weight:600;font-size:13px}.ai-provider-desc{font-size:12px;opacity:.75}.ai-provider-key{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600;letter-spacing:.2px;box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2))}.ai-provider-key mat-icon{width:16px;height:16px;font-size:16px}.ai-provider-key.is-present{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary)}.ai-provider-key.is-saved{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary)}.ai-provider-key.is-missing{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-style:dashed;opacity:.9}.ai-provider-key.is-unlocked{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary)}.ai-action-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;min-width:168px;border-radius:var(--md-sys-shape-corner-medium, 12px);white-space:nowrap;background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2));transition:background-color .15s ease,box-shadow .15s ease,transform .06s ease;--mdc-outlined-button-container-color: var(--md-sys-color-secondary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-secondary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-outline-variant);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-secondary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-secondary-container)}.ai-action-btn .mat-button-wrapper,.ai-action-btn .mdc-button__label{display:inline-flex;align-items:center;gap:8px;line-height:1;height:100%}.ai-action-btn .mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.ai-action-btn .ai-action-label{display:inline-flex;align-items:center;line-height:1}.ai-action-btn .mat-progress-spinner,.ai-action-btn .btn-spinner{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.ai-action-btn:hover{background:var(--md-sys-color-secondary-container);box-shadow:var(--md-sys-elevation-level2, 0 2px 6px rgba(0,0,0,.25))}.ai-action-btn:active{transform:translateY(1px)}.ai-action-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.ai-action-btn.is-success{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary);--mdc-outlined-button-container-color: var(--md-sys-color-tertiary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-tertiary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-tertiary);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-tertiary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-tertiary-container)}.ai-action-btn.is-success:hover{background:var(--md-sys-color-tertiary-container)}.ai-action-btn:disabled{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-color:var(--md-sys-color-outline-variant);box-shadow:none;opacity:.7}.ai-form-inline{flex:1;min-width:300px}.ai-credentials-row button{margin-top:4px;height:40px}.btn-spinner{margin-right:8px}.ai-feedback{margin-top:8px;display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:var(--md-sys-shape-corner-extra-small, 4px);font-size:13px}.ai-feedback--warn{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.disabled-group{opacity:.6;pointer-events:none}.ai-model-content{display:flex;flex-direction:column;gap:8px}.ai-model-controls{display:flex;align-items:flex-start;gap:8px}.ai-model-controls ::ng-deep praxis-dynamic-form{flex:1}.ai-model-details{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-left:4px}.ai-subtext{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.ai-header-actions{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.ai-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;background:var(--md-sys-color-surface-container-low);border-radius:var(--md-sys-shape-corner-small, 8px);color:var(--md-sys-color-outline);gap:8px;text-align:center;font-size:13px}.spin{animation:spin 1s linear infinite}@keyframes spin{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i3$1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i3$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i8.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
5317
+ `, isInline: true, styles: [".dlg-icon-helpers{margin:12px 16px 4px;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:var(--md-sys-shape-corner-small, 8px)}.dlg-icon-helpers__head{font-weight:600;margin-bottom:8px;opacity:.8}.dlg-icon-helpers__row{display:flex;align-items:center;gap:12px;padding:6px 0}.dlg-icon-helpers__label{text-transform:capitalize;width:96px;opacity:.8}.dlg-icon-helpers__preview{width:24px;height:24px}.dlg-icon-helpers__value{font-family:monospace;font-size:12px;opacity:.8}.dlg-icon-helpers__hint{margin-top:8px;font-size:12px;opacity:.7}.panel-icon{margin-right:12px;color:var(--md-sys-color-primary);flex-shrink:0}:host ::ng-deep .mat-expansion-panel-header{height:auto!important;min-height:54px;padding-block:10px}:host ::ng-deep .mat-expansion-panel-header-title,:host ::ng-deep .mat-expansion-panel-header-description{line-height:1.35}:host ::ng-deep .mat-expansion-panel-body .form-section{border:none;background:transparent;box-shadow:none;padding:4px 0 0}@media(max-width:560px){:host ::ng-deep .mat-expansion-panel-header .mat-content{flex-direction:column;align-items:flex-start;gap:4px}:host ::ng-deep .mat-expansion-panel-header-title,:host ::ng-deep .mat-expansion-panel-header-description{margin-right:0}}.ai-config-container{padding:16px;display:flex;flex-direction:column;gap:24px}.ai-config-source{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);font-size:12px;color:var(--md-sys-color-on-surface-variant);flex-wrap:wrap}.ai-config-source__meta{display:inline-flex;align-items:center;gap:8px}.ai-action-btn--clear{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);--mdc-outlined-button-container-color: var(--md-sys-color-error-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-error-container);--mdc-outlined-button-outline-color: var(--md-sys-color-error);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-error-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-error-container)}.ai-action-btn--clear:hover{background:var(--md-sys-color-error-container)}.ai-group-title{display:flex;align-items:center;gap:8px;font-weight:500;font-size:14px;color:var(--md-sys-color-primary);margin-bottom:12px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:4px}.ai-group-title mat-icon{font-size:20px;width:20px;height:20px}.ai-group ::ng-deep .form-actions,.ai-group ::ng-deep button[type=submit]{display:none!important}.ai-credentials-row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.ai-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.ai-provider-summary{display:flex;align-items:center;gap:12px;padding:8px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant);margin:8px 0 4px;flex-wrap:wrap}.ai-provider-icon{width:32px;height:32px;border-radius:var(--md-sys-shape-corner-small, 8px);border:1px solid var(--md-sys-color-outline-variant);display:flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface);color:var(--md-sys-color-primary);flex:0 0 auto}.provider-svg{width:18px;height:18px}.ai-provider-meta{display:flex;flex-direction:column;gap:2px;min-width:200px;flex:1 1 auto}.ai-provider-name{font-weight:600;font-size:13px}.ai-provider-desc{font-size:12px;opacity:.75}.ai-provider-key{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600;letter-spacing:.2px;box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2))}.ai-provider-key mat-icon{width:16px;height:16px;font-size:16px}.ai-provider-key.is-present{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary)}.ai-provider-key.is-saved{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary)}.ai-provider-key.is-missing{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-style:dashed;opacity:.9}.ai-provider-key.is-unlocked{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary)}.ai-action-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;min-width:168px;border-radius:var(--md-sys-shape-corner-medium, 12px);white-space:nowrap;background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2));transition:background-color .15s ease,box-shadow .15s ease,transform .06s ease;--mdc-outlined-button-container-color: var(--md-sys-color-secondary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-secondary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-outline-variant);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-secondary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-secondary-container)}.ai-action-btn .mat-button-wrapper,.ai-action-btn .mdc-button__label{display:inline-flex;align-items:center;gap:8px;line-height:1;height:100%}.ai-action-btn .mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.ai-action-btn .ai-action-label{display:inline-flex;align-items:center;line-height:1}.ai-action-btn .mat-progress-spinner,.ai-action-btn .btn-spinner{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.ai-action-btn:hover{background:var(--md-sys-color-secondary-container);box-shadow:var(--md-sys-elevation-level2, 0 2px 6px rgba(0,0,0,.25))}.ai-action-btn:active{transform:translateY(1px)}.ai-action-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.ai-action-btn.is-success{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary);--mdc-outlined-button-container-color: var(--md-sys-color-tertiary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-tertiary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-tertiary);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-tertiary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-tertiary-container)}.ai-action-btn.is-success:hover{background:var(--md-sys-color-tertiary-container)}.ai-action-btn:disabled{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-color:var(--md-sys-color-outline-variant);box-shadow:none;opacity:.7}.ai-form-inline{flex:1;min-width:300px}.ai-credentials-row button{margin-top:4px;height:40px}.btn-spinner{margin-right:8px}.ai-feedback{margin-top:8px;display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:var(--md-sys-shape-corner-extra-small, 4px);font-size:13px}.ai-feedback--warn{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.disabled-group{opacity:.6;pointer-events:none}.ai-model-content{display:flex;flex-direction:column;gap:8px}.ai-model-controls{display:flex;align-items:flex-start;gap:8px}.ai-model-controls ::ng-deep praxis-dynamic-form{flex:1}.ai-model-details{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-left:4px}.ai-subtext{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.ai-header-actions{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.ai-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;background:var(--md-sys-color-surface-container-low);border-radius:var(--md-sys-shape-corner-small, 8px);color:var(--md-sys-color-outline);gap:8px;text-align:center;font-size:13px}.spin{animation:spin 1s linear infinite}@keyframes spin{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: MatSnackBarModule }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i3$1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i3$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i3$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i3$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i3$1.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i8.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }] });
5112
5318
  }
5113
5319
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: GlobalConfigEditorComponent, decorators: [{
5114
5320
  type: Component,
@@ -5410,8 +5616,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5410
5616
  <div class="dlg-icon-helpers__hint">{{ tx('The text field above remains editable. These buttons only help with selection/clear preview.') }}</div>
5411
5617
  </div>
5412
5618
  </mat-expansion-panel>
5619
+ <mat-expansion-panel>
5620
+ <mat-expansion-panel-header>
5621
+ <mat-panel-title>
5622
+ <mat-icon class="panel-icon">dashboard_customize</mat-icon>
5623
+ {{ tx('Dynamic Pages') }}
5624
+ </mat-panel-title>
5625
+ <mat-panel-description>{{ tx('Global presets for layout, theme, widget shell and canvas grid') }}</mat-panel-description>
5626
+ </mat-expansion-panel-header>
5627
+ <ng-template #hostPages></ng-template>
5628
+ </mat-expansion-panel>
5413
5629
  </mat-accordion>
5414
- `, styles: [".dlg-icon-helpers{margin:12px 16px 4px;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:var(--md-sys-shape-corner-small, 8px)}.dlg-icon-helpers__head{font-weight:600;margin-bottom:8px;opacity:.8}.dlg-icon-helpers__row{display:flex;align-items:center;gap:12px;padding:6px 0}.dlg-icon-helpers__label{text-transform:capitalize;width:96px;opacity:.8}.dlg-icon-helpers__preview{width:24px;height:24px}.dlg-icon-helpers__value{font-family:monospace;font-size:12px;opacity:.8}.dlg-icon-helpers__hint{margin-top:8px;font-size:12px;opacity:.7}.panel-icon{margin-right:12px;color:var(--md-sys-color-primary)}.ai-config-container{padding:16px;display:flex;flex-direction:column;gap:24px}.ai-config-source{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);font-size:12px;color:var(--md-sys-color-on-surface-variant);flex-wrap:wrap}.ai-config-source__meta{display:inline-flex;align-items:center;gap:8px}.ai-action-btn--clear{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);--mdc-outlined-button-container-color: var(--md-sys-color-error-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-error-container);--mdc-outlined-button-outline-color: var(--md-sys-color-error);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-error-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-error-container)}.ai-action-btn--clear:hover{background:var(--md-sys-color-error-container)}.ai-group-title{display:flex;align-items:center;gap:8px;font-weight:500;font-size:14px;color:var(--md-sys-color-primary);margin-bottom:12px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:4px}.ai-group-title mat-icon{font-size:20px;width:20px;height:20px}.ai-group ::ng-deep .form-actions,.ai-group ::ng-deep button[type=submit]{display:none!important}.ai-credentials-row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.ai-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.ai-provider-summary{display:flex;align-items:center;gap:12px;padding:8px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant);margin:8px 0 4px;flex-wrap:wrap}.ai-provider-icon{width:32px;height:32px;border-radius:var(--md-sys-shape-corner-small, 8px);border:1px solid var(--md-sys-color-outline-variant);display:flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface);color:var(--md-sys-color-primary);flex:0 0 auto}.provider-svg{width:18px;height:18px}.ai-provider-meta{display:flex;flex-direction:column;gap:2px;min-width:200px;flex:1 1 auto}.ai-provider-name{font-weight:600;font-size:13px}.ai-provider-desc{font-size:12px;opacity:.75}.ai-provider-key{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600;letter-spacing:.2px;box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2))}.ai-provider-key mat-icon{width:16px;height:16px;font-size:16px}.ai-provider-key.is-present{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary)}.ai-provider-key.is-saved{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary)}.ai-provider-key.is-missing{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-style:dashed;opacity:.9}.ai-provider-key.is-unlocked{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary)}.ai-action-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;min-width:168px;border-radius:var(--md-sys-shape-corner-medium, 12px);white-space:nowrap;background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2));transition:background-color .15s ease,box-shadow .15s ease,transform .06s ease;--mdc-outlined-button-container-color: var(--md-sys-color-secondary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-secondary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-outline-variant);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-secondary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-secondary-container)}.ai-action-btn .mat-button-wrapper,.ai-action-btn .mdc-button__label{display:inline-flex;align-items:center;gap:8px;line-height:1;height:100%}.ai-action-btn .mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.ai-action-btn .ai-action-label{display:inline-flex;align-items:center;line-height:1}.ai-action-btn .mat-progress-spinner,.ai-action-btn .btn-spinner{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.ai-action-btn:hover{background:var(--md-sys-color-secondary-container);box-shadow:var(--md-sys-elevation-level2, 0 2px 6px rgba(0,0,0,.25))}.ai-action-btn:active{transform:translateY(1px)}.ai-action-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.ai-action-btn.is-success{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary);--mdc-outlined-button-container-color: var(--md-sys-color-tertiary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-tertiary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-tertiary);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-tertiary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-tertiary-container)}.ai-action-btn.is-success:hover{background:var(--md-sys-color-tertiary-container)}.ai-action-btn:disabled{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-color:var(--md-sys-color-outline-variant);box-shadow:none;opacity:.7}.ai-form-inline{flex:1;min-width:300px}.ai-credentials-row button{margin-top:4px;height:40px}.btn-spinner{margin-right:8px}.ai-feedback{margin-top:8px;display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:var(--md-sys-shape-corner-extra-small, 4px);font-size:13px}.ai-feedback--warn{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.disabled-group{opacity:.6;pointer-events:none}.ai-model-content{display:flex;flex-direction:column;gap:8px}.ai-model-controls{display:flex;align-items:flex-start;gap:8px}.ai-model-controls ::ng-deep praxis-dynamic-form{flex:1}.ai-model-details{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-left:4px}.ai-subtext{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.ai-header-actions{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.ai-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;background:var(--md-sys-color-surface-container-low);border-radius:var(--md-sys-shape-corner-small, 8px);color:var(--md-sys-color-outline);gap:8px;text-align:center;font-size:13px}.spin{animation:spin 1s linear infinite}@keyframes spin{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}\n"] }]
5630
+ `, styles: [".dlg-icon-helpers{margin:12px 16px 4px;padding:12px;border:1px dashed var(--md-sys-color-outline-variant);border-radius:var(--md-sys-shape-corner-small, 8px)}.dlg-icon-helpers__head{font-weight:600;margin-bottom:8px;opacity:.8}.dlg-icon-helpers__row{display:flex;align-items:center;gap:12px;padding:6px 0}.dlg-icon-helpers__label{text-transform:capitalize;width:96px;opacity:.8}.dlg-icon-helpers__preview{width:24px;height:24px}.dlg-icon-helpers__value{font-family:monospace;font-size:12px;opacity:.8}.dlg-icon-helpers__hint{margin-top:8px;font-size:12px;opacity:.7}.panel-icon{margin-right:12px;color:var(--md-sys-color-primary);flex-shrink:0}:host ::ng-deep .mat-expansion-panel-header{height:auto!important;min-height:54px;padding-block:10px}:host ::ng-deep .mat-expansion-panel-header-title,:host ::ng-deep .mat-expansion-panel-header-description{line-height:1.35}:host ::ng-deep .mat-expansion-panel-body .form-section{border:none;background:transparent;box-shadow:none;padding:4px 0 0}@media(max-width:560px){:host ::ng-deep .mat-expansion-panel-header .mat-content{flex-direction:column;align-items:flex-start;gap:4px}:host ::ng-deep .mat-expansion-panel-header-title,:host ::ng-deep .mat-expansion-panel-header-description{margin-right:0}}.ai-config-container{padding:16px;display:flex;flex-direction:column;gap:24px}.ai-config-source{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);border:1px dashed var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-low);font-size:12px;color:var(--md-sys-color-on-surface-variant);flex-wrap:wrap}.ai-config-source__meta{display:inline-flex;align-items:center;gap:8px}.ai-action-btn--clear{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);--mdc-outlined-button-container-color: var(--md-sys-color-error-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-error-container);--mdc-outlined-button-outline-color: var(--md-sys-color-error);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-error-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-error-container)}.ai-action-btn--clear:hover{background:var(--md-sys-color-error-container)}.ai-group-title{display:flex;align-items:center;gap:8px;font-weight:500;font-size:14px;color:var(--md-sys-color-primary);margin-bottom:12px;border-bottom:1px solid var(--md-sys-color-outline-variant);padding-bottom:4px}.ai-group-title mat-icon{font-size:20px;width:20px;height:20px}.ai-group ::ng-deep .form-actions,.ai-group ::ng-deep button[type=submit]{display:none!important}.ai-credentials-row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.ai-group-header{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.ai-provider-summary{display:flex;align-items:center;gap:12px;padding:8px 12px;border-radius:var(--md-sys-shape-corner-medium, 10px);background:var(--md-sys-color-surface-variant);border:1px solid var(--md-sys-color-outline-variant);margin:8px 0 4px;flex-wrap:wrap}.ai-provider-icon{width:32px;height:32px;border-radius:var(--md-sys-shape-corner-small, 8px);border:1px solid var(--md-sys-color-outline-variant);display:flex;align-items:center;justify-content:center;background:var(--md-sys-color-surface);color:var(--md-sys-color-primary);flex:0 0 auto}.provider-svg{width:18px;height:18px}.ai-provider-meta{display:flex;flex-direction:column;gap:2px;min-width:200px;flex:1 1 auto}.ai-provider-name{font-weight:600;font-size:13px}.ai-provider-desc{font-size:12px;opacity:.75}.ai-provider-key{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container-lowest);color:var(--md-sys-color-on-surface-variant);font-size:11px;font-weight:600;letter-spacing:.2px;box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2))}.ai-provider-key mat-icon{width:16px;height:16px;font-size:16px}.ai-provider-key.is-present{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary)}.ai-provider-key.is-saved{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary)}.ai-provider-key.is-missing{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-style:dashed;opacity:.9}.ai-provider-key.is-unlocked{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary)}.ai-action-btn{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px;min-width:168px;border-radius:var(--md-sys-shape-corner-medium, 12px);white-space:nowrap;background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-outline-variant);box-shadow:var(--md-sys-elevation-level1, 0 1px 2px rgba(0,0,0,.2));transition:background-color .15s ease,box-shadow .15s ease,transform .06s ease;--mdc-outlined-button-container-color: var(--md-sys-color-secondary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-secondary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-outline-variant);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-secondary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-secondary-container)}.ai-action-btn .mat-button-wrapper,.ai-action-btn .mdc-button__label{display:inline-flex;align-items:center;gap:8px;line-height:1;height:100%}.ai-action-btn .mat-icon{width:18px;height:18px;font-size:18px;line-height:18px}.ai-action-btn .ai-action-label{display:inline-flex;align-items:center;line-height:1}.ai-action-btn .mat-progress-spinner,.ai-action-btn .btn-spinner{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.ai-action-btn:hover{background:var(--md-sys-color-secondary-container);box-shadow:var(--md-sys-elevation-level2, 0 2px 6px rgba(0,0,0,.25))}.ai-action-btn:active{transform:translateY(1px)}.ai-action-btn:focus-visible{outline:2px solid var(--md-sys-color-primary);outline-offset:2px}.ai-action-btn.is-success{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container);border-color:var(--md-sys-color-tertiary);--mdc-outlined-button-container-color: var(--md-sys-color-tertiary-container);--mdc-outlined-button-label-text-color: var(--md-sys-color-on-tertiary-container);--mdc-outlined-button-outline-color: var(--md-sys-color-tertiary);--mat-mdc-button-persistent-ripple-color: var(--md-sys-color-on-tertiary-container);--mat-mdc-button-ripple-color: var(--md-sys-color-on-tertiary-container)}.ai-action-btn.is-success:hover{background:var(--md-sys-color-tertiary-container)}.ai-action-btn:disabled{background:var(--md-sys-color-surface-container-low);color:var(--md-sys-color-on-surface-variant);border-color:var(--md-sys-color-outline-variant);box-shadow:none;opacity:.7}.ai-form-inline{flex:1;min-width:300px}.ai-credentials-row button{margin-top:4px;height:40px}.btn-spinner{margin-right:8px}.ai-feedback{margin-top:8px;display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-radius:var(--md-sys-shape-corner-extra-small, 4px);font-size:13px}.ai-feedback--warn{background:var(--md-sys-color-tertiary-container);color:var(--md-sys-color-on-tertiary-container)}.disabled-group{opacity:.6;pointer-events:none}.ai-model-content{display:flex;flex-direction:column;gap:8px}.ai-model-controls{display:flex;align-items:flex-start;gap:8px}.ai-model-controls ::ng-deep praxis-dynamic-form{flex:1}.ai-model-details{font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-left:4px}.ai-subtext{font-size:12px;color:var(--md-sys-color-on-surface-variant)}.ai-header-actions{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.ai-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;background:var(--md-sys-color-surface-container-low);border-radius:var(--md-sys-shape-corner-small, 8px);color:var(--md-sys-color-outline);gap:8px;text-align:center;font-size:13px}.spin{animation:spin 1s linear infinite}@keyframes spin{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}\n"] }]
5415
5631
  }], ctorParameters: () => [{ type: GlobalConfigAdminService }, { type: i2$1.MatSnackBar }], propDecorators: { hostCrud: [{
5416
5632
  type: ViewChild,
5417
5633
  args: ['hostCrud', { read: ViewContainerRef, static: true }]
@@ -5427,6 +5643,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5427
5643
  }], hostDialog: [{
5428
5644
  type: ViewChild,
5429
5645
  args: ['hostDialog', { read: ViewContainerRef, static: true }]
5646
+ }], hostPages: [{
5647
+ type: ViewChild,
5648
+ args: ['hostPages', { read: ViewContainerRef, static: true }]
5430
5649
  }], hostAiCredentials: [{
5431
5650
  type: ViewChild,
5432
5651
  args: ['hostAiCredentials', { read: ViewContainerRef, static: true }]
@@ -5444,10 +5663,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
5444
5663
  * openGlobalConfigEditor(settings);
5445
5664
  */
5446
5665
  function openGlobalConfigEditor(settings, opts) {
5447
- settings.open({
5666
+ return settings.open({
5448
5667
  id: opts?.id ?? 'global-config',
5449
5668
  title: opts?.title,
5450
5669
  titleIcon: opts?.titleIcon ?? 'tune',
5670
+ owner: opts?.owner,
5451
5671
  content: { component: GlobalConfigEditorComponent, inputs: {} },
5452
5672
  });
5453
5673
  }
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@praxisui/settings-panel",
3
- "version": "10.0.0-rc.40",
3
+ "version": "10.0.0-rc.42",
4
4
  "description": "Settings panel for Praxis UI libraries: open editors for configuration at runtime and persist settings.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/cdk": "^21.0.0",
9
9
  "@angular/material": "^21.0.0",
10
- "@praxisui/ai": "^10.0.0-rc.40",
11
- "@praxisui/core": "^10.0.0-rc.40",
12
- "@praxisui/dynamic-fields": "^10.0.0-rc.40",
10
+ "@praxisui/ai": "^10.0.0-rc.42",
11
+ "@praxisui/core": "^10.0.0-rc.42",
12
+ "@praxisui/dynamic-fields": "^10.0.0-rc.42",
13
13
  "rxjs": "~7.8.0"
14
14
  },
15
15
  "dependencies": {
@@ -651,8 +651,9 @@ interface GlobalConfigEditorState {
651
651
  crud: NonNullable<GlobalConfig['crud']>;
652
652
  dynamicFields: NonNullable<GlobalConfig['dynamicFields']>;
653
653
  table: NonNullable<GlobalConfig['table']>;
654
+ pages?: NonNullable<GlobalConfig['pages']>;
654
655
  }
655
- type GlobalConfigEditorGroup = 'CRUD' | 'Dynamic Fields' | 'Table';
656
+ type GlobalConfigEditorGroup = 'CRUD' | 'Dynamic Fields' | 'Table' | 'Dynamic Pages';
656
657
  interface GlobalConfigEditorOption<T = any> {
657
658
  label: string;
658
659
  value: T;
@@ -696,6 +697,7 @@ declare class GlobalConfigEditorComponent implements OnInit, AfterViewInit {
696
697
  hostCache: ViewContainerRef;
697
698
  hostTable: ViewContainerRef;
698
699
  hostDialog: ViewContainerRef;
700
+ hostPages: ViewContainerRef;
699
701
  hostAiCredentials: ViewContainerRef;
700
702
  hostAiModel: ViewContainerRef;
701
703
  hostAiEmbedding: ViewContainerRef;
@@ -707,6 +709,7 @@ declare class GlobalConfigEditorComponent implements OnInit, AfterViewInit {
707
709
  private readonly logger;
708
710
  private readonly logContext;
709
711
  private readonly providedDynamicFormCtor;
712
+ private readonly componentMetadata;
710
713
  private dynamicFormCtor;
711
714
  private loggedMissingDynamicForm;
712
715
  private dialogFormInst;
@@ -787,6 +790,7 @@ declare class GlobalConfigEditorComponent implements OnInit, AfterViewInit {
787
790
  private resolveSaveErrorMessage;
788
791
  private normalizeFieldValue;
789
792
  private validateCompactTableAppearancePayload;
793
+ private validatePagesDefaultsPayload;
790
794
  getVariantIcon(key: string): string | undefined;
791
795
  pickVariantIcon(key: string): Promise<void>;
792
796
  clearVariantIcon(key: string): void;
@@ -812,6 +816,7 @@ type OpenGlobalConfigOptions = {
812
816
  id?: string;
813
817
  title?: string;
814
818
  titleIcon?: string;
819
+ owner?: DestroyRef;
815
820
  tx?: (text: string, params?: Record<string, string | number | boolean | null | undefined>) => string;
816
821
  };
817
822
  /**
@@ -819,7 +824,7 @@ type OpenGlobalConfigOptions = {
819
824
  * Usage:
820
825
  * openGlobalConfigEditor(settings);
821
826
  */
822
- declare function openGlobalConfigEditor(settings: SettingsPanelService, opts?: OpenGlobalConfigOptions): void;
827
+ declare function openGlobalConfigEditor(settings: SettingsPanelService, opts?: OpenGlobalConfigOptions): SettingsPanelRef;
823
828
 
824
829
  /**
825
830
  * Capabilities catalog for SettingsPanelConfig.