@praxisui/dynamic-form 1.0.0-beta.18 → 1.0.0-beta.19
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.
|
@@ -34,7 +34,7 @@ import * as i9 from '@angular/material/select';
|
|
|
34
34
|
import { MatSelectModule } from '@angular/material/select';
|
|
35
35
|
import * as i7 from '@angular/material/input';
|
|
36
36
|
import { MatInputModule } from '@angular/material/input';
|
|
37
|
-
import * as
|
|
37
|
+
import * as i11 from '@angular/material/checkbox';
|
|
38
38
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
39
39
|
import * as i6$2 from '@angular/material/slide-toggle';
|
|
40
40
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
@@ -4071,6 +4071,14 @@ class PraxisDynamicFormConfigEditor {
|
|
|
4071
4071
|
labelAlign: 'start',
|
|
4072
4072
|
valueAlign: 'start',
|
|
4073
4073
|
};
|
|
4074
|
+
/** Ensure hints object exists (normalized upstream) */
|
|
4075
|
+
ensureHints() {
|
|
4076
|
+
const c = this.editedConfig;
|
|
4077
|
+
if (!c.hints) {
|
|
4078
|
+
// Minimal fallback: seed with empty shape; normalize upstream will fill defaults on save
|
|
4079
|
+
c.hints = { dataModes: { create: '', edit: '', view: '' }, uiModes: { presentation: '', readonly: '', disabled: '', visible: '' } };
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4074
4082
|
// Schema verification preferences (persisted outside FormConfig)
|
|
4075
4083
|
schemaPrefs = {
|
|
4076
4084
|
notifyIfOutdated: 'both',
|
|
@@ -4174,6 +4182,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
4174
4182
|
this.isBusy$.next(false);
|
|
4175
4183
|
}
|
|
4176
4184
|
}
|
|
4185
|
+
// Public: referenced in template for (ngModelChange) handlers
|
|
4177
4186
|
updateDirtyState(reason = 'unknown') {
|
|
4178
4187
|
// Verificar se há alterações em relação à configuração inicial
|
|
4179
4188
|
const a = this.stripLegacy(structuredClone(this.initialConfig));
|
|
@@ -4230,6 +4239,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
4230
4239
|
// (Resumo/ações rápidas removidos da aba Geral conforme orientação)
|
|
4231
4240
|
onJsonConfigChange(newConfig) {
|
|
4232
4241
|
this.editedConfig = this.stripLegacy(newConfig);
|
|
4242
|
+
this.ensureHints();
|
|
4233
4243
|
try {
|
|
4234
4244
|
console.debug('[FormConfigEditor] onJsonConfigChange()', { sections: this.editedConfig.sections?.length || 0 });
|
|
4235
4245
|
}
|
|
@@ -4250,6 +4260,7 @@ class PraxisDynamicFormConfigEditor {
|
|
|
4250
4260
|
}
|
|
4251
4261
|
onConfigChange(newConfig) {
|
|
4252
4262
|
this.editedConfig = this.stripLegacy(newConfig);
|
|
4263
|
+
this.ensureHints();
|
|
4253
4264
|
try {
|
|
4254
4265
|
console.debug('[FormConfigEditor] onConfigChange()', { sections: newConfig.sections?.length || 0 });
|
|
4255
4266
|
}
|
|
@@ -4371,8 +4382,20 @@ class PraxisDynamicFormConfigEditor {
|
|
|
4371
4382
|
}
|
|
4372
4383
|
return copy;
|
|
4373
4384
|
}
|
|
4385
|
+
// UI handlers
|
|
4386
|
+
restoreHintsDefaults() {
|
|
4387
|
+
try {
|
|
4388
|
+
const current = this.editedConfig;
|
|
4389
|
+
// Defaults are injected by normalization on save/apply; keep a local reset to blank to let defaults win.
|
|
4390
|
+
current.hints = undefined;
|
|
4391
|
+
// Keep JSON editor in sync
|
|
4392
|
+
this.jsonEditor?.updateJsonFromConfig(this.editedConfig);
|
|
4393
|
+
this.updateDirtyState('hints-restore');
|
|
4394
|
+
}
|
|
4395
|
+
catch { }
|
|
4396
|
+
}
|
|
4374
4397
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicFormConfigEditor, deps: [{ token: CONFIG_STORAGE }, { token: FormConfigService }, { token: SETTINGS_PANEL_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
4375
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatCheckboxModule }, { kind: "component", type: i10.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i9$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i9$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["config", "initialRules"], outputs: ["rulesChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }] });
|
|
4398
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.4", type: PraxisDynamicFormConfigEditor, isStandalone: true, selector: "praxis-dynamic-form-config-editor", providers: [FormConfigService], viewQueries: [{ propertyName: "jsonEditor", first: true, predicate: JsonConfigEditorComponent, descendants: true }], ngImport: i0, template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Dicas e Tooltips\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Dicas dos Modos</h3>\n <p class=\"text-caption\">Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.</p>\n\n <div class=\"grid-2-cols\">\n <section>\n <h4>Modos de dados</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Criar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\" (ngModelChange)=\"updateDirtyState('hints-data-create')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Editar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\" (ngModelChange)=\"updateDirtyState('hints-data-edit')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Visualizar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\" (ngModelChange)=\"updateDirtyState('hints-data-view')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>Modos de UI</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Apresenta\u00E7\u00E3o</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\" (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Leitura (readonly)</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\" (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Desabilitado</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\" (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Vis\u00EDvel</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\" (ngModelChange)=\"updateDirtyState('hints-ui-visible')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n Restaurar padr\u00F5es\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i6$3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i6$3.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: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i8.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i8.MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.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: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i9.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: i9.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: MatCheckboxModule }, { kind: "component", type: i11.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$2.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatButtonToggleModule }, { kind: "directive", type: i9$1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i9$1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: JsonConfigEditorComponent, selector: "form-json-config-editor", inputs: ["config"], outputs: ["configChange", "validationChange", "editorEvent"] }, { kind: "component", type: LayoutEditorComponent, selector: "praxis-layout-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: BehaviorEditorComponent, selector: "praxis-behavior-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: ActionsEditorComponent$1, selector: "praxis-actions-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: MessagesEditorComponent, selector: "praxis-messages-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: HooksEditorComponent, selector: "praxis-hooks-editor", inputs: ["config"], outputs: ["configChange"] }, { kind: "component", type: PraxisVisualBuilder, selector: "praxis-visual-builder", inputs: ["config", "initialRules"], outputs: ["rulesChanged", "exportRequested", "importRequested"] }, { kind: "component", type: CascadeManagerTabComponent, selector: "praxis-cascade-manager-tab", inputs: ["fields", "connections"], outputs: ["apply", "cancel"] }] });
|
|
4376
4399
|
}
|
|
4377
4400
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: PraxisDynamicFormConfigEditor, decorators: [{
|
|
4378
4401
|
type: Component,
|
|
@@ -4382,6 +4405,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
4382
4405
|
MatTabsModule,
|
|
4383
4406
|
MatIconModule,
|
|
4384
4407
|
MatCardModule,
|
|
4408
|
+
MatButtonModule,
|
|
4385
4409
|
MatFormFieldModule,
|
|
4386
4410
|
MatSelectModule,
|
|
4387
4411
|
MatInputModule,
|
|
@@ -4396,7 +4420,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImpor
|
|
|
4396
4420
|
HooksEditorComponent,
|
|
4397
4421
|
PraxisVisualBuilder,
|
|
4398
4422
|
CascadeManagerTabComponent,
|
|
4399
|
-
], providers: [FormConfigService], template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"] }]
|
|
4423
|
+
], providers: [FormConfigService], template: " <mat-tab-group class=\"config-tabs\">\n <mat-tab label=\"Geral\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Modo do formul\u00E1rio (dados)</mat-label>\n <mat-select [(ngModel)]=\"inputMode\">\n <mat-option value=\"create\">create</mat-option>\n <mat-option value=\"edit\">edit</mat-option>\n <mat-option value=\"view\">view</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <p class=\"hint\">\n O <b>mode</b> controla o comportamento de dados (create/edit/view). J\u00E1 o <b>editModeEnabled</b> controla apenas a\n customiza\u00E7\u00E3o do layout (canvas) e \u00E9 independente do <b>mode</b>.\n </p>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Verifica\u00E7\u00E3o de Schema\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <div class=\"form-grid\">\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Notificar quando desatualizado</mat-label>\n <mat-select [(ngModel)]=\"schemaPrefs.notifyIfOutdated\">\n <mat-option value=\"both\">Banner + Snackbar</mat-option>\n <mat-option value=\"inline\">Somente Banner</mat-option>\n <mat-option value=\"snackbar\">Somente Snackbar</mat-option>\n <mat-option value=\"none\">Nenhum</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Soneca (ms)</mat-label>\n <input matInput type=\"number\" [(ngModel)]=\"schemaPrefs.snoozeMs\" />\n </mat-form-field>\n </div>\n <div class=\"form-row\">\n <mat-slide-toggle [(ngModel)]=\"schemaPrefs.autoOpenSettingsOnOutdated\">Abrir configura\u00E7\u00F5es automaticamente</mat-slide-toggle>\n </div>\n <div class=\"form-row\" *ngIf=\"serverMeta\">\n <div class=\"hint\">\n <div><b>Server Hash:</b> {{ serverMeta.serverHash || '\u2014' }}</div>\n <div><b>\u00DAltima verifica\u00E7\u00E3o:</b> {{ serverMeta.lastVerifiedAt || '\u2014' }}</div>\n </div>\n </div>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Layout\">\n <div class=\"tab-content\">\n <praxis-layout-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-layout-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Hooks\">\n <div class=\"tab-content\">\n <praxis-hooks-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-hooks-editor>\n </div>\n </mat-tab>\n <mat-tab *ngIf=\"isPresentationMode\" label=\"Modo Apresenta\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Modo Apresenta\u00E7\u00E3o</h3>\n <p class=\"text-caption\">Configura\u00E7\u00F5es de exibi\u00E7\u00E3o aplicadas somente ao modo apresenta\u00E7\u00E3o.</p>\n\n <div class=\"presentation-layout\">\n <div class=\"presentation-controls\">\n <div class=\"control\">\n <label class=\"control__label\">Posi\u00E7\u00E3o do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelPosition\"\n aria-label=\"Posi\u00E7\u00E3o do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"above\">\n <mat-icon>view_stream</mat-icon>\n <span class=\"sr-only\">Acima</span>\n </mat-button-toggle>\n <mat-button-toggle value=\"left\">\n <mat-icon>view_column</mat-icon>\n <span class=\"sr-only\">\u00C0 esquerda</span>\n </mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Densidade</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.density\"\n aria-label=\"Densidade\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"comfortable\">Confort\u00E1vel</mat-button-toggle>\n <mat-button-toggle value=\"cozy\">Intermedi\u00E1ria</mat-button-toggle>\n <mat-button-toggle value=\"compact\">Compacta</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do r\u00F3tulo</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.labelAlign\"\n aria-label=\"Alinhamento do r\u00F3tulo\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <label class=\"control__label\">Alinhamento do valor</label>\n <mat-button-toggle-group\n [(ngModel)]=\"presentationPrefs.valueAlign\"\n aria-label=\"Alinhamento do valor\"\n class=\"toggle-group\"\n >\n <mat-button-toggle value=\"start\"><mat-icon>format_align_left</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"center\"><mat-icon>format_align_center</mat-icon></mat-button-toggle>\n <mat-button-toggle value=\"end\"><mat-icon>format_align_right</mat-icon></mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do r\u00F3tulo</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.labelFontSize\" placeholder=\"ex.: 12\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Tamanho do valor</mat-label>\n <input matInput type=\"number\" min=\"10\" [(ngModel)]=\"presentationPrefs.valueFontSize\" placeholder=\"ex.: 16\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control\">\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Largura do r\u00F3tulo (label \u00E0 esquerda)</mat-label>\n <input matInput type=\"number\" min=\"60\" [(ngModel)]=\"presentationPrefs.labelWidth\" placeholder=\"ex.: 140\" />\n <span matSuffix>px</span>\n </mat-form-field>\n </div>\n\n <div class=\"control control--inline\">\n <mat-slide-toggle [(ngModel)]=\"presentationPrefs.compact\">\n Modo compacto\n </mat-slide-toggle>\n <mat-checkbox [(ngModel)]=\"truncatePreview\">\n Truncar valores\n </mat-checkbox>\n </div>\n </div>\n\n <div class=\"presentation-preview\">\n <h4>Pr\u00E9\u2011visualiza\u00E7\u00E3o</h4>\n <div class=\"preview-card\">\n <div class=\"praxis-dynamic-form presentation-mode\"\n [ngClass]=\"{\n 'pres-compact': !!presentationPrefs.compact,\n 'pres-label-left': presentationPrefs.labelPosition === 'left',\n 'pres-label-above': presentationPrefs.labelPosition === 'above',\n 'pres-density-compact': presentationPrefs.density === 'compact',\n 'pres-density-cozy': presentationPrefs.density === 'cozy'\n }\"\n [style.--pfx-pres-label-size]=\"(presentationPrefs.labelFontSize || 12) + 'px'\"\n [style.--pfx-pres-value-size]=\"(presentationPrefs.valueFontSize || 16) + 'px'\"\n [style.--pfx-pres-label-width]=\"(presentationPrefs.labelWidth || 140) + 'px'\"\n [style.--pfx-pres-label-align]=\"presentationPrefs.labelAlign || 'start'\"\n [style.--pfx-pres-value-align]=\"presentationPrefs.valueAlign || 'start'\">\n <div class=\"preview-row\" *ngFor=\"let item of previewItems\">\n <span class=\"praxis-presentation__label\">{{ item.label }}</span>\n <span class=\"praxis-presentation__value\"\n [title]=\"truncatePreview ? item.value : null\"\n [style.maxWidth]=\"truncatePreview ? '280px' : null\"\n [style.overflow]=\"truncatePreview ? 'hidden' : null\"\n [style.textOverflow]=\"truncatePreview ? 'ellipsis' : null\"\n [style.whiteSpace]=\"truncatePreview ? 'nowrap' : 'normal'\">\n {{ item.value }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <p class=\"hint\">\n Estas configura\u00E7\u00F5es afetam apenas o Modo Apresenta\u00E7\u00E3o. S\u00E3o salvas por formul\u00E1rio\n e aplicadas no runtime atrav\u00E9s de vari\u00E1veis CSS e classes.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"Comportamento\">\n <div class=\"tab-content\">\n <praxis-behavior-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-behavior-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Dicas e Tooltips\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <h3>Dicas dos Modos</h3>\n <p class=\"text-caption\">Personalize os textos usados como tooltip/hint para modos de dados e modos globais de UI.</p>\n\n <div class=\"grid-2-cols\">\n <section>\n <h4>Modos de dados</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Criar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.create\" (ngModelChange)=\"updateDirtyState('hints-data-create')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Editar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.edit\" (ngModelChange)=\"updateDirtyState('hints-data-edit')\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Visualizar</mat-label>\n <input matInput [(ngModel)]=\"editedConfig.hints!.dataModes.view\" (ngModelChange)=\"updateDirtyState('hints-data-view')\" />\n </mat-form-field>\n </section>\n\n <section>\n <h4>Modos de UI</h4>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Apresenta\u00E7\u00E3o</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.presentation\" (ngModelChange)=\"updateDirtyState('hints-ui-presentation')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Leitura (readonly)</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.readonly\" (ngModelChange)=\"updateDirtyState('hints-ui-readonly')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Desabilitado</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.disabled\" (ngModelChange)=\"updateDirtyState('hints-ui-disabled')\"></textarea>\n </mat-form-field>\n <mat-form-field appearance=\"fill\" class=\"w-100\">\n <mat-label>Vis\u00EDvel</mat-label>\n <textarea matInput rows=\"2\" [(ngModel)]=\"editedConfig.hints!.uiModes.visible\" (ngModelChange)=\"updateDirtyState('hints-ui-visible')\"></textarea>\n </mat-form-field>\n </section>\n </div>\n\n <div class=\"actions-row\">\n <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"restoreHintsDefaults()\">\n <mat-icon>restore</mat-icon>\n Restaurar padr\u00F5es\n </button>\n </div>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"A\u00E7\u00F5es\">\n <div class=\"tab-content\">\n <praxis-actions-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-actions-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Regras\">\n <div class=\"tab-content visual-builder-content\">\n <praxis-visual-builder\n [config]=\"ruleBuilderConfig\"\n [initialRules]=\"ruleBuilderState\"\n (rulesChanged)=\"onRulesChanged($event)\"\n ></praxis-visual-builder>\n </div>\n </mat-tab>\n <mat-tab label=\"Cascatas\">\n <div class=\"tab-content\">\n <praxis-cascade-manager-tab\n [fields]=\"editedConfig.fieldMetadata || []\"\n (apply)=\"onCascadeApply($event)\"\n ></praxis-cascade-manager-tab>\n </div>\n </mat-tab>\n <mat-tab label=\"Mensagens\">\n <div class=\"tab-content\">\n <praxis-messages-editor\n [config]=\"editedConfig\"\n (configChange)=\"onConfigChange($event)\"\n ></praxis-messages-editor>\n </div>\n </mat-tab>\n <mat-tab label=\"Navega\u00E7\u00E3o\">\n <div class=\"tab-content\">\n <mat-card>\n <mat-card-content>\n <p>\n Configure o comportamento do bot\u00E3o Voltar quando este formul\u00E1rio\n for aberto via CRUD (rota ou modal).\n </p>\n <div class=\"form-row\">\n <label for=\"returnTo\">Rota de retorno (returnTo)</label>\n <input\n id=\"returnTo\"\n type=\"text\"\n class=\"text-input\"\n [(ngModel)]=\"backConfig!.returnTo\"\n placeholder=\"/funcionarios\"\n />\n </div>\n <div class=\"form-row\">\n <label>\n <input\n type=\"checkbox\"\n [(ngModel)]=\"backConfig!.confirmOnDirty\"\n />\n Confirmar ao sair com altera\u00E7\u00F5es\n </label>\n </div>\n <p class=\"hint\">\n Observa\u00E7\u00E3o: estas configura\u00E7\u00F5es afetam o fluxo de navega\u00E7\u00E3o do\n CRUD e podem ser sobrepostas por metadados do recurso.\n </p>\n </mat-card-content>\n </mat-card>\n </div>\n </mat-tab>\n <mat-tab label=\"JSON\">\n <div class=\"tab-content\">\n <form-json-config-editor\n [config]=\"editedConfig\"\n (configChange)=\"onJsonConfigChange($event)\"\n (validationChange)=\"onJsonValidationChange($event)\"\n (editorEvent)=\"onJsonEditorEvent($event)\"\n >\n </form-json-config-editor>\n </div>\n </mat-tab>\n </mat-tab-group>\n", styles: ["@charset \"UTF-8\";.config-tabs{height:auto}.tab-content{padding:16px;height:auto;overflow:visible}.form-row{display:block;margin-bottom:12px}.w-100{width:100%}.visual-builder-content{padding:0;height:100%}.json-field{width:100%}.presentation-layout{display:flex;gap:16px;align-items:flex-start}.presentation-controls{flex:1 1 60%;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 16px}.control{display:flex;flex-direction:column}.control__label{font-size:12px;color:var(--md-sys-color-on-surface-variant, #8a8a8a);margin-bottom:6px}.toggle-group{width:100%}.control--inline{grid-column:1/-1;display:flex;gap:16px;align-items:center}.presentation-preview{flex:0 0 360px;position:sticky;top:12px}.preview-card{border:1px solid var(--md-sys-color-outline, rgba(255, 255, 255, .12));border-radius:8px;padding:12px;background:var(--md-sys-color-surface-container, #2a3038)}.preview-row{display:flex;gap:8px;padding:6px 0;border-bottom:1px dashed var(--md-sys-color-outline-variant, rgba(255, 255, 255, .08))}.preview-row:last-child{border-bottom:none}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.presentation-preview .praxis-presentation__label{color:var(--md-sys-color-on-surface-variant, #b9c0cf)}.presentation-preview .praxis-presentation__value{color:var(--md-sys-color-on-surface, #e6eaf2)}.presentation-preview .presentation-mode.pres-density-cozy .preview-row{padding:6px 0}.presentation-preview .presentation-mode.pres-density-compact .preview-row,.presentation-preview .presentation-mode.pres-compact .preview-row{padding:2px 0}.presentation-preview .presentation-mode.pres-label-left .preview-row{display:grid;grid-template-columns:var(--pfx-pres-label-width, 140px) 1fr;align-items:baseline;column-gap:10px}.presentation-preview .presentation-mode.pres-label-left .praxis-presentation__label{margin:0;text-align:var(--pfx-pres-label-align, start)}.presentation-preview .presentation-mode .praxis-presentation__value{text-align:var(--pfx-pres-value-align, start)}.presentation-preview h4{margin:0 0 8px;color:var(--md-sys-color-on-surface, #e6eaf2)}\n"] }]
|
|
4400
4424
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
4401
4425
|
type: Inject,
|
|
4402
4426
|
args: [CONFIG_STORAGE]
|