mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
More fixes for TCR (#2255)
* Open in new tab * Fix splitter resizing error, and css background issue * Prevent new line on enter key press when editing name in object browse bar. Update domainObject name on enter key press in Object Browse Bar * Flexible layout should react to composition remove, and fix delete container * Render a drag ghost when dragging frame items in flexible layout * Use composition.on add to add new frames
This commit is contained in:
parent
1dc1cc6c24
commit
e254fafb5c
@ -35,7 +35,7 @@
|
||||
class="c-fl-frame__drop-hint"
|
||||
:index="-1"
|
||||
:allow-drop="allowDrop"
|
||||
@object-drop-to="moveOrCreateFrame">
|
||||
@object-drop-to="moveOrCreateNewFrame">
|
||||
</drop-hint>
|
||||
|
||||
<div class="c-fl-container__frames-holder">
|
||||
@ -55,7 +55,7 @@
|
||||
:key="i"
|
||||
:index="i"
|
||||
:allowDrop="allowDrop"
|
||||
@object-drop-to="moveOrCreateFrame">
|
||||
@object-drop-to="moveOrCreateNewFrame">
|
||||
</drop-hint>
|
||||
|
||||
<resize-handle
|
||||
@ -123,15 +123,12 @@ export default {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
moveOrCreateFrame(insertIndex, event) {
|
||||
moveOrCreateNewFrame(insertIndex, event) {
|
||||
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
// create frame using domain object
|
||||
let domainObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||
this.$emit(
|
||||
'create-frame',
|
||||
'new-frame',
|
||||
this.index,
|
||||
insertIndex,
|
||||
domainObject.identifier
|
||||
insertIndex
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
@ -24,6 +24,7 @@
|
||||
<div v-show="isValidTarget">
|
||||
<div class="c-drop-hint c-drop-hint--always-show"
|
||||
:class="{'is-mouse-over': isMouseOver}"
|
||||
@dragover.prevent
|
||||
@dragenter="dragenter"
|
||||
@dragleave="dragleave"
|
||||
@drop="dropHandler">
|
||||
@ -71,10 +72,12 @@ export default {
|
||||
mounted() {
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
document.addEventListener('drop', this.dragend);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
document.removeEventListener('drop', this.dragend);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
<template>
|
||||
<div class="c-fl">
|
||||
<div
|
||||
id="js-fl-drag-ghost"
|
||||
class="c-fl__drag-ghost">
|
||||
</div>
|
||||
|
||||
<div class="c-fl__empty"
|
||||
v-if="areAllContainersEmpty()">
|
||||
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
||||
@ -50,7 +55,7 @@
|
||||
:container="container"
|
||||
:rowsLayout="rowsLayout"
|
||||
@move-frame="moveFrame"
|
||||
@create-frame="createFrame"
|
||||
@new-frame="setFrameLocation"
|
||||
@persist="persist">
|
||||
</container-component>
|
||||
|
||||
@ -137,6 +142,23 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
&__drag-ghost{
|
||||
background: $colorItemTreeHoverBg;
|
||||
color: $colorItemTreeHoverFg;
|
||||
border-radius: $basicCr;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $interiorMarginLg $interiorMarginLg * 2;
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
z-index: 2;
|
||||
|
||||
&:before {
|
||||
color: $colorKey;
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-fl-container {
|
||||
@ -451,7 +473,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
domainObject: this.layoutObject
|
||||
domainObject: this.layoutObject,
|
||||
newFrameLocation: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -497,12 +520,22 @@ export default {
|
||||
sizeItems(toContainer.frames, frame);
|
||||
this.persist();
|
||||
},
|
||||
createFrame(containerIndex, insertFrameIndex, objectIdentifier) {
|
||||
let frame = new Frame(objectIdentifier);
|
||||
let container = this.containers[containerIndex];
|
||||
container.frames.splice(insertFrameIndex + 1, 0, frame);
|
||||
sizeItems(container.frames, frame);
|
||||
this.persist();
|
||||
setFrameLocation(containerIndex, insertFrameIndex) {
|
||||
this.newFrameLocation = [containerIndex, insertFrameIndex];
|
||||
},
|
||||
addFrame(domainObject) {
|
||||
if (this.newFrameLocation.length) {
|
||||
let containerIndex = this.newFrameLocation[0],
|
||||
frameIndex = this.newFrameLocation[1],
|
||||
frame = new Frame(domainObject.identifier),
|
||||
container = this.containers[containerIndex];
|
||||
|
||||
container.frames.splice(frameIndex + 1, 0, frame);
|
||||
sizeItems(container.frames, frame);
|
||||
|
||||
this.newFrameLocation = [];
|
||||
this.persist(containerIndex);
|
||||
}
|
||||
},
|
||||
deleteFrame(frameId) {
|
||||
let container = this.containers
|
||||
@ -584,13 +617,33 @@ export default {
|
||||
} else {
|
||||
this.containers.splice(toIndex, 0, container);
|
||||
}
|
||||
this.persist(index);
|
||||
},
|
||||
removeChildObject(identifier) {
|
||||
let removeIdentifier = this.openmct.objects.makeKeyString(identifier);
|
||||
|
||||
this.containers.forEach(container => {
|
||||
container.frames = container.frames.filter(frame => {
|
||||
let frameIdentifier = this.openmct.objects.makeKeyString(frame.domainObjectIdentifier);
|
||||
|
||||
return removeIdentifier !== frameIdentifier;
|
||||
});
|
||||
});
|
||||
|
||||
this.persist();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('remove', this.removeChildObject);
|
||||
this.composition.on('add', this.addFrame);
|
||||
|
||||
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.composition.off('remove', this.removeChildObject);
|
||||
this.composition.off('add', this.addFrame);
|
||||
|
||||
this.unobserve();
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
setDomainObject(object) {
|
||||
console.log('setting object!');
|
||||
this.domainObject = object;
|
||||
this.objectPath = [object];
|
||||
this.setSelection();
|
||||
@ -89,6 +88,18 @@ export default {
|
||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$refs.frame, context, false);
|
||||
},
|
||||
initDrag(event) {
|
||||
let type = this.openmct.types.get(this.domainObject.type),
|
||||
iconClass = type.definition ? type.definition.cssClass : 'icon-object-unknown';
|
||||
|
||||
if (this.dragGhost) {
|
||||
let originalClassName = this.dragGhost.classList[0];
|
||||
this.dragGhost.className = '';
|
||||
this.dragGhost.classList.add(originalClassName, iconClass);
|
||||
|
||||
this.dragGhost.innerHTML = `<span>${this.domainObject.name}</span>`;
|
||||
event.dataTransfer.setDragImage(this.dragGhost, 0, 0);
|
||||
}
|
||||
|
||||
event.dataTransfer.setData('frameid', this.frame.id);
|
||||
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
||||
}
|
||||
@ -99,6 +110,8 @@ export default {
|
||||
this.setDomainObject(object);
|
||||
});
|
||||
}
|
||||
|
||||
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribeSelection) {
|
||||
|
@ -151,7 +151,7 @@ function ToolbarProvider(openmct) {
|
||||
|
||||
let prompt = openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: `This action will permanently delete container ${containerIndex + 1} from this Flexible Layout`,
|
||||
message: 'This action will permanently delete this container from this Flexible Layout',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
|
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
<div class="hide-menu hidden">
|
||||
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
||||
<div class="menu context-menu">
|
||||
<div class="c-menu">
|
||||
<ul>
|
||||
<li v-for="action in actions"
|
||||
:key="action.name"
|
||||
|
@ -254,13 +254,14 @@ function (
|
||||
// Remove the context menu
|
||||
function dismiss() {
|
||||
container.find('.hide-menu').append(menu);
|
||||
body.off(initiatingEvent, dismiss);
|
||||
menu.off(initiatingEvent, menuClickHandler);
|
||||
body.off(initiatingEvent, menuClickHandler);
|
||||
dismissExistingMenu = undefined;
|
||||
}
|
||||
|
||||
function menuClickHandler(e) {
|
||||
e.stopPropagation();
|
||||
window.setTimeout(() => {
|
||||
dismiss();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Dismiss any menu which was already showing
|
||||
@ -276,11 +277,7 @@ function (
|
||||
marginY: -50
|
||||
});
|
||||
|
||||
// Stop propagation so that clicks or touches on the menu do not close the menu
|
||||
menu.on(initiatingEvent, menuClickHandler);
|
||||
|
||||
body.on(initiatingEvent, dismiss);
|
||||
|
||||
body.on(initiatingEvent, menuClickHandler);
|
||||
};
|
||||
|
||||
EmbedController.prototype.exposedData = function () {
|
||||
|
@ -8,7 +8,9 @@
|
||||
:class="type.cssClass">
|
||||
<span
|
||||
class="l-browse-bar__object-name c-input-inline"
|
||||
v-on:blur="updateName"
|
||||
@blur="updateName"
|
||||
@keydown.enter.prevent
|
||||
@keyup.enter.prevent="updateNameOnEnterKeyPress"
|
||||
contenteditable>
|
||||
{{ domainObject.name }}
|
||||
</span>
|
||||
@ -60,17 +62,20 @@ const PLACEHOLDER_OBJECT = {};
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
methods: {
|
||||
toggleViewMenu: function (event) {
|
||||
toggleViewMenu(event) {
|
||||
event.stopPropagation();
|
||||
this.showViewMenu = !this.showViewMenu;
|
||||
},
|
||||
updateName: function (event) {
|
||||
updateName(event) {
|
||||
// TODO: handle isssues with contenteditable text escaping.
|
||||
if (event.target.innerText !== this.domainObject.name) {
|
||||
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
||||
}
|
||||
},
|
||||
setView: function (view) {
|
||||
updateNameOnEnterKeyPress (event) {
|
||||
event.target.blur();
|
||||
},
|
||||
setView(view) {
|
||||
this.viewKey = view.key;
|
||||
this.openmct.router.updateParams({
|
||||
view: this.viewKey
|
||||
|
@ -338,7 +338,7 @@
|
||||
}
|
||||
},
|
||||
openInNewTab(event) {
|
||||
event.target.href = window.location.href;
|
||||
window.open(window.location.href);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +183,12 @@
|
||||
+ .l-pane {
|
||||
@include userSelectNone();
|
||||
}
|
||||
|
||||
.l-pane {
|
||||
&__handle {
|
||||
background: $colorSplitterHover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&[class*="--collapsed"] {
|
||||
@ -368,12 +374,12 @@ export default {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
label: String,
|
||||
resizing: Boolean
|
||||
label: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
collapsed: false
|
||||
collapsed: false,
|
||||
resizing: false
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
|
Loading…
Reference in New Issue
Block a user