mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
2 Commits
omm-large-
...
form-contr
Author | SHA1 | Date | |
---|---|---|---|
1a6ccc77fc | |||
a5946aa10e |
@ -26,7 +26,6 @@ define([
|
||||
"./src/controllers/EditObjectController",
|
||||
"./src/actions/EditAndComposeAction",
|
||||
"./src/actions/EditAction",
|
||||
"./src/actions/PropertiesAction",
|
||||
"./src/actions/SaveAction",
|
||||
"./src/actions/SaveAndStopEditingAction",
|
||||
"./src/actions/SaveAsAction",
|
||||
@ -55,7 +54,6 @@ define([
|
||||
EditObjectController,
|
||||
EditAndComposeAction,
|
||||
EditAction,
|
||||
PropertiesAction,
|
||||
SaveAction,
|
||||
SaveAndStopEditingAction,
|
||||
SaveAsAction,
|
||||
@ -143,22 +141,6 @@ define([
|
||||
"group": "action",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"key": "properties",
|
||||
"category": [
|
||||
"contextual",
|
||||
"view-control"
|
||||
],
|
||||
"implementation": PropertiesAction,
|
||||
"cssClass": "major icon-pencil",
|
||||
"name": "Edit Properties...",
|
||||
"group": "action",
|
||||
"priority": 10,
|
||||
"description": "Edit properties of this object.",
|
||||
"depends": [
|
||||
"dialogService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "save-and-stop-editing",
|
||||
"category": "save",
|
||||
|
@ -21,11 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../creation/CreateWizard',
|
||||
// '../creation/CreateWizard',
|
||||
'./SaveInProgressDialog'
|
||||
],
|
||||
function (
|
||||
CreateWizard,
|
||||
// CreateWizard,
|
||||
SaveInProgressDialog
|
||||
) {
|
||||
|
||||
@ -100,7 +100,8 @@ function (
|
||||
toUndirty = [];
|
||||
|
||||
function doWizardSave(parent) {
|
||||
var wizard = self.createWizard(parent);
|
||||
console.log('SaveAsAction');
|
||||
// var wizard = self.createWizard(parent);
|
||||
|
||||
return self.dialogService
|
||||
.getUserInput(wizard.getFormStructure(true),
|
||||
|
@ -252,6 +252,8 @@ define([
|
||||
|
||||
this.status = new api.StatusAPI(this);
|
||||
|
||||
this.forms = new api.FormsAPI.default(this);
|
||||
|
||||
this.router = new ApplicationRouter();
|
||||
|
||||
this.branding = BrandingAPI.default;
|
||||
|
@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
import _ from 'lodash';
|
||||
const INSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "link", "locate", "move", "link"];
|
||||
const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "properties", "move", "link", "remove", "locate"];
|
||||
const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "move", "link", "remove", "locate"];
|
||||
|
||||
export default class LegacyContextMenuAction {
|
||||
constructor(openmct, LegacyAction) {
|
||||
|
@ -21,41 +21,44 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'./time/TimeAPI',
|
||||
'./objects/ObjectAPI',
|
||||
'./composition/CompositionAPI',
|
||||
'./types/TypeRegistry',
|
||||
'./telemetry/TelemetryAPI',
|
||||
'./indicators/IndicatorAPI',
|
||||
'./notifications/NotificationAPI',
|
||||
'./Editor',
|
||||
'./menu/MenuAPI',
|
||||
'./actions/ActionsAPI',
|
||||
'./status/StatusAPI'
|
||||
'./composition/CompositionAPI',
|
||||
'./Editor',
|
||||
'./forms/FormsAPI',
|
||||
'./indicators/IndicatorAPI',
|
||||
'./menu/MenuAPI',
|
||||
'./notifications/NotificationAPI',
|
||||
'./objects/ObjectAPI',
|
||||
'./status/StatusAPI',
|
||||
'./telemetry/TelemetryAPI',
|
||||
'./time/TimeAPI',
|
||||
'./types/TypeRegistry'
|
||||
], function (
|
||||
TimeAPI,
|
||||
ObjectAPI,
|
||||
CompositionAPI,
|
||||
TypeRegistry,
|
||||
TelemetryAPI,
|
||||
IndicatorAPI,
|
||||
NotificationAPI,
|
||||
EditorAPI,
|
||||
MenuAPI,
|
||||
ActionsAPI,
|
||||
StatusAPI
|
||||
CompositionAPI,
|
||||
EditorAPI,
|
||||
FormsAPI,
|
||||
IndicatorAPI,
|
||||
MenuAPI,
|
||||
NotificationAPI,
|
||||
ObjectAPI,
|
||||
StatusAPI,
|
||||
TelemetryAPI,
|
||||
TimeAPI,
|
||||
TypeRegistry
|
||||
) {
|
||||
return {
|
||||
TimeAPI: TimeAPI,
|
||||
ObjectAPI: ObjectAPI,
|
||||
CompositionAPI: CompositionAPI,
|
||||
TypeRegistry: TypeRegistry,
|
||||
TelemetryAPI: TelemetryAPI,
|
||||
IndicatorAPI: IndicatorAPI,
|
||||
NotificationAPI: NotificationAPI.default,
|
||||
EditorAPI: EditorAPI,
|
||||
MenuAPI: MenuAPI.default,
|
||||
ActionsAPI: ActionsAPI.default,
|
||||
StatusAPI: StatusAPI.default
|
||||
CompositionAPI: CompositionAPI,
|
||||
EditorAPI: EditorAPI,
|
||||
FormsAPI: FormsAPI,
|
||||
IndicatorAPI: IndicatorAPI,
|
||||
MenuAPI: MenuAPI.default,
|
||||
NotificationAPI: NotificationAPI.default,
|
||||
ObjectAPI: ObjectAPI,
|
||||
StatusAPI: StatusAPI.default,
|
||||
TelemetryAPI: TelemetryAPI,
|
||||
TimeAPI: TimeAPI,
|
||||
TypeRegistry: TypeRegistry,
|
||||
};
|
||||
});
|
||||
|
178
src/api/forms/CreateWizard.js
Normal file
178
src/api/forms/CreateWizard.js
Normal file
@ -0,0 +1,178 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* A class for capturing user input data from an object creation
|
||||
* dialog, and populating a domain object with that data.
|
||||
*
|
||||
* @param {DomainObject} domainObject the newly created object to
|
||||
* populate with user input
|
||||
* @param {DomainObject} parent the domain object to serve as
|
||||
* the initial parent for the created object, in the dialog
|
||||
* @memberof platform/commonUI/browse
|
||||
* @constructor
|
||||
*/
|
||||
export default class CreateWizard {
|
||||
|
||||
constructor(domainObject, parent, openmct) {
|
||||
this.type = openmct.types.get(domainObject.type);
|
||||
this.model = domainObject;
|
||||
this.domainObject = domainObject;
|
||||
this.properties = this.type.definition.form || [];
|
||||
this.parent = parent;
|
||||
this.openmct = openmct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form model for this wizard; this is a description
|
||||
* that will be rendered to an HTML form. See the
|
||||
* platform/forms bundle
|
||||
* @param {boolean} includeLocation if true, a 'location' section
|
||||
* will be included that will allow the user to select the location
|
||||
* of the newly created object, otherwise the .location property of
|
||||
* the model will be used.
|
||||
* @return {FormModel} formModel the form model to
|
||||
* show in the create dialog
|
||||
*/
|
||||
getFormStructure(includeLocation) {
|
||||
let sections = [];
|
||||
let domainObject = this.domainObject;
|
||||
let self = this;
|
||||
|
||||
function validateLocation(parent) {
|
||||
return parent && self.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
|
||||
}
|
||||
|
||||
sections.push({
|
||||
name: "Properties",
|
||||
rows: this.properties.map(function (property, index) {
|
||||
// Property definition is same as form row definition
|
||||
let row = JSON.parse(JSON.stringify(property));
|
||||
|
||||
// Use index as the key into the formValue;
|
||||
// this correlates to the indexing provided by
|
||||
// getInitialFormValue
|
||||
row.key = index;
|
||||
|
||||
return row;
|
||||
}).filter(function (row) {
|
||||
// Only show rows which have defined controls
|
||||
return row && row.control;
|
||||
})
|
||||
});
|
||||
|
||||
// Ensure there is always a "save in" section
|
||||
if (includeLocation) {
|
||||
sections.push({
|
||||
name: 'Location',
|
||||
cssClass: "grows",
|
||||
rows: [{
|
||||
name: "Save In",
|
||||
control: "locator",
|
||||
validate: validateLocation.bind(this),
|
||||
key: "createParent"
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
sections: sections,
|
||||
name: "Create a New " + this.type.definition.name
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Given some form input values and a domain object, populate the
|
||||
* domain object used to create this wizard from the given form values.
|
||||
* @param formValue
|
||||
* @returns {DomainObject}
|
||||
*/
|
||||
populateObjectFromInput(formValue) {
|
||||
let parent = this.getLocation(formValue);
|
||||
let formModel = this.createModel(formValue);
|
||||
|
||||
formModel.location = parent.getId();
|
||||
|
||||
this.updateNamespaceFromParent(parent);
|
||||
|
||||
this.domainObject.useCapability("mutation", function () {
|
||||
return formModel;
|
||||
});
|
||||
|
||||
return this.domainObject;
|
||||
}
|
||||
|
||||
updateNamespaceFromParent(parent) {
|
||||
let childIdentifier = this.domainObject.useCapability('adapter').identifier;
|
||||
let parentIdentifier = parent.useCapability('adapter').identifier;
|
||||
childIdentifier.namespace = parentIdentifier.namespace;
|
||||
this.domainObject.id = this.openmct.objects.makeKeyString(childIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the initial value for the form being described.
|
||||
* This will include the values for all properties described
|
||||
* in the structure.
|
||||
*
|
||||
* @returns {object} the initial value of the form
|
||||
*/
|
||||
getInitialFormValue() {
|
||||
// Start with initial values for properties
|
||||
let model = this.model;
|
||||
let formValue = this.properties.map(function (property) {
|
||||
return property.getValue(model);
|
||||
});
|
||||
|
||||
// Include the createParent
|
||||
formValue.createParent = this.parent;
|
||||
|
||||
return formValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on a populated form, get the domain object which
|
||||
* should be used as a parent for the newly-created object.
|
||||
* @private
|
||||
* @return {DomainObject}
|
||||
*/
|
||||
getLocation(formValue) {
|
||||
return formValue.createParent || this.parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the domain object model for a newly-created object,
|
||||
* based on user input read from a formModel.
|
||||
* @private
|
||||
* @return {object} the domain object model
|
||||
*/
|
||||
createModel(formValue) {
|
||||
// Clone
|
||||
let newModel = JSON.parse(JSON.stringify(this.domainObject));
|
||||
|
||||
// Update all properties
|
||||
this.properties.forEach(function (property, index) {
|
||||
property.setValue(newModel, formValue[index]);
|
||||
});
|
||||
|
||||
return newModel;
|
||||
}
|
||||
}
|
40
src/api/forms/FormsAPI.js
Normal file
40
src/api/forms/FormsAPI.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*****************************************************************************
|
||||
* 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 EditPropertiesAction from './actions/EditPropertiesAction';
|
||||
|
||||
export default class FormsAPI {
|
||||
constructor(openmct) {
|
||||
openmct.actions.register(new EditPropertiesAction(openmct));
|
||||
}
|
||||
|
||||
addControl(name, actions) {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
showForm() {
|
||||
|
||||
}
|
||||
|
||||
save() {
|
||||
|
||||
}
|
||||
}
|
108
src/api/forms/actions/CreateAction.js
Normal file
108
src/api/forms/actions/CreateAction.js
Normal file
@ -0,0 +1,108 @@
|
||||
/*****************************************************************************
|
||||
* 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 PropertiesAction from './PropertiesAction';
|
||||
import FormProperties from '../components/Form-properties.vue';
|
||||
import CreateWizard from '../CreateWizard';
|
||||
import Vue from "vue";
|
||||
|
||||
export default class CreateAction extends PropertiesAction {
|
||||
constructor(openmct, key, parentDomainObject) {
|
||||
super(openmct);
|
||||
|
||||
this.key = key;
|
||||
this.parentDomainObject = parentDomainObject;
|
||||
}
|
||||
|
||||
invoke() {
|
||||
const definition = this._getTypeDefination(this.key);
|
||||
|
||||
console.log('CreateAction invoke, Show form', definition.form);
|
||||
let newModel = {
|
||||
type: this.key,
|
||||
location: this.openmct.objects.makeKeyString(this.parentDomainObject.identifier)
|
||||
};
|
||||
if (definition.initialize) {
|
||||
definition.initialize(newModel);
|
||||
}
|
||||
|
||||
let openmct = this.openmct;
|
||||
newModel.modified = Date.now();
|
||||
let wizard = new CreateWizard(newModel, this.parentDomainObject, openmct);
|
||||
let formStructure = wizard.getFormStructure(true);
|
||||
// let initialFormValue = wizard.getInitialFormValue();
|
||||
// if save navigateAndEdit
|
||||
// this.openmct.editor.cancel();
|
||||
this.showForm(formStructure);
|
||||
}
|
||||
|
||||
showForm(formStructure) {
|
||||
let vm = new Vue({
|
||||
components: { FormProperties },
|
||||
provide: {
|
||||
openmct: this.openmct
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formStructure
|
||||
};
|
||||
},
|
||||
template: '<form-properties :model="formStructure"></form-properties>'
|
||||
}).$mount();
|
||||
|
||||
function dismissDialog(overlay, initialize) {
|
||||
overlay.dismiss();
|
||||
}
|
||||
|
||||
let overlay = this.openmct.overlays.overlay({
|
||||
element: vm.$el, //TODO: create and show new form component
|
||||
size: 'small',
|
||||
buttons: [
|
||||
{
|
||||
label: 'OK',
|
||||
emphasis: 'true',
|
||||
callback: () => dismissDialog(overlay, true)
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: () => dismissDialog(overlay, false)
|
||||
}
|
||||
],
|
||||
onDestroy: () => vm.$destroy()
|
||||
});
|
||||
}
|
||||
|
||||
navigateAndEdit(object) {
|
||||
let objectPath = object.getCapability('context').getPath();
|
||||
let url = '#/browse/' + objectPath
|
||||
.slice(1)
|
||||
.map(function (o) {
|
||||
return o && openmct.objects.makeKeyString(o.getId());
|
||||
})
|
||||
.join('/');
|
||||
|
||||
window.location.href = url;
|
||||
|
||||
if (isFirstViewEditable(object.useCapability('adapter'), objectPath)) {
|
||||
openmct.editor.edit();
|
||||
}
|
||||
}
|
||||
}
|
73
src/api/forms/actions/EditPropertiesAction.js
Normal file
73
src/api/forms/actions/EditPropertiesAction.js
Normal file
@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
* 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 PropertiesAction from './PropertiesAction';
|
||||
|
||||
export default class EditPropertiesAction extends PropertiesAction {
|
||||
constructor(openmct) {
|
||||
super(openmct);
|
||||
|
||||
this.name = 'Edit Properties...';
|
||||
this.key = 'properties';
|
||||
this.description = 'Edit properties of this object.';
|
||||
this.cssClass = 'major icon-pencil';
|
||||
this.hideInDefaultMenu = true;
|
||||
this.group= 'action';
|
||||
this.priority= 10;
|
||||
}
|
||||
|
||||
appliesTo(objectPath) {
|
||||
return Boolean(this._getForm(objectPath));
|
||||
}
|
||||
|
||||
invoke(objectPath) {
|
||||
const formElements = this._getFormElements(objectPath);
|
||||
|
||||
// Start:Testing
|
||||
const parent = document.createElement('div');
|
||||
formElements.forEach(e => {
|
||||
const child = document.createElement('div');
|
||||
const spanKey = document.createElement('span');
|
||||
const spanValue = document.createElement('span');
|
||||
|
||||
spanKey.textContent = e.key;
|
||||
spanValue.textContent = e.value;
|
||||
child.appendChild(spanKey);
|
||||
child.appendChild(spanValue);
|
||||
parent.appendChild(child);
|
||||
});
|
||||
// End:Testing
|
||||
|
||||
let overlay = this.openmct.overlays.overlay({
|
||||
element: parent, //TODO: create and show new form component
|
||||
size: 'small',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Done',
|
||||
// TODO: save form values into domain object properties
|
||||
callback: () => overlay.dismiss()
|
||||
}
|
||||
],
|
||||
onDestroy: () => {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
91
src/api/forms/actions/PropertiesAction.js
Normal file
91
src/api/forms/actions/PropertiesAction.js
Normal file
@ -0,0 +1,91 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
export default class PropertiesAction {
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
}
|
||||
|
||||
invoke(objectPath) {
|
||||
// Start:Testing
|
||||
// const parent = document.createElement('div');
|
||||
// formElements.forEach(e => {
|
||||
// const child = document.createElement('div');
|
||||
// const spanKey = document.createElement('span');
|
||||
// const spanValue = document.createElement('span');
|
||||
|
||||
// spanKey.textContent = e.key;
|
||||
// spanValue.textContent = e.value;
|
||||
// child.appendChild(spanKey);
|
||||
// child.appendChild(spanValue);
|
||||
// parent.appendChild(child);
|
||||
// });
|
||||
// End:Testing
|
||||
|
||||
// let overlay = this.openmct.overlays.overlay({
|
||||
// element: parent, //TODO: create and show new form component
|
||||
// size: 'small',
|
||||
// buttons: [
|
||||
// {
|
||||
// label: 'Done',
|
||||
// // TODO: save form values into domain object properties
|
||||
// callback: () => overlay.dismiss()
|
||||
// }
|
||||
// ],
|
||||
// onDestroy: () => {
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getForm(objectPath) {
|
||||
const definition = this._getTypeDefination(objectPath[0].type);
|
||||
|
||||
return definition.form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getFormElements(objectPath) {
|
||||
const form = this._getForm(objectPath);
|
||||
const domainObject = objectPath[0];
|
||||
const formElements = [];
|
||||
form.forEach(element => {
|
||||
const value = element.property.reduce((acc, property) => acc[property], domainObject);
|
||||
formElements.push({key: element.key, value});
|
||||
});
|
||||
|
||||
return formElements;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getTypeDefination(type) {
|
||||
const TypeDefinition = this.openmct.types.get(type);
|
||||
|
||||
return TypeDefinition.definition;
|
||||
}
|
||||
}
|
53
src/api/forms/components/Form-properties.vue
Normal file
53
src/api/forms/components/Form-properties.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<form name="mctForm"
|
||||
novalidate
|
||||
class="form c-form"
|
||||
autocomplete="off"
|
||||
>
|
||||
<span v-for="section in model.sections"
|
||||
:key="section.name"
|
||||
class="l-form-section c-form__section"
|
||||
:class="section.cssClass"
|
||||
>
|
||||
<h2 class="c-form__header"
|
||||
ng-if="section.name"
|
||||
>
|
||||
{{ section.name }}
|
||||
</h2>
|
||||
<div v-for="(row, index) in section.rows"
|
||||
:key="row.name"
|
||||
>
|
||||
<form-row :css-class="section.cssClass"
|
||||
:first="index < 1"
|
||||
:row="row"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormRow from "@/api/forms/components/FormRow.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormRow
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.model, this.value);
|
||||
}
|
||||
};
|
||||
</script>
|
115
src/api/forms/components/FormRow.vue
Normal file
115
src/api/forms/components/FormRow.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<div class="form-row c-form__row validates"
|
||||
:class="rowClass"
|
||||
>
|
||||
<div class="c-form__row__label label flex-elem"
|
||||
:title="row.description"
|
||||
>
|
||||
{{ row.name }}
|
||||
</div>
|
||||
<div class="c-form__row__controls controls flex-elem">
|
||||
<div v-if="row.control && row.control !== 'locator'"
|
||||
class="c-form__controls-wrapper wrapper"
|
||||
>
|
||||
<component
|
||||
:is="row.control"
|
||||
:key="row.key"
|
||||
:ref="`form-control-${row.key}`"
|
||||
:model="row"
|
||||
:required="isRequired"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TextField from "@/api/forms/components/controls/TextField.vue";
|
||||
import NumberField from "@/api/forms/components/controls/NumberField.vue";
|
||||
import Composite from "@/api/forms/components/controls/Composite.vue";
|
||||
import AutoCompleteField from "@/api/forms/components/controls/AutoCompleteField.vue";
|
||||
|
||||
const CONTROL_TYPE_VIEW_MAP = {
|
||||
'textfield': TextField,
|
||||
'numberfield': NumberField,
|
||||
'composite': Composite,
|
||||
'autocomplete': AutoCompleteField
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'FormRow',
|
||||
components: CONTROL_TYPE_VIEW_MAP,
|
||||
props: {
|
||||
cssClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
first: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: true
|
||||
},
|
||||
row: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
valid: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isRequired() {
|
||||
//TODO: Check if field is required
|
||||
return false;
|
||||
},
|
||||
rowClass() {
|
||||
let cssClass = this.cssClass;
|
||||
|
||||
if (this.first === true) {
|
||||
cssClass = `${cssClass} first`;
|
||||
}
|
||||
|
||||
if (this.row.required) {
|
||||
cssClass = `${cssClass} req`;
|
||||
}
|
||||
|
||||
if (this.row.layout === 'controls-first') {
|
||||
cssClass = `${cssClass} l-controls-first`;
|
||||
}
|
||||
|
||||
if (this.row.layout === 'controls-under') {
|
||||
cssClass = `${cssClass} l-controls-under`;
|
||||
}
|
||||
|
||||
if (this.valid === true) {
|
||||
cssClass = `${cssClass} valid`;
|
||||
} else {
|
||||
cssClass = `${cssClass} invalid`;
|
||||
}
|
||||
|
||||
return cssClass;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// Check if an element is defined; the map step of isNonEmpty
|
||||
isDefined(element) {
|
||||
return typeof element !== 'undefined';
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if an array contains anything other than
|
||||
* undefined elements.
|
||||
* @param {Array} value the array to check
|
||||
* @returns {boolean} true if any non-undefined
|
||||
* element is in the array
|
||||
* @memberof platform/forms.CompositeController#
|
||||
*/
|
||||
isNonEmpty(value) {
|
||||
return Array.isArray(value) && value.some(this.isDefined);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
172
src/api/forms/components/controls/AutoCompleteField.vue
Normal file
172
src/api/forms/components/controls/AutoCompleteField.vue
Normal file
@ -0,0 +1,172 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<template>
|
||||
<div class="form-control autocomplete">
|
||||
<input v-model="field"
|
||||
class="autocompleteInput"
|
||||
type="text"
|
||||
@change="filterOptions(field)"
|
||||
@click="inputClicked()"
|
||||
@keydown="keyDown($event)"
|
||||
>
|
||||
<span class="icon-arrow-down"
|
||||
@click="arrowClicked()"
|
||||
></span>
|
||||
<div v-show="hideOptions"
|
||||
class="autocompleteOptions"
|
||||
@blur="hideOptions = true"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="opt in filteredOptions"
|
||||
:key="opt.optionId"
|
||||
:class="{'optionPreSelected': optionIndex === opt.optionId}"
|
||||
@click="fillInput(opt.name)"
|
||||
@mouseover="optionMouseover(opt.optionId)"
|
||||
>
|
||||
<span class="optionText">{{ opt.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const key = {
|
||||
down: 40,
|
||||
up: 38,
|
||||
enter: 13
|
||||
};
|
||||
|
||||
export default {
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hideOptions: true,
|
||||
filteredOptions: [],
|
||||
optionIndex: 0,
|
||||
field: ''
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.options = this.model.options;
|
||||
this.autocompleteInputElement = this.$el.getElementsByClassName('autocompleteInput')[0];
|
||||
if (this.options[0].name) {
|
||||
// If "options" include name, value pair
|
||||
this.optionNames = this.options.map((opt) => {
|
||||
return opt.name;
|
||||
});
|
||||
} else {
|
||||
// If options is only an array of string.
|
||||
this.optionNames = this.options;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fillInputWithIndexedOption() {
|
||||
if (this.filteredOptions[this.optionIndex]) {
|
||||
this.ngModel[this.field] = this.filteredOptions[this.optionIndex].name;
|
||||
}
|
||||
},
|
||||
|
||||
decrementOptionIndex() {
|
||||
if (this.optionIndex === 0) {
|
||||
this.optionIndex = this.filteredOptions.length;
|
||||
}
|
||||
|
||||
this.optionIndex--;
|
||||
this.fillInputWithIndexedOption();
|
||||
},
|
||||
|
||||
incrementOptionIndex() {
|
||||
if (this.optionIndex === this.filteredOptions.length - 1) {
|
||||
this.optionIndex = -1;
|
||||
}
|
||||
|
||||
this.optionIndex++;
|
||||
this.fillInputWithIndexedOption();
|
||||
},
|
||||
|
||||
fillInputWithString(string) {
|
||||
this.hideOptions = true;
|
||||
this.ngModel[this.field] = string;
|
||||
},
|
||||
|
||||
showOptions(string) {
|
||||
this.hideOptions = false;
|
||||
this.filterOptions(string);
|
||||
this.optionIndex = 0;
|
||||
},
|
||||
keyDown($event) {
|
||||
if (this.filteredOptions) {
|
||||
let keyCode = $event.keyCode;
|
||||
switch (keyCode) {
|
||||
case key.down:
|
||||
this.incrementOptionIndex();
|
||||
break;
|
||||
case key.up:
|
||||
$event.preventDefault(); // Prevents cursor jumping back and forth
|
||||
this.decrementOptionIndex();
|
||||
break;
|
||||
case key.enter:
|
||||
if (this.filteredOptions[this.optionIndex]) {
|
||||
this.fillInputWithString(this.filteredOptions[this.optionIndex].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
filterOptions() {
|
||||
this.hideOptions = false;
|
||||
this.filteredOptions = this.optionNames.filter((option) => {
|
||||
return option.toLowerCase().indexOf(this.field.toLowerCase()) >= 0;
|
||||
}).map((option, index) => {
|
||||
return {
|
||||
optionId: index,
|
||||
name: option
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
inputClicked() {
|
||||
this.autocompleteInputElement.select();
|
||||
this.showOptions(this.autocompleteInputElement.value);
|
||||
},
|
||||
|
||||
arrowClicked() {
|
||||
this.autocompleteInputElement.select();
|
||||
this.showOptions('');
|
||||
},
|
||||
|
||||
fillInput(string) {
|
||||
this.fillInputWithString(string);
|
||||
},
|
||||
|
||||
optionMouseover(optionId) {
|
||||
this.optionIndex = optionId;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
46
src/api/forms/components/controls/Composite.vue
Normal file
46
src/api/forms/components/controls/Composite.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<template>
|
||||
<span>
|
||||
<composite-item v-for="(item, index) in model.items"
|
||||
:key="item.name"
|
||||
:first="index < 1"
|
||||
:item="item"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CompositeItem from "@/api/forms/components/controls/CompositeItem.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CompositeItem
|
||||
},
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
57
src/api/forms/components/controls/CompositeItem.vue
Normal file
57
src/api/forms/components/controls/CompositeItem.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<template>
|
||||
<div :class="compositeCssClass">
|
||||
<form-row :css-class="item.cssClass"
|
||||
:first="first"
|
||||
:row="item"
|
||||
/>
|
||||
<span class="composite-control-label">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FormRow from "@/api/forms/components/FormRow.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormRow
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
first: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compositeCssClass() {
|
||||
return `l-composite-control l-${this.item.control}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
58
src/api/forms/components/controls/NumberField.vue
Normal file
58
src/api/forms/components/controls/NumberField.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<template>
|
||||
<span class="form-control shell">
|
||||
<span class="field control"
|
||||
:class="model.cssClass"
|
||||
>
|
||||
<input v-model="field"
|
||||
type="number"
|
||||
:min="model.min"
|
||||
:max="model.max"
|
||||
:step="model.step"
|
||||
@blur="blur()"
|
||||
>
|
||||
<!-- ng-pattern="ngPattern"-->
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
field: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
blur() {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
56
src/api/forms/components/controls/TextField.vue
Normal file
56
src/api/forms/components/controls/TextField.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<template>
|
||||
<span class="form-control shell">
|
||||
<span class="field control"
|
||||
:class="model.cssClass"
|
||||
>
|
||||
<input v-model="field"
|
||||
type="text"
|
||||
:size="model.size"
|
||||
@blur="blur()"
|
||||
>
|
||||
<!-- ng-pattern="ngPattern"-->
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
model: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
field: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
blur() {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -40,7 +40,6 @@ const DEFAULTS = [
|
||||
'platform/features/clock',
|
||||
'platform/features/hyperlink',
|
||||
'platform/features/timeline',
|
||||
'platform/forms',
|
||||
'platform/identity',
|
||||
'platform/persistence/aggregator',
|
||||
'platform/persistence/queue',
|
||||
@ -85,7 +84,6 @@ define([
|
||||
'../platform/features/hyperlink/bundle',
|
||||
'../platform/features/static-markup/bundle',
|
||||
'../platform/features/timeline/bundle',
|
||||
'../platform/forms/bundle',
|
||||
'../platform/framework/bundle',
|
||||
'../platform/framework/src/load/Bundle',
|
||||
'../platform/identity/bundle',
|
||||
|
@ -12,7 +12,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CreateAction from '../../../platform/commonUI/edit/src/creation/CreateAction';
|
||||
import CreateAction from '@/api/forms/actions/CreateAction';
|
||||
import objectUtils from 'objectUtils';
|
||||
|
||||
export default {
|
||||
@ -74,6 +74,12 @@ export default {
|
||||
// 4. perform action.
|
||||
return this.openmct.objects.get(this.openmct.router.path[0].identifier)
|
||||
.then((currentObject) => {
|
||||
console.log('type', key);
|
||||
const createAction = new CreateAction(this.openmct, key, currentObject);
|
||||
|
||||
createAction.invoke();
|
||||
|
||||
|
||||
let legacyContextualParent = this.convertToLegacy(currentObject);
|
||||
let legacyType = this.openmct.$injector.get('typeService').getType(key);
|
||||
let context = {
|
||||
@ -87,7 +93,6 @@ export default {
|
||||
this.openmct
|
||||
);
|
||||
|
||||
return action.perform();
|
||||
});
|
||||
},
|
||||
convertToLegacy(domainObject) {
|
||||
|
Reference in New Issue
Block a user