/***************************************************************************** * Open MCT, Copyright (c) 2014-2021, United States Government * as represented by the Administrator of the National Aeronautics and Space * Administration. All rights reserved. * * Open MCT is licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * * Open MCT includes source code licensed under additional open source * licenses. See the Open Source Licenses file (LICENSES.md) included with * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ import FormController from './FormController'; import FormProperties from './components/FormProperties.vue'; import Vue from 'vue'; export default class FormsAPI { constructor(openmct) { this.openmct = openmct; this.formController = new FormController(openmct); } /** * Control View Provider definition for a form control * @typedef ControlViewProvider * @property {function} show a function renders view in place of given element * This function accepts element, model and onChange function * element - html element (place holder) to render a row view * model - row data for rendering name, value etc for given row type * onChange - an onChange event callback funtion to keep track of any change in value * @property {function} destroy a callback function when a vue component gets destroyed */ /** * Create a new form control definition with a formControlViewProvider * this formControlViewProvider is used inside form overlay to show/render a form row * * @public * @param {String} controlName a form structure, array of section * @param {ControlViewProvider} controlViewProvider */ addNewFormControl(controlName, controlViewProvider) { this.formController.addControl(controlName, controlViewProvider); } /** * Get a ControlViewProvider for a given/stored form controlName * * @public * @param {String} controlName a form structure, array of section * @return {ControlViewProvider} */ getFormControl(controlName) { return this.formController.getControl(controlName); } /** * Section definition for formStructure * @typedef Section * @property {object} name Name of the section to display on Form * @property {string} cssClass class name for styling section * @property {array} rows collection of rows inside a section */ /** * Row definition for Section * @typedef Row * @property {string} control represents type of row to render * eg:autocomplete,composite,datetime,file-input,locator,numberfield,select,textarea,textfield * @property {string} cssClass class name for styling this row * @property {module:openmct.DomainObject} domainObject object to be used by row * @property {string} key id for this row * @property {string} name Name of the row to display on Form * @property {module:openmct.DomainObject} parent parent object to be used by row * @property {boolean} required is this row mandatory * @property {function} validate a function to validate this row on any changes */ /** * Show form inside an Overlay dialog with given form structure * * @public * @param {Array
} formStructure a form structure, array of section * @param {Object} options * @property {HTMLElement} element Parent Element to render a Form * @property {function} onChange a callback function when any changes detected * @property {function} onSave a callback function when form is submitted * @property {function} onDismiss a callback function when form is dismissed */ showForm(formStructure, { element, onChange } = {}) { const changes = {}; let overlay; let onDismiss; let onSave; const promise = new Promise((resolve, reject) => { onSave = onFormSave(resolve); onDismiss = onFormDismiss(reject); }); const vm = new Vue({ components: { FormProperties }, provide: { openmct: this.openmct }, data() { return { formStructure, onChange: onFormPropertyChange, onDismiss, onSave }; }, template: '' }).$mount(); const formElement = vm.$el; if (element) { element.append(formElement); } else { overlay = this.openmct.overlays.overlay({ element: vm.$el, size: 'small', onDestroy: () => vm.$destroy() }); } function onFormPropertyChange(data) { if (onChange) { onChange(data); } if (data.model) { const property = data.model.property; let key = data.model.key; if (property && property.length) { key = property.join('.'); } changes[key] = data.value; } } function onFormDismiss(dismiss) { return () => { if (element) { formElement.remove(); } else { overlay.dismiss(); } if (dismiss) { dismiss(); } }; } function onFormSave(save) { return () => { overlay.dismiss(); if (save) { save(changes); } }; } return promise; } }