@praxisui/table 1.0.0-beta.20 → 1.0.0-beta.22

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.
@@ -9077,6 +9077,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
9077
9077
  class BehaviorConfigEditorComponent {
9078
9078
  fb;
9079
9079
  config = { columns: [] };
9080
+ // Opcional: informa se há recurso remoto para ajustar defaults
9081
+ resourcePath;
9080
9082
  configChange = new EventEmitter();
9081
9083
  behaviorChange = new EventEmitter();
9082
9084
  behaviorForm;
@@ -9108,7 +9110,8 @@ class BehaviorConfigEditorComponent {
9108
9110
  this.arrayToString(pagination.pageSizeOptions || [5, 10, 25, 50]),
9109
9111
  ],
9110
9112
  showFirstLastButtons: [pagination.showFirstLastButtons !== false],
9111
- paginationStrategy: ['client'], // V2 only
9113
+ // Default adaptado: se houver resourcePath e não houver override, usar 'server'
9114
+ paginationStrategy: [this.resourcePath ? 'server' : 'client'], // V2 only
9112
9115
  paginationPosition: ['bottom'],
9113
9116
  paginationStyle: ['default'],
9114
9117
  // Sorting
@@ -9156,7 +9159,8 @@ class BehaviorConfigEditorComponent {
9156
9159
  pageSize: behavior.pagination.pageSize || 10,
9157
9160
  pageSizeOptions: this.arrayToString(behavior.pagination.pageSizeOptions || [5, 10, 25, 50]),
9158
9161
  showFirstLastButtons: behavior.pagination.showFirstLastButtons !== false,
9159
- paginationStrategy: behavior.pagination.strategy || 'client',
9162
+ // Se a estratégia não estiver definida, respeitar contexto de resourcePath
9163
+ paginationStrategy: behavior.pagination.strategy ?? (this.resourcePath ? 'server' : 'client'),
9160
9164
  paginationPosition: behavior.pagination.position || 'bottom',
9161
9165
  paginationStyle: behavior.pagination.style || 'default',
9162
9166
  });
@@ -9375,7 +9379,7 @@ class BehaviorConfigEditorComponent {
9375
9379
  .filter((n) => !isNaN(n));
9376
9380
  }
