UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

800 lines 133 kB
import { Component, ElementRef, Input, ViewChild } from '@angular/core'; import { TreeTableComponent } from '../../controls/data-table/data-table.component'; import { SchemaPrimitiveType } from '../schema/schema-models'; import { SchemaDataTypeStore } from '../schema/schema-store'; import { SchemaUtilities } from '../schema/schema-utilities'; import { SchemaFormContentComponent } from './schema-form-content.component'; import { propertyFormSchema } from './schema-form-editor-schema-tree.constants'; import { SchemaFormEditorUtilities } from './schema-form-editor-utilities'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "../data-table/data-table-column.component"; import * as i3 from "../data-table/data-table.component"; import * as i4 from "../split-view/split-view.component"; import * as i5 from "../tooltip/tooltip.directive"; import * as i6 from "./schema-form-content.component"; const _c0 = ["propertyForm"]; const _c1 = ["schemaTree"]; function SchemaFormEditorSchemaTreeComponent_ng_template_7_Template(rf, ctx) { if (rf & 1) { i0.ɵɵtext(0); } if (rf & 2) { const data_r7 = ctx.$implicit; const ctx_r2 = i0.ɵɵnextContext(); i0.ɵɵtextInterpolate1(" ", ctx_r2.getSchemaTreeNodeDisplayText(data_r7), " "); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_1_Template(rf, ctx) { if (rf & 1) { const _r15 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "button", 11); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_1_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r15); const ctx_r14 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r14.addProperty()); }); i0.ɵɵelement(2, "span", 12); i0.ɵɵelementEnd()(); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_2_Template(rf, ctx) { if (rf & 1) { const _r17 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "button", 13); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_2_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r17); const ctx_r16 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r16.moveUp()); }); i0.ɵɵelement(2, "span", 14); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "button", 15); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r17); const ctx_r18 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r18.moveDown()); }); i0.ɵɵelement(4, "span", 16); i0.ɵɵelementEnd(); i0.ɵɵelementStart(5, "button", 17); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r17); const ctx_r19 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r19.delete()); }); i0.ɵɵelement(6, "span", 18); i0.ɵɵelementEnd()(); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template(rf, ctx) { if (rf & 1) { const _r21 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "button", 11); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r21); const ctx_r20 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r20.addProperty()); }); i0.ɵɵelement(2, "span", 12); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "button", 13); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r21); const ctx_r22 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r22.moveUp()); }); i0.ɵɵelement(4, "span", 14); i0.ɵɵelementEnd(); i0.ɵɵelementStart(5, "button", 15); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r21); const ctx_r23 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r23.moveDown()); }); i0.ɵɵelement(6, "span", 16); i0.ɵɵelementEnd(); i0.ɵɵelementStart(7, "button", 17); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r24 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r24.delete()); }); i0.ɵɵelement(8, "span", 18); i0.ɵɵelementEnd()(); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_4_Template(rf, ctx) { if (rf & 1) { const _r26 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "button", 13); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_4_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r26); const ctx_r25 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r25.moveUp()); }); i0.ɵɵelement(2, "span", 14); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "button", 15); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_4_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r26); const ctx_r27 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r27.moveDown()); }); i0.ɵɵelement(4, "span", 16); i0.ɵɵelementEnd(); i0.ɵɵelementStart(5, "button", 17); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_4_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r26); const ctx_r28 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r28.delete()); }); i0.ɵɵelement(6, "span", 18); i0.ɵɵelementEnd()(); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_5_Template(rf, ctx) { if (rf & 1) { const _r30 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "button", 11); i0.ɵɵlistener("click", function SchemaFormEditorSchemaTreeComponent_ng_template_9_div_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r30); const ctx_r29 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r29.addProperty()); }); i0.ɵɵelement(2, "span", 12); i0.ɵɵelementEnd()(); } } function SchemaFormEditorSchemaTreeComponent_ng_template_9_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 10); i0.ɵɵtemplate(1, SchemaFormEditorSchemaTreeComponent_ng_template_9_div_1_Template, 3, 0, "div", 9); i0.ɵɵtemplate(2, SchemaFormEditorSchemaTreeComponent_ng_template_9_div_2_Template, 7, 0, "div", 9); i0.ɵɵtemplate(3, SchemaFormEditorSchemaTreeComponent_ng_template_9_div_3_Template, 9, 0, "div", 9); i0.ɵɵtemplate(4, SchemaFormEditorSchemaTreeComponent_ng_template_9_div_4_Template, 7, 0, "div", 9); i0.ɵɵtemplate(5, SchemaFormEditorSchemaTreeComponent_ng_template_9_div_5_Template, 3, 0, "div", 9); i0.ɵɵelementEnd(); } if (rf & 2) { const data_r8 = ctx.$implicit; const ctx_r3 = i0.ɵɵnextContext(); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r3.getPropertyTreeNodeType(data_r8) == "root"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r3.getPropertyTreeNodeType(data_r8) == "normal"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r3.getPropertyTreeNodeType(data_r8) == "object"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r3.getPropertyTreeNodeType(data_r8) == "array"); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r3.getPropertyTreeNodeType(data_r8) == "array-item"); } } function SchemaFormEditorSchemaTreeComponent_div_10_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 19)(1, "ul")(2, "li"); i0.ɵɵtext(3); i0.ɵɵelementEnd(); i0.ɵɵelementStart(4, "li"); i0.ɵɵtext(5); i0.ɵɵelementEnd(); i0.ɵɵelementStart(6, "li"); i0.ɵɵtext(7); i0.ɵɵelementEnd(); i0.ɵɵelementStart(8, "li"); i0.ɵɵtext(9); i0.ɵɵelementEnd(); i0.ɵɵelementStart(10, "li")(11, "strong"); i0.ɵɵtext(12); i0.ɵɵelementEnd()()()(); } if (rf & 2) { const ctx_r4 = i0.ɵɵnextContext(); i0.ɵɵadvance(3); i0.ɵɵtextInterpolate(ctx_r4.strings.SchemaTree.Welcome.Row1); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r4.strings.SchemaTree.Welcome.Row2); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r4.strings.SchemaTree.Welcome.Row3); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r4.strings.SchemaTree.Welcome.Row4); i0.ɵɵadvance(3); i0.ɵɵtextInterpolate(ctx_r4.strings.SchemaTree.Welcome.Row5); } } function SchemaFormEditorSchemaTreeComponent_div_13_Template(rf, ctx) { if (rf & 1) { const _r33 = i0.ɵɵgetCurrentView(); i0.ɵɵelementStart(0, "div")(1, "h3", 20); i0.ɵɵtext(2); i0.ɵɵelementEnd(); i0.ɵɵelementStart(3, "sme-schema-form-content", 21, 22); i0.ɵɵlistener("dataChange", function SchemaFormEditorSchemaTreeComponent_div_13_Template_sme_schema_form_content_dataChange_3_listener($event) { i0.ɵɵrestoreView(_r33); const ctx_r32 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r32.selectedSchemaTreeNode.data.schema = $event); }); i0.ɵɵelementEnd(); i0.ɵɵelementStart(5, "i", 23); i0.ɵɵtext(6); i0.ɵɵelementEnd()(); } if (rf & 2) { const ctx_r5 = i0.ɵɵnextContext(); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r5.strings.PropertyForm.Header); i0.ɵɵadvance(1); i0.ɵɵproperty("schema", ctx_r5.currentPropertyFormSchema)("data", ctx_r5.selectedSchemaTreeNode.data.schema)("formController", ctx_r5.propertyFormController); i0.ɵɵadvance(3); i0.ɵɵtextInterpolate(ctx_r5.strings.PropertyForm.Footer); } } function SchemaFormEditorSchemaTreeComponent_div_14_li_5_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "li")(1, "strong"); i0.ɵɵtext(2); i0.ɵɵelementEnd()(); } if (rf & 2) { const ctx_r34 = i0.ɵɵnextContext(2); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r34.strings.PropertyForm.Welcome.Row2); } } function SchemaFormEditorSchemaTreeComponent_div_14_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div")(1, "ul")(2, "li")(3, "strong"); i0.ɵɵtext(4); i0.ɵɵelementEnd()(); i0.ɵɵtemplate(5, SchemaFormEditorSchemaTreeComponent_div_14_li_5_Template, 3, 1, "li", 9); i0.ɵɵelementStart(6, "li"); i0.ɵɵtext(7); i0.ɵɵelementEnd(); i0.ɵɵelementStart(8, "li"); i0.ɵɵtext(9); i0.ɵɵelementEnd(); i0.ɵɵelementStart(10, "li"); i0.ɵɵtext(11); i0.ɵɵelementEnd(); i0.ɵɵelementStart(12, "li"); i0.ɵɵtext(13); i0.ɵɵelementEnd(); i0.ɵɵelementStart(14, "li"); i0.ɵɵtext(15); i0.ɵɵelementEnd()()(); } if (rf & 2) { const ctx_r6 = i0.ɵɵnextContext(); i0.ɵɵadvance(4); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row1); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", ctx_r6.schemaTreeData && ctx_r6.schemaTreeData[0] && ctx_r6.schemaTreeData[0].children.length > 0); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row3); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row4); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row5); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row6); i0.ɵɵadvance(2); i0.ɵɵtextInterpolate(ctx_r6.strings.PropertyForm.Welcome.Row7); } } export class SchemaFormEditorSchemaTreeComponent { constructor(elementRef) { this.elementRef = elementRef; this.strings = MsftSme.getStrings().MsftSmeShell.Angular.SchemaForm.Editor; this.isInitialized = false; this.schemaDataTypeStore = new SchemaDataTypeStore(); this.propertyFormSchema = SchemaFormEditorUtilities.deepCopy(propertyFormSchema); /** * The data bind to the schema tree. * It describes the data schema in a tree visual style. */ this.schemaTreeData = []; this.propertyFormController = { isRootNodeSelected: () => { return this.selectedSchemaTreeNode.data.tag === 'root'; }, isNotObjectType: (context) => context.formData.dataType.type !== 'Object' }; } get isPropertyFormValid() { return !this.propertyForm || this.propertyForm.isFormValid; } /** * The schema from the form to be edited. */ get schema() { return this.internalSchema; } set schema(value) { this.internalSchema = value; if (this.isInitialized) { this.refreshSchemaTreeData(); } } /** * The selected schema tree node. * Every time when it's selected, the form schema for the property related tree node will be constructed dynamically * and the property form will be rendered based on the form schema. */ get selectedSchemaTreeNode() { return this.internalSelectedSchemaTreeNode; } set selectedSchemaTreeNode(value) { this.internalSelectedSchemaTreeNode = value; if (this.selectedSchemaTreeNode && this.selectedSchemaTreeNode.data && this.selectedSchemaTreeNode.data.schema) { this.currentSelectedPropertyFullType = SchemaUtilities.generateFullTypeStringByPropertySchema(this.selectedSchemaTreeNode.data.schema.toPropertySchemaModel()); this.currentPropertyFormSchema = this.getPropertyFormSchema(); this.selectedSchemaTreeNode.data.schema = SchemaUtilities.setUpFormData(this.selectedSchemaTreeNode.data.schema, this.currentPropertyFormSchema); this.selectedSchemaTreeNode.data.schema.dataType.isInitialized = false; setTimeout(() => { if (this.selectedSchemaTreeNode) { this.selectedSchemaTreeNode.data.schema.dataType.isInitialized = true; } }); } } ngOnInit() { // Collect the available data types for the form to be edited. const allRegistrations = this.schemaDataTypeStore.getAllRegistrations(); this.availableDataTypes = []; allRegistrations.forEach(registration => { if (this.availableDataTypes.filter(item => item.value === SchemaPrimitiveType[registration.type]).length === 0) { this.availableDataTypes.push({ value: SchemaPrimitiveType[registration.type], label: 'actual_string:' + SchemaPrimitiveType[registration.type] }); } }); this.timer = setInterval(() => { this.handleSchemaFormChange(); }, 1500); // Construct the root node of the schema tree. this.refreshSchemaTreeData(); this.isInitialized = true; setTimeout(() => { this.treeWidth = this.elementRef.nativeElement.querySelector('sme-split-view').offsetWidth * 0.5; }); } ngOnDestroy() { clearInterval(this.timer); } getPropertyFormSchema() { if (this.selectedSchemaTreeNode) { // Get the schema from the selected tree node. const schema = this.selectedSchemaTreeNode.data.schema; // Set the "options" property schema to default to json object editor. const currentOptionsPropertySchema = SchemaUtilities.getPropertySchemaByName(this.propertyFormSchema, 'options'); currentOptionsPropertySchema.format = 'json-text-editor'; currentOptionsPropertySchema.properties = []; // If the specific data type registration has its own "options" schema, use it. const type = SchemaPrimitiveType[schema.dataType.type]; const dataTypeRegistration = this.schemaDataTypeStore.getDataTypeRegistration(type, schema.dataType.format); if (dataTypeRegistration && dataTypeRegistration.optionProperties) { currentOptionsPropertySchema.format = 'default'; currentOptionsPropertySchema.properties = SchemaFormEditorUtilities.deepCopy(dataTypeRegistration.optionProperties); } this.propertyFormSchema.properties[this.propertyFormSchema.properties.indexOf(currentOptionsPropertySchema)] = SchemaFormEditorUtilities.deepCopy(currentOptionsPropertySchema); // Setup the schema data based on current property form schema. // It helps construct some default values based on the schema if the current schema data misses some property values. this.selectedSchemaTreeNode.data.schema = SchemaUtilities.setUpFormData(this.selectedSchemaTreeNode.data.schema, this.propertyFormSchema); } // return SchemaFormEditorUtilities.deepCopy(this.propertyFormSchema); return this.propertyFormSchema; } getPropertyTreeNodeType(nodeData) { let result = 'normal'; if (nodeData.tag === 'root') { result = 'root'; } else { // "array-item" is a special tree node because it only appears under array data and cannot be deleted. if (nodeData.tag === 'array-item') { result = 'array-item'; } else if (nodeData.schema.dataType.type === SchemaPrimitiveType[SchemaPrimitiveType.Object]) { result = 'object'; } else if (nodeData.schema.dataType.type === SchemaPrimitiveType[SchemaPrimitiveType.Array]) { result = 'array'; } } return result; } getItemIdentityFunction(data) { return data.schema && data.schema.name; } getSchemaTreeNodeDisplayText(schemaTreeData) { let prefix = ''; if (schemaTreeData.schema) { if (schemaTreeData.schema.dataType.type === SchemaPrimitiveType[SchemaPrimitiveType.Object]) { prefix = '[Object]'; } else if (schemaTreeData.schema.dataType.type === SchemaPrimitiveType[SchemaPrimitiveType.Array]) { prefix = '[Array]'; } else { prefix = ''; } } let text = schemaTreeData.schema && schemaTreeData.schema.name; if (!text) { if (schemaTreeData.tag === 'root') { prefix = ''; text = 'Schema'; } else if (schemaTreeData.tag === 'array-item') { text = 'Array Item'; } else { text = '<new property>'; } } if (prefix) { prefix += ' '; } return prefix + text; } handleSchemaFormChange() { if (this.selectedSchemaTreeNode) { const newSelectedProperty = (this.selectedSchemaTreeNode && this.selectedSchemaTreeNode.data && this.selectedSchemaTreeNode.data.schema && this.selectedSchemaTreeNode.data.schema.toPropertySchemaModel()); const newPropertyFullType = SchemaUtilities.generateFullTypeStringByPropertySchema(newSelectedProperty); const selectedSchemaTreeNodeData = this.selectedSchemaTreeNode.data; // If the user changes the type or format for the current property, then we need to do something here. if (this.currentSelectedPropertyFullType && newPropertyFullType && newPropertyFullType !== this.currentSelectedPropertyFullType) { if (this.currentSelectedPropertyFullType) { // Put all the child schema tree nodes of the current selected tree node in to "previousChildren" // Later if the user switch back from new full type to current full type, we will restore the previous // child schema tree nodes back. if (selectedSchemaTreeNodeData.previousChildren) { selectedSchemaTreeNodeData.previousChildren[this.currentSelectedPropertyFullType] = []; this.selectedSchemaTreeNode.children.forEach(item => { selectedSchemaTreeNodeData.previousChildren[this.currentSelectedPropertyFullType].push(item); }); } if (selectedSchemaTreeNodeData.previousOptions) { selectedSchemaTreeNodeData.previousOptions[this.currentSelectedPropertyFullType] = selectedSchemaTreeNodeData.schema.options; } } // If the new type is object, we will automatically add some child schema tree nodes based on // the "predefinedObjectProperties" defined in the data type registration. // In some object type data type registration (not default format), the data type may requires some fixed property // structure. For example a "image" object type (type:'object', format:'image) may have properties like "url", // "title", "width", "height". Then those properties can be defined in "predefinedObjectProperties". // When the user use 'object' type 'image' format, the editor will automatically add those properties // as the child schema tree nodes. if (newSelectedProperty.type === SchemaPrimitiveType.Object) { const predefinedObjectProperties = this.schemaDataTypeStore.getDataTypeRegistration(newSelectedProperty.type, newSelectedProperty.format).predefinedObjectProperties; let predefinedPropertySchemaTreeNodes = null; if (predefinedObjectProperties) { predefinedPropertySchemaTreeNodes = []; predefinedObjectProperties.forEach(item => { predefinedPropertySchemaTreeNodes.push(this.generateSchemaTreeNodeInternal(item)); }); } this.selectedSchemaTreeNode.children = selectedSchemaTreeNodeData.previousChildren[SchemaUtilities.generateFullTypeString(newSelectedProperty.type, newSelectedProperty.format)] || predefinedPropertySchemaTreeNodes || []; } else if (newSelectedProperty.type === SchemaPrimitiveType.Array) { this.selectedSchemaTreeNode.children = selectedSchemaTreeNodeData.previousChildren[SchemaUtilities.generateFullTypeString(newSelectedProperty.type, newSelectedProperty.format)] || [ { data: { schema: new PropertySchemaViewModel({ type: SchemaPrimitiveType.Object, format: 'default', name: '', label: '' }, this.availableDataTypes), tag: 'array-item' }, children: [], expanded: true } ]; } else { this.selectedSchemaTreeNode.children = []; } selectedSchemaTreeNodeData.schema.options = selectedSchemaTreeNodeData.previousOptions[newPropertyFullType]; this.currentPropertyFormSchema = this.getPropertyFormSchema(); const defaultData = SchemaUtilities.generateDataBasedOnSchema(this.currentPropertyFormSchema); for (const property in defaultData) { if (defaultData.hasOwnProperty(property)) { if (!selectedSchemaTreeNodeData.schema[property]) { selectedSchemaTreeNodeData.schema[property] = SchemaFormEditorUtilities.deepCopy(defaultData[property]); } } } this.schemaTree.refreshData(); } this.currentSelectedPropertyFullType = SchemaUtilities.generateFullTypeStringByPropertySchema(newSelectedProperty); } } refreshSchemaTreeData() { const rootPropertySchemaViewModel = new PropertySchemaViewModel(this.schema, this.availableDataTypes, true); const root = { data: { schema: rootPropertySchemaViewModel, previousChildren: {}, previousOptions: {}, tag: 'root' }, children: [], expanded: true }; if (!root.data.schema.dataType.type) { root.data.schema.dataType.type = 'Object'; } if (!root.data.schema.dataType.format) { root.data.schema.dataType.format = 'basic-form'; } const formats = []; const allRegistrations = this.schemaDataTypeStore.getAllRegistrations(); allRegistrations.forEach(registration => { if (registration.tags && registration.tags.indexOf('form-container') !== -1) { formats.push({ value: registration.format, label: 'actual_string:' + registration.format }); } }); rootPropertySchemaViewModel.dataType.formats = formats; if (this.schema.properties) { this.schema.properties.forEach(property => { const schema = this.generateSchemaTreeNodeInternal(property); root.children.push(schema); }); } this.schemaTreeData = [root]; if (this.schemaTree) { setTimeout(() => { this.schemaTree.refreshData(); }); } } generateSchemaTreeNodeInternal(property) { let schemaChild = null; if (property.type === SchemaPrimitiveType.Object) { schemaChild = { data: { schema: new PropertySchemaViewModel(property, this.availableDataTypes), previousChildren: {}, previousOptions: {} }, children: [], expanded: true }; const objectProperty = property; objectProperty.properties.forEach(subProperty => { const result = this.generateSchemaTreeNodeInternal(subProperty); schemaChild.children.push(result); }); } else if (property.type === SchemaPrimitiveType.Array) { schemaChild = { data: { schema: new PropertySchemaViewModel(property, this.availableDataTypes), previousChildren: {}, previousOptions: {} }, children: [], expanded: true }; const arrayProperty = property; const result = this.generateSchemaTreeNodeInternal(arrayProperty.item); result.data.tag = 'array-item'; schemaChild.children.push(result); } else { schemaChild = { data: { schema: new PropertySchemaViewModel(property, this.availableDataTypes), previousChildren: {}, previousOptions: {} }, children: [], expanded: true }; } return schemaChild; } generateSchema() { const schema = this.generatePropertyInternal(this.schemaTreeData[0]); return schema; } addProperty() { setTimeout(() => { let child = { data: { schema: new PropertySchemaViewModel({ type: SchemaPrimitiveType.String, format: 'textbox', name: '', label: '' }, this.availableDataTypes), previousChildren: {}, previousOptions: {} }, children: [], expanded: true }; if (this.getPropertyTreeNodeType(this.selectedSchemaTreeNode.data) === 'array') { const arrayChildren = [ { schema: new PropertySchemaViewModel({ type: SchemaPrimitiveType.Object, format: 'textbox', name: '', label: '' }, this.availableDataTypes), tag: 'array-item' } ]; child = { data: { schema: new PropertySchemaViewModel({ type: SchemaPrimitiveType.String, format: 'textbox', name: '', label: '' }, this.availableDataTypes) }, children: arrayChildren, expanded: true }; } this.selectedSchemaTreeNode.children.push(child); this.schemaTree.refreshData(); }); } moveUp() { setTimeout(() => { const parentNode = this.selectedSchemaTreeNode.parent; const index = parentNode.children.indexOf(this.selectedSchemaTreeNode); if (index > 0) { const temp = { ...parentNode.children[index] }; parentNode.children[index] = { ...parentNode.children[index - 1] }; parentNode.children[index - 1] = temp; this.selectedSchemaTreeNode = null; this.selectedSchemaTreeNode = parentNode.children[index - 1]; this.schemaTree.refreshData(); } }); } moveDown() { setTimeout(() => { const parentNode = this.selectedSchemaTreeNode.parent; const index = parentNode.children.indexOf(this.selectedSchemaTreeNode); if (index < parentNode.children.length - 1) { const temp = { ...parentNode.children[index] }; parentNode.children[index] = { ...parentNode.children[index + 1] }; parentNode.children[index + 1] = temp; this.selectedSchemaTreeNode = null; this.selectedSchemaTreeNode = parentNode.children[index + 1]; this.schemaTree.refreshData(); } }); } delete() { setTimeout(() => { const parentNode = this.selectedSchemaTreeNode.parent; const index = parentNode.children.indexOf(this.selectedSchemaTreeNode); parentNode.children.splice(index, 1); this.selectedSchemaTreeNode = null; this.schemaTree.clearSelection(); this.schemaTree.refreshData(); }); } shouldShowWelcomeTextForSchemaTree() { return !(this.schemaTreeData && this.schemaTreeData[0] && this.schemaTreeData[0].children.length > 0); } generatePropertyInternal(schemaTreeNode) { let property; const schemaTreeNodeData = schemaTreeNode.data; const propertySchemaModel = schemaTreeNodeData.schema.toPropertySchemaModel(); if (schemaTreeNodeData.schema && schemaTreeNodeData.schema.dataType.type === SchemaPrimitiveType[SchemaPrimitiveType.Object]) { let objectProperty; if (schemaTreeNodeData.tag === 'root') { objectProperty = { properties: [] }; if (propertySchemaModel.format !== 'default') { objectProperty.format = propertySchemaModel.format; } objectProperty.options = propertySchemaModel.options; objectProperty.label = propertySchemaModel.label; } else { objectProperty = { ...propertySchemaModel, properties: [] }; } schemaTreeNode.children.forEach(child => { objectProperty.properties.push(this.generatePropertyInternal(child)); }); property = objectProperty; } else if (this.getPropertyTreeNodeType(schemaTreeNodeData) === 'array') { const arrayProperty = { ...schemaTreeNode.data.schema.toPropertySchemaModel(), item: this.generatePropertyInternal(schemaTreeNode.children[0]) }; property = arrayProperty; } else { property = { ...propertySchemaModel }; } return property; } } /** @nocollapse */ SchemaFormEditorSchemaTreeComponent.ɵfac = function SchemaFormEditorSchemaTreeComponent_Factory(t) { return new (t || SchemaFormEditorSchemaTreeComponent)(i0.ɵɵdirectiveInject(i0.ElementRef)); }; /** @nocollapse */ SchemaFormEditorSchemaTreeComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SchemaFormEditorSchemaTreeComponent, selectors: [["sme-schema-form-editor-schema-tree"]], viewQuery: function SchemaFormEditorSchemaTreeComponent_Query(rf, ctx) { if (rf & 1) { i0.ɵɵviewQuery(_c0, 5); i0.ɵɵviewQuery(_c1, 5); } if (rf & 2) { let _t; i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.propertyForm = _t.first); i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.schemaTree = _t.first); } }, inputs: { schema: "schema" }, decls: 15, vars: 11, consts: [["orientation", "left", 3, "isExpanded", "paneDistance"], ["editingSplitView", ""], [1, "sme-layout-absolute-phone-up", "sme-position-inset-none", "sme-padding-inset-xs"], [1, "sme-layout-absolute-phone-up", "sme-position-inset-none", 3, "items", "showHeader", "showGrid", "showLeftMargin", "getItemIdentityFunction", "selection", "selectionChange"], ["schemaTree", ""], ["field", "label", "header", "Name", "sortable", "true"], ["field", "label", "header", "Name", "sortable", "true", "width", "100px"], ["class", "sme-layout-absolute-phone-up sme-position-bottom-none sme-arrange-overflow-auto", 4, "ngIf"], [1, "sme-layout-absolute-phone-up", "sme-position-inset-none", "sme-padding-inset-xs", "sme-arrange-overflow-auto"], [4, "ngIf"], [1, "toolbar", "sme-position-right-inline"], ["title", "Add a property", 1, "sme-button-trigger", 3, "click"], [1, "sme-icon", "sme-icon-add"], ["title", "Move a property up", 1, "sme-button-trigger", 3, "click"], [1, "sme-icon", "sme-icon-up"], ["title", "Move a property down", 1, "sme-button-trigger", 3, "click"], [1, "sme-icon", "sme-icon-down"], ["title", "Delete a property", 1, "sme-button-trigger", 3, "click"], [1, "sme-icon", "sme-icon-cancel", "sme-color-red"], [1, "sme-layout-absolute-phone-up", "sme-position-bottom-none", "sme-arrange-overflow-auto"], [1, "sme-margin-bottom-lg"], [3, "schema", "data", "formController", "dataChange"], ["propertyForm", ""], [1, "sme-layout-block", "sme-margin-top-xxl"]], template: function SchemaFormEditorSchemaTreeComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "sme-split-view", 0, 1)(2, "sme-split-view-pane")(3, "div", 2)(4, "sme-tree-table", 3, 4); i0.ɵɵlistener("selectionChange", function SchemaFormEditorSchemaTreeComponent_Template_sme_tree_table_selectionChange_4_listener($event) { return ctx.selectedSchemaTreeNode = $event; }); i0.ɵɵelementStart(6, "sme-tree-table-column", 5); i0.ɵɵtemplate(7, SchemaFormEditorSchemaTreeComponent_ng_template_7_Template, 1, 1, "ng-template"); i0.ɵɵelementEnd(); i0.ɵɵelementStart(8, "sme-tree-table-column", 6); i0.ɵɵtemplate(9, SchemaFormEditorSchemaTreeComponent_ng_template_9_Template, 6, 5, "ng-template"); i0.ɵɵelementEnd()(); i0.ɵɵtemplate(10, SchemaFormEditorSchemaTreeComponent_div_10_Template, 13, 5, "div", 7); i0.ɵɵelementEnd()(); i0.ɵɵelementStart(11, "sme-split-view-content")(12, "div", 8); i0.ɵɵtemplate(13, SchemaFormEditorSchemaTreeComponent_div_13_Template, 7, 5, "div", 9); i0.ɵɵtemplate(14, SchemaFormEditorSchemaTreeComponent_div_14_Template, 16, 7, "div", 9); i0.ɵɵelementEnd()()(); } if (rf & 2) { i0.ɵɵproperty("isExpanded", true)("paneDistance", ctx.treeWidth); i0.ɵɵadvance(4); i0.ɵɵproperty("items", ctx.schemaTreeData)("showHeader", false)("showGrid", false)("showLeftMargin", false)("getItemIdentityFunction", ctx.getItemIdentityFunction)("selection", ctx.selectedSchemaTreeNode); i0.ɵɵadvance(6); i0.ɵɵproperty("ngIf", ctx.shouldShowWelcomeTextForSchemaTree()); i0.ɵɵadvance(3); i0.ɵɵproperty("ngIf", ctx.selectedSchemaTreeNode && ctx.selectedSchemaTreeNode.data.schema); i0.ɵɵadvance(1); i0.ɵɵproperty("ngIf", !(ctx.selectedSchemaTreeNode && ctx.selectedSchemaTreeNode.data.schema)); } }, dependencies: [i1.NgIf, i2.DataTableColumnComponent, i3.TreeTableComponent, i4.SplitViewComponent, i4.SplitViewContentComponent, i4.SplitViewPaneComponent, i5.TooltipDirective, i6.SchemaFormContentComponent], styles: ["[_nghost-%COMP%]::sme-tree-table .sme-table-row[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{padding:0;margin:0;min-width:auto;height:30px;width:19px}[_nghost-%COMP%]::sme-tree-table .sme-table-row[_ngcontent-%COMP%] .toolbar[_ngcontent-%COMP%]{display:none}[_nghost-%COMP%]::sme-tree-table .sme-table-row[_ngcontent-%COMP%]:hover .toolbar[_ngcontent-%COMP%], [_nghost-%COMP%]::sme-tree-table .sme-table-row.selected[_ngcontent-%COMP%] .toolbar[_ngcontent-%COMP%]{display:block}"] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchemaFormEditorSchemaTreeComponent, [{ type: Component, args: [{ selector: 'sme-schema-form-editor-schema-tree', template: "<sme-split-view #editingSplitView orientation=\"left\" [isExpanded]=\"true\" [paneDistance]=\"treeWidth\">\r\n <sme-split-view-pane>\r\n <div class=\"sme-layout-absolute-phone-up sme-position-inset-none sme-padding-inset-xs\">\r\n <sme-tree-table #schemaTree [items]=\"schemaTreeData\" class=\"sme-layout-absolute-phone-up sme-position-inset-none\"\r\n [showHeader]=\"false\" [showGrid]=\"false\" [showLeftMargin]=\"false\" [getItemIdentityFunction]=\"getItemIdentityFunction\"\r\n [(selection)]=\"selectedSchemaTreeNode\">\r\n <sme-tree-table-column field=\"label\" header=\"Name\" sortable=\"true\">\r\n <ng-template let-data>\r\n {{getSchemaTreeNodeDisplayText(data)}}\r\n </ng-template>\r\n </sme-tree-table-column>\r\n <sme-tree-table-column field=\"label\" header=\"Name\" sortable=\"true\" width=\"100px\">\r\n <ng-template let-data>\r\n <div class='toolbar sme-position-right-inline'>\r\n <div *ngIf=\"getPropertyTreeNodeType(data)=='root'\">\r\n <button class=\"sme-button-trigger\" (click)=\"addProperty()\" title=\"Add a property\">\r\n <span class=\"sme-icon sme-icon-add\"></span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"getPropertyTreeNodeType(data)=='normal'\">\r\n <button class=\"sme-button-trigger\" (click)=\"moveUp()\" title=\"Move a property up\">\r\n <span class=\"sme-icon sme-icon-up\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"moveDown()\" title=\"Move a property down\">\r\n <span class=\"sme-icon sme-icon-down\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"delete()\" title=\"Delete a property\">\r\n <span class=\"sme-icon sme-icon-cancel sme-color-red\"></span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"getPropertyTreeNodeType(data)=='object'\">\r\n <button class=\"sme-button-trigger\" (click)=\"addProperty()\" title=\"Add a property\">\r\n <span class=\"sme-icon sme-icon-add\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"moveUp()\" title=\"Move a property up\">\r\n <span class=\"sme-icon sme-icon-up\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"moveDown()\" title=\"Move a property down\">\r\n <span class=\"sme-icon sme-icon-down\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"delete()\" title=\"Delete a property\">\r\n <span class=\"sme-icon sme-icon-cancel sme-color-red\"></span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"getPropertyTreeNodeType(data)=='array'\">\r\n <button class=\"sme-button-trigger\" (click)=\"moveUp()\" title=\"Move a property up\">\r\n <span class=\"sme-icon sme-icon-up\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"moveDown()\" title=\"Move a property down\">\r\n <span class=\"sme-icon sme-icon-down\"></span>\r\n </button>\r\n <button class=\"sme-button-trigger\" (click)=\"delete()\" title=\"Delete a property\">\r\n <span class=\"sme-icon sme-icon-cancel sme-color-red\"></span>\r\n </button>\r\n </div>\r\n <div *ngIf=\"getPropertyTreeNodeType(data)=='array-item'\">\r\n <button class=\"sme-button-trigger\" (click)=\"addProperty()\" title=\"Add a property\">\r\n <span class=\"sme-icon sme-icon-add\"></span>\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </sme-tree-table-column>\r\n </sme-tree-table>\r\n <div *ngIf=\"shouldShowWelcomeTextForSchemaTree()\" class=\"sme-layout-absolute-phone-up sme-position-bottom-none sme-arrange-overflow-auto\">\r\n <ul>\r\n <li>{{strings.SchemaTree.Welcome.Row1}}</li>\r\n <li>{{strings.SchemaTree.Welcome.Row2}}</li>\r\n <li>{{strings.SchemaTree.Welcome.Row3}}</li>\r\n <li>{{strings.SchemaTree.Welcome.Row4}}</li>\r\n <li><strong>{{strings.SchemaTree.Welcome.Row5}}</strong></li>\r\n </ul>\r\n </div>\r\n </div>\r\n </sme-split-view-pane>\r\n <sme-split-view-content>\r\n <div class=\"sme-layout-absolute-phone-up sme-position-inset-none sme-padding-inset-xs sme-arrange-overflow-auto\">\r\n <div *ngIf=\"selectedSchemaTreeNode && selectedSchemaTreeNode.data.schema\">\r\n <h3 class=\"sme-margin-bottom-lg\">{{strings.PropertyForm.Header}}</h3>\r\n <sme-schema-form-content #propertyForm [schema]=\"currentPropertyFormSchema\" [(data)]=\"selectedSchemaTreeNode.data.schema\"\r\n [formController]=\"propertyFormController\"></sme-schema-form-content>\r\n <i class=\"sme-layout-block sme-margin-top-xxl\">{{strings.PropertyForm.Footer}}</i>\r\n </div>\r\n <div *ngIf=\"!(selectedSchemaTreeNode && selectedSchemaTreeNode.data.schema)\">\r\n <ul>\r\n <li>\r\n <strong>{{strings.PropertyForm.Welcome.Row1}}</strong>\r\n </li>\r\n <li *ngIf=\"schemaTreeData && schemaTreeData[0] &&schemaTreeData[0].children.length>0\">\r\n <strong>{{strings.PropertyForm.Welcome.Row2}}</strong>\r\n </li>\r\n <li>{{strings.PropertyForm.Welcome.Row3}}</li>\r\n <li>{{strings.PropertyForm.Welcome.Row4}}</li>\r\n <li>{{strings.PropertyForm.Welcome.Row5}}</li>\r\n <li>{{strings.PropertyForm.Welcome.Row6}}</li>\r\n <li>{{strings.PropertyForm.Welcome.Row7}}</li>\r\n </ul>\r\n </div>\r\n </div>\r\n </sme-split-view-content>\r\n</sme-split-view>\r\n", styles: [":host::sme-tree-table .sme-table-row button{padding:0;margin:0;min-width:auto;height:30px;width:19px}:host::sme-tree-table .sme-table-row .toolbar{display:none}:host::sme-tree-table .sme-table-row:hover .toolbar,:host::sme-tree-table .sme-table-row.selected .toolbar{display:block}\n"] }] }], function () { return [{ type: i0.ElementRef }]; }, { propertyForm: [{ type: ViewChild, args: ['propertyForm'] }], schemaTree: [{ type: ViewChild, args: ['schemaTree'] }], schema: [{ type: Input }] }); })(); export class PropertySchemaDataTypePropertiesViewModel { constructor(types) { this.dataTypeStore = new SchemaDataTypeStore(); this.isInitialized = false; this.isRoot = false; this.types = types; } get type() { return this.internalType; } set type(value) { this.internalType = value; this.formats = []; const allRegistrations = this.dataTypeStore.getAllRegistrations(); let dataOnlyRegistration; allRegistrations.forEach(registration => { if (!(registration.tags && registration.tags.indexOf('form-editor') !== -1) && SchemaPrimitiveType[value] === registration.type && ((!this.isRoot && !(registration.tags && registration.tags.indexOf('form-container') !== -1)) || (this.isRoot && registration.tags && registration.tags.indexOf('form-container') !== -1))) { if (registration.format === '*data-only') { dataOnlyRegistration = registration; } else { if (registration.isDefaultFormat) { this.formats.splice(0, 0, { value: registration.format, label: 'actual_string:' + registration.format + ' (default)' }); } else { this.formats.push({ value: registration.format, label: 'actual_string:' + registration.format }); } } } }); if (dataOnlyRegistration) { this.formats.push({ value: dataOnlyRegistration.format, label: 'actual_string:' + dataOnlyRegistration.format }); } if (this.isInitialized) { const defaultFormat = this.formats.filter(item => item.value === 'default')[0]; this.format = defaultFormat ? defaultFormat.value : this.formats[0].value; } } } export class PropertySchemaAdvancePropertiesViewModel { } export class PropertySchemaViewModel { constructor(propertySchemaModel, avaiableTypes, isRoot) { this.dataType = new PropertySchemaDataTypePropertiesViewModel(avaiableTypes); this.dataType.isRoot = isRoot; this.advanceProperties = new PropertySchemaAdvancePropertiesViewModel(); this.dataType.type = SchemaPrimitiveType[propertySchemaModel.type]; this.dataType.format = propertySchemaModel.format; this.name = propertySchemaModel.name; this.label = propertySchemaModel.label; this.advanceProperties.required = propertySchemaModel.required; this.advanceProperties.defaultValue = propertySchemaModel.defaultValue; this.advanceProperties.description = propertySchemaModel.description; this.advanceProperties.hideCondition = propertySchemaModel.hideCondition; this.advanceProperties.disabledCondition = propertySchemaModel.disabledCondition; this.advanceProperties.customValidation = propertySchemaModel.customValidation; this.advanceProperties.customAsyncValidation = SchemaUtilities.deepCopy(propertySchemaModel.customAsyncValidation); this.advanceProperties.readonlyCondition = propertySchemaModel.readonlyCondition; if (propertySchemaModel.type === SchemaPrimitiveType.Object) { this.advanceProperties.emptyByDefault = propertySchemaModel.emptyByDefault; } this.options = propertySchemaModel.options; if (SchemaPrimitiveType[this.dataType.type] === SchemaPrimitiveType.Object) { this.properties = propertySchemaModel.properties; } else if (SchemaPrimitiveType[this.dataType.type] === SchemaPrimitiveType.Array) { this.item = propertySchemaModel.item; } } toPropertySchemaModel() { const result = { type: SchemaPrimitiveType[this.dataType.type], format: this.dataType.format, name: this.name, label: this.label, required: this.advanceProperties.required, defaultValue: this.advanceProperties.defaultValue, description: this.advanceProperties.description, hideCondition: this.advanceProperties.hideCondition, disabledCondition: this.advanceProperties.disabledCondition, customValidation: this.advanceProperties.customValidation, customAsyncValidation: SchemaUtilities.deepCopy(this.advanceProperties.customAsyncValidation), readonlyCondition: this.advanceProperties.readonlyCondition, options: this.options }; if (SchemaPrimitiveType[this.dataType.type] === SchemaPrimitiveType.Object) { result.properties = this.properties; re