merge display layout view config with components, add line view.
* Hacky WIP * WIP * check for 'domainobject' in data transfer * Metadata manager can return default display value * Refactor subobject and telemetry views to use layout frame * Use data domainObject * Get metadata for selected object. * Don't inject lodash via vue * move selection to specific layout types * restore toolbar functionality * Support creating line * Add controls for setting x, y, x2 and y2 for lines from the toolbar. * Initial attempt at resizing lines * Check for duplicate panel * line resize handles working * Get Text and Box elements working. * Refactor image view to use layout frame * Fix drill in * Check for object before accessing the identifier to avoid type error. * Add inspectable class if item is subobject or telemetry view. * Delete unused files * remove unused imports * Fix typos * Fix cssClass and objectPath * object can be undefined so check for it not being undefined before adding a listener. * Set cssClass when domain object is available * Get user input for text and image in the toolbar when adding element.
This commit is contained in:
committed by
Pete Richards
parent
c6a181a2e7
commit
c1ef701eb2
@@ -37,15 +37,16 @@
|
||||
v-if="gridSize[1] >= 3"
|
||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
||||
</div>
|
||||
<layout-item v-for="(item, index) in layoutItems"
|
||||
class="l-layout__frame"
|
||||
:key="index"
|
||||
:item="item"
|
||||
:gridSize="gridSize"
|
||||
@drilledIn="updateDrilledInState"
|
||||
@dragInProgress="updatePosition"
|
||||
@endDrag="endDrag">
|
||||
</layout-item>
|
||||
<component v-for="(item, index) in layoutItems"
|
||||
:is="item.type"
|
||||
:item="item"
|
||||
:gridSize="gridSize"
|
||||
:initSelect="initSelectIndex === index"
|
||||
:index="index"
|
||||
@drilledIn="updateDrilledIn"
|
||||
@endDrag="endDrag"
|
||||
>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -85,112 +86,74 @@
|
||||
|
||||
|
||||
<script>
|
||||
import LayoutItem from './LayoutItem.vue';
|
||||
import TelemetryViewConfiguration from './../TelemetryViewConfiguration.js'
|
||||
import SubobjectViewConfiguration from './../SubobjectViewConfiguration.js'
|
||||
import ElementViewConfiguration from './../ElementViewConfiguration.js'
|
||||
import uuid from 'uuid';
|
||||
|
||||
const DEFAULT_GRID_SIZE = [10, 10];
|
||||
import SubobjectView from './SubobjectView.vue'
|
||||
import TelemetryView from './TelemetryView.vue'
|
||||
import BoxView from './BoxView.vue'
|
||||
import TextView from './TextView.vue'
|
||||
import LineView from './LineView.vue'
|
||||
import ImageView from './ImageView.vue'
|
||||
|
||||
const ITEM_TYPE_VIEW_MAP = {
|
||||
'subobject-view': SubobjectView,
|
||||
'telemetry-view': TelemetryView,
|
||||
'box-view': BoxView,
|
||||
'line-view': LineView,
|
||||
'text-view': TextView,
|
||||
'image-view': ImageView
|
||||
};
|
||||
|
||||
function getItemDefinition(itemType, ...options) {
|
||||
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
||||
|
||||
if (!itemView) {
|
||||
throw `Invalid itemType: ${itemType}`;
|
||||
}
|
||||
|
||||
return itemView.makeDefinition(...options);
|
||||
}
|
||||
|
||||
export default {
|
||||
data() {
|
||||
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
||||
return {
|
||||
gridSize: [],
|
||||
layoutItems: [],
|
||||
drilledIn: undefined
|
||||
drilledIn: undefined,
|
||||
internalDomainObject: domainObject,
|
||||
initSelectIndex: undefined
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
gridSize() {
|
||||
return this.internalDomainObject.configuration.layoutGrid;
|
||||
},
|
||||
layoutItems() {
|
||||
return this.internalDomainObject.configuration.items;
|
||||
}
|
||||
},
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: ['domainObject'],
|
||||
components: {
|
||||
LayoutItem
|
||||
},
|
||||
components: ITEM_TYPE_VIEW_MAP,
|
||||
methods: {
|
||||
getAlphanumerics() {
|
||||
let alphanumerics = this.newDomainObject.configuration.alphanumerics || [];
|
||||
alphanumerics.forEach((alphanumeric, index) => {
|
||||
alphanumeric.index = index;
|
||||
this.makeTelemetryItem(alphanumeric, false);
|
||||
});
|
||||
},
|
||||
getElements() {
|
||||
let elements = this.newDomainObject.configuration.elements || [];
|
||||
elements.forEach((element, index) => {
|
||||
element.index = index;
|
||||
this.makeElementItem(element, false);
|
||||
});
|
||||
},
|
||||
makeSubobjectItem(panel, initSelect) {
|
||||
let id = this.openmct.objects.makeKeyString(panel.domainObject.identifier);
|
||||
let config = new SubobjectViewConfiguration({
|
||||
domainObject: this.newDomainObject,
|
||||
panel: panel,
|
||||
id: id,
|
||||
openmct: openmct,
|
||||
gridSize: this.gridSize
|
||||
});
|
||||
this.layoutItems.push({
|
||||
id: id,
|
||||
domainObject: panel.domainObject,
|
||||
drilledIn: this.isItemDrilledIn(id),
|
||||
initSelect: initSelect,
|
||||
type: 'subobject-view',
|
||||
config: config
|
||||
});
|
||||
},
|
||||
makeTelemetryItem(alphanumeric, initSelect) {
|
||||
let id = this.openmct.objects.makeKeyString(alphanumeric.identifier);
|
||||
this.openmct.objects.get(id).then(domainObject => {
|
||||
let config = new TelemetryViewConfiguration({
|
||||
domainObject: this.newDomainObject,
|
||||
alphanumeric: alphanumeric,
|
||||
openmct: openmct,
|
||||
gridSize: this.gridSize
|
||||
});
|
||||
this.layoutItems.push({
|
||||
id: id,
|
||||
domainObject: domainObject,
|
||||
initSelect: initSelect,
|
||||
type: 'telemetry-view',
|
||||
config: config
|
||||
});
|
||||
});
|
||||
},
|
||||
makeElementItem(element, initSelect) {
|
||||
let config = new ElementViewConfiguration({
|
||||
domainObject: this.newDomainObject,
|
||||
element: element,
|
||||
openmct: openmct,
|
||||
gridSize: this.gridSize
|
||||
});
|
||||
this.layoutItems.push({
|
||||
initSelect: initSelect,
|
||||
type: element.type + '-view',
|
||||
config: config
|
||||
});
|
||||
addElement(itemType, element) {
|
||||
this.addItem(itemType + '-view', element);
|
||||
},
|
||||
setSelection(selection) {
|
||||
if (selection.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateDrilledInState();
|
||||
this.updateDrilledIn();
|
||||
},
|
||||
updateDrilledInState(id) {
|
||||
this.drilledIn = id;
|
||||
this.layoutItems.forEach(function (item) {
|
||||
updateDrilledIn(drilledInItem) {
|
||||
let identifier = drilledInItem && this.openmct.objects.makeKeyString(drilledInItem.identifier);
|
||||
this.drilledIn = identifier;
|
||||
this.layoutItems.forEach(item => {
|
||||
if (item.type === 'subobject-view') {
|
||||
item.drilledIn = item.id === id;
|
||||
item.drilledIn = this.openmct.objects.makeKeyString(item.identifier) === identifier;
|
||||
}
|
||||
});
|
||||
},
|
||||
isItemDrilledIn(id) {
|
||||
return this.drilledIn === id;
|
||||
},
|
||||
updatePosition(item, newPosition) {
|
||||
item.config.newPosition = newPosition;
|
||||
item.config.updateStyle(newPosition);
|
||||
},
|
||||
bypassSelection($event) {
|
||||
if (this.dragInProgress) {
|
||||
if ($event) {
|
||||
@@ -199,59 +162,56 @@
|
||||
return;
|
||||
}
|
||||
},
|
||||
endDrag(item) {
|
||||
endDrag(item, updates) {
|
||||
this.dragInProgress = true;
|
||||
setTimeout(function () {
|
||||
this.dragInProgress = false;
|
||||
}.bind(this), 0);
|
||||
// TODO: emit "finishResizing" for view components to mutate position?
|
||||
item.config.mutatePosition();
|
||||
|
||||
let index = this.layoutItems.indexOf(item);
|
||||
Object.assign(item, updates);
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
},
|
||||
mutate(path, value) {
|
||||
this.openmct.objects.mutate(this.newDomainObject, path, value);
|
||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||
},
|
||||
handleDrop($event) {
|
||||
if (!$event.dataTransfer.types.includes('domainobject')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('domainObject'));
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('domainobject'));
|
||||
let elementRect = this.$el.getBoundingClientRect();
|
||||
this.droppedObjectPosition = [
|
||||
let droppedObjectPosition = [
|
||||
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
||||
Math.floor(($event.pageY - elementRect.top) / this.gridSize[1])
|
||||
];
|
||||
|
||||
if (this.isTelemetry(domainObject)) {
|
||||
this.addAlphanumeric(domainObject, this.droppedObjectPosition);
|
||||
this.addItem('telemetry-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
this.checkForDuplicatePanel(domainObject);
|
||||
}
|
||||
},
|
||||
checkForDuplicatePanel(domainObject) {
|
||||
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
let panels = this.newDomainObject.configuration.panels;
|
||||
let identifier = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
if (panels && panels[id]) {
|
||||
let prompt = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: "This item is already in layout and will not be added again.",
|
||||
buttons: [
|
||||
{
|
||||
label: 'OK',
|
||||
callback: function () {
|
||||
prompt.dismiss();
|
||||
if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', domainObject, droppedObjectPosition);
|
||||
} else {
|
||||
let prompt = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: "This item is already in layout and will not be added again.",
|
||||
buttons: [
|
||||
{
|
||||
label: 'OK',
|
||||
callback: function () {
|
||||
prompt.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
addAlphanumeric(domainObject, position) {
|
||||
let alphanumerics = this.newDomainObject.configuration.alphanumerics || [];
|
||||
let alphanumeric = TelemetryViewConfiguration.create(domainObject, position, this.openmct);
|
||||
alphanumeric.index = alphanumerics.push(alphanumeric) - 1;
|
||||
this.mutate("configuration.alphanumerics", alphanumerics);
|
||||
this.makeTelemetryItem(alphanumeric, true);
|
||||
},
|
||||
handleDragOver($event){
|
||||
$event.preventDefault();
|
||||
},
|
||||
@@ -263,63 +223,58 @@
|
||||
return false;
|
||||
}
|
||||
},
|
||||
addSubobject(domainObject) {
|
||||
if (!this.isTelemetry(domainObject)) {
|
||||
let panels = this.newDomainObject.configuration.panels,
|
||||
id = this.openmct.objects.makeKeyString(domainObject.identifier),
|
||||
panel = panels[id],
|
||||
mutateObject = false,
|
||||
initSelect = false;
|
||||
|
||||
// If the panel doesn't exist, create one and mutate the configuration
|
||||
if (!panel) {
|
||||
panel = SubobjectViewConfiguration.create(domainObject, this.gridSize, this.droppedObjectPosition);
|
||||
initSelect = true;
|
||||
this.mutate("configuration.panels[" + id + "]", panel);
|
||||
delete this.droppedObjectPosition;
|
||||
}
|
||||
|
||||
panel.domainObject = domainObject;
|
||||
this.makeSubobjectItem(panel, initSelect);
|
||||
addItem(itemType, ...options) {
|
||||
let item = getItemDefinition(itemType, this.openmct, this.gridSize, ...options);
|
||||
item.type = itemType;
|
||||
this.trackItem(item);
|
||||
this.layoutItems.push(item);
|
||||
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
|
||||
this.initSelectIndex = this.layoutItems.length - 1;
|
||||
},
|
||||
trackItem(item) {
|
||||
if (item.type === "telemetry-view") {
|
||||
this.telemetryViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
|
||||
} else if (item.type === "subobject-view") {
|
||||
this.objectViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
|
||||
}
|
||||
},
|
||||
removeSubobject() {
|
||||
// Not yet implemented
|
||||
initializeItems() {
|
||||
this.telemetryViewMap = {};
|
||||
this.objectViewMap = {};
|
||||
this.layoutItems.forEach(this.trackItem);
|
||||
},
|
||||
addElement(type) {
|
||||
let elements = this.newDomainObject.configuration.elements || [];
|
||||
Promise.resolve(ElementViewConfiguration.create(type, this.openmct))
|
||||
.then(element => {
|
||||
element.index = elements.push(element) - 1;
|
||||
this.mutate("configuration.elements", elements);
|
||||
this.makeElementItem(element, true);
|
||||
});
|
||||
addChild(child) {
|
||||
let identifier = this.openmct.objects.makeKeyString(child.identifier);
|
||||
if (this.isTelemetry(child)) {
|
||||
if (!this.telemetryViewMap[identifier]) {
|
||||
this.addItem('telemetry-view', child);
|
||||
}
|
||||
} else if (!this.objectViewMap[identifier]) {
|
||||
this.addItem('subobject-view', child);
|
||||
}
|
||||
},
|
||||
removeChild(identifier) {
|
||||
// TODO: implement
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.newDomainObject = this.domainObject;
|
||||
this.gridSize = this.newDomainObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||
|
||||
this.unlisten = this.openmct.objects.observe(this.newDomainObject, '*', function (obj) {
|
||||
this.newDomainObject = JSON.parse(JSON.stringify(obj));
|
||||
this.gridSize = this.newDomainObject.layoutGrid || DEFAULT_GRID_SIZE;;
|
||||
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
|
||||
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
|
||||
}.bind(this));
|
||||
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
|
||||
this.composition = this.openmct.composition.get(this.newDomainObject);
|
||||
this.composition.on('add', this.addSubobject);
|
||||
this.composition.on('remove', this.removeSubobject);
|
||||
this.initializeItems();
|
||||
this.composition = this.openmct.composition.get(this.internalDomainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load();
|
||||
this.getAlphanumerics();
|
||||
this.getElements();
|
||||
},
|
||||
destroyed: function () {
|
||||
this.openmct.off('change', this.setSelection);
|
||||
this.composition.off('add', this.addSubobject);
|
||||
this.composition.off('remove', this.removeSubobject);
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
this.unlisten();
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user