9377
9381
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: BehaviorConfigEditorComponent, deps: [{ token: i1$1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
9378
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: BehaviorConfigEditorComponent, isStandalone: true, selector: "behavior-config-editor", inputs: { config: "config" }, outputs: { configChange: "configChange", behaviorChange: "behaviorChange" }, ngImport: i0, template: `
9382
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: BehaviorConfigEditorComponent, isStandalone: true, selector: "behavior-config-editor", inputs: { config: "config", resourcePath: "resourcePath" }, outputs: { configChange: "configChange", behaviorChange: "behaviorChange" }, ngImport: i0, template: `
9379
9383
  <div class="behavior-config-container">
9380
9384
  <form [formGroup]="behaviorForm">
9381
9385
  <!-- Paginação -->
@@ -10259,6 +10263,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
10259
10263
  `, styles: [".behavior-config-container{width:100%;padding:8px}.config-section{padding:16px}.config-fields{display:flex;flex-direction:column;gap:16px;margin-top:16px}.toggle-field{display:flex;align-items:center;gap:8px}.section-icon{margin-right:8px;color:var(--mat-sys-primary)}.info-icon{font-size:18px;width:18px;height:18px;color:var(--mat-sys-on-surface-variant);cursor:help}mat-form-field{width:100%}mat-expansion-panel{margin-bottom:8px;border-radius:8px;overflow:hidden}mat-expansion-panel-header{min-height:56px}mat-panel-description{color:var(--mat-sys-on-surface-variant)}\n"] }]
10260
10264
  }], ctorParameters: () => [{ type: i1$1.FormBuilder }], propDecorators: { config: [{
10261
10265
  type: Input
10266
+ }], resourcePath: [{
10267
+ type: Input
10262
10268
  }], configChange: [{
10263
10269
  type: Output
10264
10270
  }], behaviorChange: [{
@@ -19452,7 +19458,7 @@ class PraxisTableConfigEditor {
19452
19458
  this.isBusy$.complete();
19453
19459
  }
19454
19460
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisTableConfigEditor, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$3.TableConfigService }, { token: SETTINGS_PANEL_DATA }, { token: SETTINGS_PANEL_REF, optional: true }], target: i0.ɵɵFactoryTarget.Component });
19455
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisTableConfigEditor, isStandalone: true, selector: "praxis-table-config-editor", providers: [TableConfigService], viewQueries: [{ propertyName: "behaviorEditor", first: true, predicate: BehaviorConfigEditorComponent, descendants: true }, { propertyName: "crudEditorSetter", first: true, predicate: ["crudEditorRef"], descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n <mat-icon *ngIf=\"section.icon\" [praxisIcon]=\"section.icon\"></mat-icon>\n <span>{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" style=\"display:grid; gap:12px; padding: 8px; grid-template-columns: 1fr 240px; align-items: start;\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <small style=\"opacity:.75\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria</small>\n\n <!-- Diverg\u00EAncia: idField -->\n <div *ngIf=\"idFieldDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #fff4e5; color: #8a4b00; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>warning</mat-icon>\n <div style=\"flex:1;\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span style=\"opacity:.85\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div>\n\n <!-- Diverg\u00EAncia: serverHash -->\n <div *ngIf=\"schemaHashDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #e6f4ff; color: #0b5aaa; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>info</mat-icon>\n <div style=\"flex:1;\">\n O schema no servidor foi atualizado desde a \u00FAltima sincroniza\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div>\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n <behavior-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n ></crud-integration-editor>\n\n <filter-settings\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"columnMetas\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n<div class=\"config-editor-status\" *ngIf=\"statusMessage\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n</div>\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.educational-card{margin-bottom:24px;background:var(--mat-sys-surface-container-low);border-left:4px solid var(--mat-sys-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid rgba(0,0,0,.12);background:var(--mat-sys-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--mat-sys-error)}.status-text.success{color:var(--mat-sys-primary)}@media (max-width: 768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i4$1.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: ColumnsConfigEditorComponent, selector: "columns-config-editor", inputs: ["config"], outputs: ["configChange", "columnChange"] }, { kind: "component", type: BehaviorConfigEditorComponent, selector: "behavior-config-editor", inputs: ["config"], outputs: ["configChange", "behaviorChange"] }, { kind: "component", type: HeaderAppearanceEditorComponent, selector: "header-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ToolbarActionsEditorComponent, selector: "toolbar-actions-editor", inputs: ["config"], outputs: ["configChange", "toolbarActionsChange"] }, { kind: "component", type: MessagesLocalizationEditorComponent, selector: "messages-localization-editor", inputs: ["config"], outputs: ["configChange", "messagesLocalizationChange"] }, { kind: "component", type: FilterSettingsComponent, selector: "filter-settings", inputs: ["metadata", "settings", "configKey"], outputs: ["settingsChange"] }, { kind: "component", type: CrudIntegrationEditorComponent, selector: "crud-integration-editor", inputs: ["tableId", "crudContext"] }, { kind: "component", type: ConfirmDialogAppearanceEditorComponent, selector: "confirm-dialog-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: TableRulesEditorComponent, selector: "table-rules-editor", inputs: ["config", "resourcePath", "fields", "i18nRules", "debugLogs", "debugLevel"], outputs: ["configChange"] }] });
19461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisTableConfigEditor, isStandalone: true, selector: "praxis-table-config-editor", providers: [TableConfigService], viewQueries: [{ propertyName: "behaviorEditor", first: true, predicate: BehaviorConfigEditorComponent, descendants: true }, { propertyName: "crudEditorSetter", first: true, predicate: ["crudEditorRef"], descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n <mat-icon *ngIf=\"section.icon\" [praxisIcon]=\"section.icon\"></mat-icon>\n <span>{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" style=\"display:grid; gap:12px; padding: 8px; grid-template-columns: 1fr 240px; align-items: start;\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <small style=\"opacity:.75\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria</small>\n\n <!-- Diverg\u00EAncia: idField -->\n <div *ngIf=\"idFieldDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #fff4e5; color: #8a4b00; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>warning</mat-icon>\n <div style=\"flex:1;\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span style=\"opacity:.85\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div>\n\n <!-- Diverg\u00EAncia: serverHash -->\n <div *ngIf=\"schemaHashDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #e6f4ff; color: #0b5aaa; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>info</mat-icon>\n <div style=\"flex:1;\">\n O schema no servidor foi atualizado desde a \u00FAltima sincroniza\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div>\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n <behavior-config-editor\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n ></crud-integration-editor>\n\n <filter-settings\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"columnMetas\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n<div class=\"config-editor-status\" *ngIf=\"statusMessage\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n</div>\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.educational-card{margin-bottom:24px;background:var(--mat-sys-surface-container-low);border-left:4px solid var(--mat-sys-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid rgba(0,0,0,.12);background:var(--mat-sys-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--mat-sys-error)}.status-text.success{color:var(--mat-sys-primary)}@media (max-width: 768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i4$1.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i4$1.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i4$1.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: ColumnsConfigEditorComponent, selector: "columns-config-editor", inputs: ["config"], outputs: ["configChange", "columnChange"] }, { kind: "component", type: BehaviorConfigEditorComponent, selector: "behavior-config-editor", inputs: ["config", "resourcePath"], outputs: ["configChange", "behaviorChange"] }, { kind: "component", type: HeaderAppearanceEditorComponent, selector: "header-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ToolbarActionsEditorComponent, selector: "toolbar-actions-editor", inputs: ["config"], outputs: ["configChange", "toolbarActionsChange"] }, { kind: "component", type: MessagesLocalizationEditorComponent, selector: "messages-localization-editor", inputs: ["config"], outputs: ["configChange", "messagesLocalizationChange"] }, { kind: "component", type: FilterSettingsComponent, selector: "filter-settings", inputs: ["metadata", "settings", "configKey"], outputs: ["settingsChange"] }, { kind: "component", type: CrudIntegrationEditorComponent, selector: "crud-integration-editor", inputs: ["tableId", "crudContext"] }, { kind: "component", type: ConfirmDialogAppearanceEditorComponent, selector: "confirm-dialog-appearance-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: TableRulesEditorComponent, selector: "table-rules-editor", inputs: ["config", "resourcePath", "fields", "i18nRules", "debugLogs", "debugLevel"], outputs: ["configChange"] }] });
19456
19462
  }
19457
19463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisTableConfigEditor, decorators: [{
19458
19464
  type: Component,
@@ -19475,7 +19481,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
19475
19481
  CrudIntegrationEditorComponent,
19476
19482
  ConfirmDialogAppearanceEditorComponent,
19477
19483
  TableRulesEditorComponent,
19478
- ], providers: [TableConfigService], template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n <mat-icon *ngIf=\"section.icon\" [praxisIcon]=\"section.icon\"></mat-icon>\n <span>{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" style=\"display:grid; gap:12px; padding: 8px; grid-template-columns: 1fr 240px; align-items: start;\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <small style=\"opacity:.75\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria</small>\n\n <!-- Diverg\u00EAncia: idField -->\n <div *ngIf=\"idFieldDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #fff4e5; color: #8a4b00; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>warning</mat-icon>\n <div style=\"flex:1;\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span style=\"opacity:.85\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div>\n\n <!-- Diverg\u00EAncia: serverHash -->\n <div *ngIf=\"schemaHashDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #e6f4ff; color: #0b5aaa; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>info</mat-icon>\n <div style=\"flex:1;\">\n O schema no servidor foi atualizado desde a \u00FAltima sincroniza\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div>\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n <behavior-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n ></crud-integration-editor>\n\n <filter-settings\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"columnMetas\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n<div class=\"config-editor-status\" *ngIf=\"statusMessage\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n</div>\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.educational-card{margin-bottom:24px;background:var(--mat-sys-surface-container-low);border-left:4px solid var(--mat-sys-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid rgba(0,0,0,.12);background:var(--mat-sys-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--mat-sys-error)}.status-text.success{color:var(--mat-sys-primary)}@media (max-width: 768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"] }]
19484
+ ], providers: [TableConfigService], template: " <mat-tab-group class=\"config-tabs\" [(selectedIndex)]=\"activeSectionIndex\">\n <mat-tab *ngFor=\"let section of sections\">\n <ng-template mat-tab-label>\n <mat-icon *ngIf=\"section.icon\" [praxisIcon]=\"section.icon\"></mat-icon>\n <span>{{ section.label }}</span>\n </ng-template>\n <div class=\"tab-content\">\n <ng-container [ngSwitch]=\"section.id\">\n <div *ngSwitchCase=\"'connect'\" style=\"display:grid; gap:12px; padding: 8px; grid-template-columns: 1fr 240px; align-items: start;\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Recurso</mat-label>\n <input matInput [(ngModel)]=\"resourcePath\" (ngModelChange)=\"onResourcePathChange($event)\" placeholder=\"ex.: employees\" />\n <mat-icon matSuffix>link</mat-icon>\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Chave prim\u00E1ria</mat-label>\n <input matInput [(ngModel)]=\"idField\" (ngModelChange)=\"onIdFieldChange($event)\" placeholder=\"ex.: id, uuid, codigo\" />\n <mat-icon matSuffix>fingerprint</mat-icon>\n </mat-form-field>\n <small style=\"opacity:.75\">Defina o recurso da API e, se necess\u00E1rio, a chave prim\u00E1ria</small>\n\n <!-- Diverg\u00EAncia: idField -->\n <div *ngIf=\"idFieldDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #fff4e5; color: #8a4b00; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>warning</mat-icon>\n <div style=\"flex:1;\">\n A chave prim\u00E1ria no servidor diverge da configura\u00E7\u00E3o atual.\n <span style=\"opacity:.85\">(config: {{ idField || 'id' }} | servidor: {{ serverIdField || 'id' }})</span>\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onReconcileIdField()\">Reconciliar</button>\n </div>\n\n <!-- Diverg\u00EAncia: serverHash -->\n <div *ngIf=\"schemaHashDiverges\" style=\"grid-column: 1 / -1; padding: 8px 12px; border-radius: 6px; background: #e6f4ff; color: #0b5aaa; display:flex; align-items:center; gap: 8px;\">\n <mat-icon>info</mat-icon>\n <div style=\"flex:1;\">\n O schema no servidor foi atualizado desde a \u00FAltima sincroniza\u00E7\u00E3o.\n </div>\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"onAcceptServerHash()\">Atualizar metadados</button>\n </div>\n </div>\n\n <div *ngSwitchCase=\"'overview'\" class=\"overview-grid\">\n <div class=\"overview-row\">\n <mat-form-field appearance=\"outline\" class=\"hs-field\">\n <mat-label>Scroll Horizontal</mat-label>\n <mat-select [(ngModel)]=\"horizontalScroll\" (ngModelChange)=\"onHorizontalScrollChange($event)\">\n <mat-option value=\"auto\">Auto (padr\u00E3o)</mat-option>\n <mat-option value=\"wrap\">Wrap (quebrar linhas)</mat-option>\n <mat-option value=\"none\">Host controla</mat-option>\n </mat-select>\n </mat-form-field>\n <div class=\"help small\">Controla como a tabela lida com largura horizontal e barra de rolagem.</div>\n </div>\n <behavior-config-editor\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onBehaviorConfigChange($event)\"\n (behaviorChange)=\"onBehaviorChange($event)\"\n ></behavior-config-editor>\n </div>\n\n <columns-config-editor\n *ngSwitchCase=\"'columns'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n (columnChange)=\"onColumnChange($event)\"\n ></columns-config-editor>\n\n <table-rules-editor\n *ngSwitchCase=\"'rules'\"\n [config]=\"editedConfig\"\n [resourcePath]=\"resourcePath\"\n (configChange)=\"onRulesConfigChange($event)\"\n ></table-rules-editor>\n\n <header-appearance-editor\n *ngSwitchCase=\"'header'\"\n [config]=\"editedConfig\"\n (configChange)=\"onColumnsConfigChange($event)\"\n ></header-appearance-editor>\n\n <toolbar-actions-editor\n *ngSwitchCase=\"'toolbar'\"\n [config]=\"editedConfig\"\n (configChange)=\"onToolbarActionsConfigChange($event)\"\n (toolbarActionsChange)=\"onToolbarActionsChange($event)\"\n ></toolbar-actions-editor>\n\n <!-- Aba extra para integra\u00E7\u00F5es CRUD (vis\u00EDvel quando em contexto CRUD) -->\n <crud-integration-editor\n #crudEditorRef\n *ngSwitchCase=\"'crud'\"\n [tableId]=\"crudContext?.tableId || 'default'\"\n [crudContext]=\"crudContext\"\n ></crud-integration-editor>\n\n <filter-settings\n *ngSwitchCase=\"'filters'\"\n [metadata]=\"columnMetas\"\n [settings]=\"\n editedConfig.behavior?.filtering?.advancedFilters?.settings\n \"\n (settingsChange)=\"onFilterSettingsChange($event)\"\n ></filter-settings>\n\n <messages-localization-editor\n *ngSwitchCase=\"'messages'\"\n [config]=\"editedConfig\"\n (configChange)=\"onMessagesLocalizationConfigChange($event)\"\n (messagesLocalizationChange)=\"\n onMessagesLocalizationChange($event)\n \"\n ></messages-localization-editor>\n\n <confirm-dialog-appearance-editor\n *ngSwitchCase=\"'dialogs'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n ></confirm-dialog-appearance-editor>\n\n\n <json-config-editor\n *ngSwitchCase=\"'json'\"\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n ></json-config-editor>\n </ng-container>\n </div>\n </mat-tab>\n </mat-tab-group>\n<div class=\"config-editor-status\" *ngIf=\"statusMessage\">\n <span\n class=\"status-text\"\n [class.error]=\"hasErrors\"\n [class.success]=\"hasSuccess\"\n >{{ statusMessage }}</span\n >\n</div>\n", styles: ["@charset \"UTF-8\";.config-tabs{flex:1 1 auto;display:flex;flex-direction:column}.config-tabs .mat-mdc-tab{min-width:120px}.config-tabs .mat-mdc-tab-body-wrapper,.config-tabs .mat-mdc-tab-group-container{flex:1 1 auto;min-height:0}.config-tabs .mat-mdc-tab-body-content{height:100%;min-height:0;overflow:visible}.tab-content{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;padding:8px 8px 56px;box-sizing:border-box;overflow:visible}.overview-grid{display:grid;grid-template-columns:1fr;gap:12px}.overview-grid .overview-row{display:grid;grid-template-columns:280px 1fr;align-items:end;gap:12px}.overview-grid .overview-row .help.small{opacity:.75;font-size:12px}.educational-card{margin-bottom:24px;background:var(--mat-sys-surface-container-low);border-left:4px solid var(--mat-sys-primary);flex-shrink:0}.config-editor-status{padding:12px 16px;margin-top:auto;border-top:1px solid rgba(0,0,0,.12);background:var(--mat-sys-surface-container);flex-shrink:0;position:relative}.status-text{font-size:.875rem;line-height:1.2}.status-text.error{color:var(--mat-sys-error)}.status-text.success{color:var(--mat-sys-primary)}@media (max-width: 768px){.tab-content{padding:8px}.config-editor-status{padding:12px 16px}:host{display:flex;flex-direction:column;flex:1 1 auto;min-height:0}}\n"] }]
19479
19485
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1$3.TableConfigService }, { type: undefined, decorators: [{
19480
19486
  type: Inject,
19481
19487
  args: [SETTINGS_PANEL_DATA]
@@ -23080,7 +23086,7 @@ class PraxisTable {
23080
23086
  // altField intentionally omitted; rely on initialsExpr + title attr if provided later
23081
23087
  initialsExpr,
23082
23088
  shape: 'circle',
23083
- size: 28,
23089
+ size: 32,
23084
23090
  },
23085
23091
  };
23086
23092
  // Sensible defaults for avatar column