import { Component } from "vue"; import { ZeroEditorField, ZeroEditorDisplay } from "zero/schemas"; import { Zero } from "../core"; import { ZeroEditor } from "./editor"; import { createBlueprintConfig } from "./editor-blueprint"; import { ZeroEditorCanvasBase, ZeroEditorTab } from "./editor-canvas"; import { ZeroEditorFieldConfiguration, ZeroEditorFieldFilterPreview } from "./editor-field"; import { localize } from '../services/localization'; let appliedExtensionsTo: string[] = []; export interface ZeroCompiledEditor { alias: string; blueprint: any; display: ZeroEditorDisplay; tabs: ZeroCompiledEditorTab[]; origin: ZeroEditor; } export interface ZeroCompiledEditorTab { alias: string; name: string; sort: number; class: string | null; count: (model: any) => number | null; disabled: (model: any) => boolean; hidden: (model: any) => boolean; fieldsets: ZeroCompiledEditorFieldset[]; component: Component | null; } export interface ZeroCompiledEditorFieldset { fields: ZeroCompiledEditorField[]; hasColumns: boolean; } export interface ZeroCompiledEditorChangeEvent { value: any; oldValue: any; model: any; component: Component; } export interface ZeroCompiledEditorField { path: string; configuration: ZeroEditorFieldConfiguration; fieldType: string; options: any | null; component: Component; optional: (model: any) => boolean; readonly: (model: any) => boolean; hidden: (model: any) => boolean; label: string; hideLabel: boolean; description: string | null; helpText: string | null; classes: string | null; horizontal: boolean; sort: number; columns: number; preview?: ZeroEditorFieldFilterPreview; onChange: (event: ZeroCompiledEditorChangeEvent) => void; } export function compileField(zero: Zero, editor: ZeroEditor, field: ZeroEditorField): ZeroCompiledEditorField | undefined { const component = field.customComponent || zero.getFieldTypeComponent(field.fieldType); if (!component) { return undefined; } let model = { configuration: field.configuration, fieldType: field.fieldType, options: field.options, path: field.path, component, optional(model: any) { if (typeof field.configuration.optional === 'boolean') { return field.configuration.optional; } if (typeof field.configuration.optional === 'function') { return field.configuration.optional(model); } return false; }, readonly(model: any) { if (typeof field.configuration.readonly === 'boolean') { return field.configuration.readonly; } if (typeof field.configuration.readonly === 'function') { return field.configuration.readonly(model); } return false; }, hidden(model: any) { if (typeof field.configuration.hidden === 'boolean') { return field.configuration.hidden; } if (typeof field.configuration.hidden === 'function') { return field.configuration.hidden(model); } return false; }, label: editor.onLabelCreate(field), description: localize(editor.onDescriptionCreate(field), { hideEmpty: true }), hideLabel: field.configuration.hideLabel, helpText: field.configuration.helpText, classes: field.configuration.classes, horizontal: field.configuration.horizontal, sort: field.configuration.sort, columns: 12, preview: field.configuration.preview ? { icon: field.configuration.preview.icon || 'fth-square', selected: field.configuration.preview.selected || (x => !!x), value: field.configuration.preview.value || (x => x ? x : null) } : null, onChange(event: ZeroCompiledEditorChangeEvent) { (field.configuration.changeHandlers || []).forEach(handler => { handler(event); }); } } as ZeroCompiledEditorField; return model; } export function compileEditor(zero: Zero, editor: ZeroEditor): ZeroCompiledEditor | null { if (!editor) { return null; } if (appliedExtensionsTo.indexOf(editor.alias) < 0) { appliedExtensionsTo.push(editor.alias); let extensions = zero.getSchemaExtensions(editor.alias); extensions.forEach(extension => { extension.extension(editor); }); } let model = { alias: editor.alias, blueprint: null, display: editor.display, tabs: [], origin: editor, } as ZeroCompiledEditor; let tabs = [...editor.tabs.sort((a, b) => a.sort - b.sort)]; // add default tab if necessary if (!tabs.length && (editor.fields.length || editor.fieldsets.length)) { let tab = new ZeroEditorTab('content', '@ui.tab_content'); tab.fieldsets.push(new ZeroEditorCanvasBase()); tabs.push(tab); } tabs.forEach((editorTab, tabIndex) => { let tab = { name: editorTab.name, sort: editorTab.sort, alias: editorTab.alias, class: null, count: (model: any) => null, disabled: (model: any) => false, hidden: (model: any) => false, fieldsets: [], component: null } as ZeroCompiledEditorTab; let fieldsets = []; // add fieldsets (which are not part of a tab) to the first tab if (tabIndex == 0 && editor.fieldsets.length) { fieldsets.push(...editor.fieldsets); } // push registered fieldsets fieldsets.push(...editorTab.fieldsets.sort((a, b) => a.sort - b.sort)); // add default fieldset if none are defined if (!fieldsets.length) { const fakeFieldset = new ZeroEditorCanvasBase(); fakeFieldset.isFake = false; fieldsets.push(fakeFieldset); } fieldsets.forEach((editorFieldset, fieldsetIndex) => { let fieldset = { sort: editorFieldset.sort, fields: [], hasColumns: !editorFieldset.isFake } as ZeroCompiledEditorFieldset; let fields = []; // add fields (which are not part of a fieldset) to the first fieldset if (fieldsetIndex == fieldsets.length - 1) { if (editor.fields.length) { fields.push(...editor.fields); } if (editorTab.fields.length) { fields.push(...editorTab.fields); } } // push registered fields // @ts-ignore fields.push(...editorFieldset.fields.sort((a, b) => a.configuration.sort - b.configuration.sort)); fields.forEach(editorField => { const field = compileField(zero, editor, editorField); if (field == null) { console.error('Could not find registered field type [' + editorField.fieldType + ']'); } else { fieldset.fields.push(field); } }); if (fieldset.fields.length) { tab.fieldsets.push(fieldset); } }); if (tab.fieldsets.length) { model.tabs.push(tab); } }); model.blueprint = createBlueprintConfig(model.alias, model); return model; }