mirror of
https://github.com/nasa/openmct.git
synced 2025-06-11 11:51:40 +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"
|
class="c-fl-frame__drop-hint"
|
||||||
:index="-1"
|
:index="-1"
|
||||||
:allow-drop="allowDrop"
|
:allow-drop="allowDrop"
|
||||||
@object-drop-to="moveOrCreateFrame">
|
@object-drop-to="moveOrCreateNewFrame">
|
||||||
</drop-hint>
|
</drop-hint>
|
||||||
|
|
||||||
<div class="c-fl-container__frames-holder">
|
<div class="c-fl-container__frames-holder">
|
||||||
@ -55,7 +55,7 @@
|
|||||||
:key="i"
|
:key="i"
|
||||||
:index="i"
|
:index="i"
|
||||||
:allowDrop="allowDrop"
|
:allowDrop="allowDrop"
|
||||||
@object-drop-to="moveOrCreateFrame">
|
@object-drop-to="moveOrCreateNewFrame">
|
||||||
</drop-hint>
|
</drop-hint>
|
||||||
|
|
||||||
<resize-handle
|
<resize-handle
|
||||||
@ -123,15 +123,12 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
moveOrCreateFrame(insertIndex, event) {
|
moveOrCreateNewFrame(insertIndex, event) {
|
||||||
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
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(
|
this.$emit(
|
||||||
'create-frame',
|
'new-frame',
|
||||||
this.index,
|
this.index,
|
||||||
insertIndex,
|
insertIndex
|
||||||
domainObject.identifier
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
<div v-show="isValidTarget">
|
<div v-show="isValidTarget">
|
||||||
<div class="c-drop-hint c-drop-hint--always-show"
|
<div class="c-drop-hint c-drop-hint--always-show"
|
||||||
:class="{'is-mouse-over': isMouseOver}"
|
:class="{'is-mouse-over': isMouseOver}"
|
||||||
|
@dragover.prevent
|
||||||
@dragenter="dragenter"
|
@dragenter="dragenter"
|
||||||
@dragleave="dragleave"
|
@dragleave="dragleave"
|
||||||
@drop="dropHandler">
|
@drop="dropHandler">
|
||||||
@ -71,10 +72,12 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
document.addEventListener('dragstart', this.dragstart);
|
document.addEventListener('dragstart', this.dragstart);
|
||||||
document.addEventListener('dragend', this.dragend);
|
document.addEventListener('dragend', this.dragend);
|
||||||
|
document.addEventListener('drop', this.dragend);
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
document.removeEventListener('dragstart', this.dragstart);
|
document.removeEventListener('dragstart', this.dragstart);
|
||||||
document.removeEventListener('dragend', this.dragend);
|
document.removeEventListener('dragend', this.dragend);
|
||||||
|
document.removeEventListener('drop', this.dragend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="c-fl">
|
<div class="c-fl">
|
||||||
|
<div
|
||||||
|
id="js-fl-drag-ghost"
|
||||||
|
class="c-fl__drag-ghost">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="c-fl__empty"
|
<div class="c-fl__empty"
|
||||||
v-if="areAllContainersEmpty()">
|
v-if="areAllContainersEmpty()">
|
||||||
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
||||||
@ -50,7 +55,7 @@
|
|||||||
:container="container"
|
:container="container"
|
||||||
:rowsLayout="rowsLayout"
|
:rowsLayout="rowsLayout"
|
||||||
@move-frame="moveFrame"
|
@move-frame="moveFrame"
|
||||||
@create-frame="createFrame"
|
@new-frame="setFrameLocation"
|
||||||
@persist="persist">
|
@persist="persist">
|
||||||
</container-component>
|
</container-component>
|
||||||
|
|
||||||
@ -137,6 +142,23 @@
|
|||||||
opacity: 0.5;
|
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 {
|
.c-fl-container {
|
||||||
@ -451,7 +473,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
domainObject: this.layoutObject
|
domainObject: this.layoutObject,
|
||||||
|
newFrameLocation: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -497,12 +520,22 @@ export default {
|
|||||||
sizeItems(toContainer.frames, frame);
|
sizeItems(toContainer.frames, frame);
|
||||||
this.persist();
|
this.persist();
|
||||||
},
|
},
|
||||||
createFrame(containerIndex, insertFrameIndex, objectIdentifier) {
|
setFrameLocation(containerIndex, insertFrameIndex) {
|
||||||
let frame = new Frame(objectIdentifier);
|
this.newFrameLocation = [containerIndex, insertFrameIndex];
|
||||||
let container = this.containers[containerIndex];
|
},
|
||||||
container.frames.splice(insertFrameIndex + 1, 0, frame);
|
addFrame(domainObject) {
|
||||||
sizeItems(container.frames, frame);
|
if (this.newFrameLocation.length) {
|
||||||
this.persist();
|
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) {
|
deleteFrame(frameId) {
|
||||||
let container = this.containers
|
let container = this.containers
|
||||||
@ -584,13 +617,33 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.containers.splice(toIndex, 0, container);
|
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();
|
this.persist();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
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);
|
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
this.composition.off('remove', this.removeChildObject);
|
||||||
|
this.composition.off('add', this.addFrame);
|
||||||
|
|
||||||
this.unobserve();
|
this.unobserve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,6 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setDomainObject(object) {
|
setDomainObject(object) {
|
||||||
console.log('setting object!');
|
|
||||||
this.domainObject = object;
|
this.domainObject = object;
|
||||||
this.objectPath = [object];
|
this.objectPath = [object];
|
||||||
this.setSelection();
|
this.setSelection();
|
||||||
@ -89,6 +88,18 @@ export default {
|
|||||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$refs.frame, context, false);
|
this.unsubscribeSelection = this.openmct.selection.selectable(this.$refs.frame, context, false);
|
||||||
},
|
},
|
||||||
initDrag(event) {
|
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('frameid', this.frame.id);
|
||||||
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
||||||
}
|
}
|
||||||
@ -99,6 +110,8 @@ export default {
|
|||||||
this.setDomainObject(object);
|
this.setDomainObject(object);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.unsubscribeSelection) {
|
if (this.unsubscribeSelection) {
|
||||||
|
@ -151,7 +151,7 @@ function ToolbarProvider(openmct) {
|
|||||||
|
|
||||||
let prompt = openmct.overlays.dialog({
|
let prompt = openmct.overlays.dialog({
|
||||||
iconClass: 'alert',
|
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: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: 'Ok',
|
label: 'Ok',
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="hide-menu hidden">
|
<div class="hide-menu hidden">
|
||||||
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
||||||
<div class="menu context-menu">
|
<div class="c-menu">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="action in actions"
|
<li v-for="action in actions"
|
||||||
:key="action.name"
|
:key="action.name"
|
||||||
|
@ -254,13 +254,14 @@ function (
|
|||||||
// Remove the context menu
|
// Remove the context menu
|
||||||
function dismiss() {
|
function dismiss() {
|
||||||
container.find('.hide-menu').append(menu);
|
container.find('.hide-menu').append(menu);
|
||||||
body.off(initiatingEvent, dismiss);
|
body.off(initiatingEvent, menuClickHandler);
|
||||||
menu.off(initiatingEvent, menuClickHandler);
|
|
||||||
dismissExistingMenu = undefined;
|
dismissExistingMenu = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function menuClickHandler(e) {
|
function menuClickHandler(e) {
|
||||||
e.stopPropagation();
|
window.setTimeout(() => {
|
||||||
|
dismiss();
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dismiss any menu which was already showing
|
// Dismiss any menu which was already showing
|
||||||
@ -276,11 +277,7 @@ function (
|
|||||||
marginY: -50
|
marginY: -50
|
||||||
});
|
});
|
||||||
|
|
||||||
// Stop propagation so that clicks or touches on the menu do not close the menu
|
body.on(initiatingEvent, menuClickHandler);
|
||||||
menu.on(initiatingEvent, menuClickHandler);
|
|
||||||
|
|
||||||
body.on(initiatingEvent, dismiss);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EmbedController.prototype.exposedData = function () {
|
EmbedController.prototype.exposedData = function () {
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
:class="type.cssClass">
|
:class="type.cssClass">
|
||||||
<span
|
<span
|
||||||
class="l-browse-bar__object-name c-input-inline"
|
class="l-browse-bar__object-name c-input-inline"
|
||||||
v-on:blur="updateName"
|
@blur="updateName"
|
||||||
|
@keydown.enter.prevent
|
||||||
|
@keyup.enter.prevent="updateNameOnEnterKeyPress"
|
||||||
contenteditable>
|
contenteditable>
|
||||||
{{ domainObject.name }}
|
{{ domainObject.name }}
|
||||||
</span>
|
</span>
|
||||||
@ -60,17 +62,20 @@ const PLACEHOLDER_OBJECT = {};
|
|||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
methods: {
|
methods: {
|
||||||
toggleViewMenu: function (event) {
|
toggleViewMenu(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
this.showViewMenu = !this.showViewMenu;
|
this.showViewMenu = !this.showViewMenu;
|
||||||
},
|
},
|
||||||
updateName: function (event) {
|
updateName(event) {
|
||||||
// TODO: handle isssues with contenteditable text escaping.
|
// TODO: handle isssues with contenteditable text escaping.
|
||||||
if (event.target.innerText !== this.domainObject.name) {
|
if (event.target.innerText !== this.domainObject.name) {
|
||||||
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
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.viewKey = view.key;
|
||||||
this.openmct.router.updateParams({
|
this.openmct.router.updateParams({
|
||||||
view: this.viewKey
|
view: this.viewKey
|
||||||
|
@ -338,7 +338,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
openInNewTab(event) {
|
openInNewTab(event) {
|
||||||
event.target.href = window.location.href;
|
window.open(window.location.href);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,12 @@
|
|||||||
+ .l-pane {
|
+ .l-pane {
|
||||||
@include userSelectNone();
|
@include userSelectNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.l-pane {
|
||||||
|
&__handle {
|
||||||
|
background: $colorSplitterHover;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&[class*="--collapsed"] {
|
&[class*="--collapsed"] {
|
||||||
@ -368,12 +374,12 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
label: String,
|
label: String
|
||||||
resizing: Boolean
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
collapsed: false
|
collapsed: false,
|
||||||
|
resizing: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user