* UI enhancements for #3176 - Large overlay now displays fullscreen; * UI enhancements for #3176 - Adding new ".is-in-small-container" CSS - VERY WIP! - TODO: fix table implementation; * UI fixes for NIRVSS client #170 - Hide table header filter inputs when table is in small container; * UI fixes for NIRVSS client #170 - Fixing legends and plot layout when small, and within a stacked plot; - Add new `hideLegendWhenSmall` property; - Remove 'hidden' from plot legend position options; - Reduced opacity of tabular headers in Espresso theme; - VERY, VERY WIP right now! * UI fixes for NIRVSS client #170 - Fixing legends and plot layout when small, and within a stacked plot; - Cleanups, indention, removed commented CSS; - Tightened up spacing in plot Y axis; * UI enhancements for #3176 - Move local controls for plots and imagery, prevent overlapping with view large button when in a hidden frame in a layout; - Finesse local control styling for increased legibility; - Move l-state-indicators to avoid overlap with repositioned local controls, finesse styling; * UI enhancements for #3176 - Tweak large overlay close button for better visual alignment; * UI enhancements for #3176 - Significant improvements to lines in Display Layouts; - Increased border-width for lines and boxes; - Code enhanced for proper handling of horizontal and vertical lines - but still isn't working properly; - Renamed box-view.scss to box-and-line-views.scss; - VERY WIP! * Fixed incorrect grid array reference * UI enhancements for #3176 - Fixed final issue with Display Layout line drawing object, thank you @deeptailor!; * UI enhancements for #3176 - Contrast enhancements and markup normalization for `c-object-label` elements in main view, Layout frames, Inspector and overlay; - Enhanced `l-overlay-large` layout; - Tightened up margins and spacing in plots; - Refined `is-paused` styling in Telemetry Tables; - Now hide Telemetry Tables 'Export Data' button if rows are selected, which use a separate export button; - Layout frames now hide button's text labels when small; - Layout frames spacing tightened up and improved; * UI enhancements for #3176 - Tweak Snow theme constants; * UI enhancements for #3176 - Fixed ObjectFrame getOverlayElement method, added a wrapper div around the viewed object to properly control resulting layout in the overlay; - Simplified preview CSS to remove background, border and padding; - Layout tweaks to add space between scrollbar and thumbs in Imagery view; - Removed dev "-info" element in LineView.vue; * UI enhancements for #3176 - Improved styling for 'edit lock' button; * UI enhancements for #3176 - Show Display Layout frame "-move" bar on hover, rather than select, to make it easier to select items with hidden frames, and only show -move bar's drag grippy when that frame is selected; - `pointer-events: none` applied to table's body and plot's plot areas when placed in a Layout and being edited, prevents distracting interactions (plot zoom/pan, table row selection) when selecting and moving elements in a Layout; - Refined hover styles for c-button to use $filterHov, simplified and normalized hover styling; - Converted a number of old `<a>` tags to `<buttons>` to normalize styling and use the appropriate control; - Edit lock button is now colored when locked; * Fix linting issue * Minor tweaks - Tweaked control positioning; Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
308 lines
10 KiB
Vue
308 lines
10 KiB
Vue
<template>
|
|
<div class="l-browse-bar">
|
|
<div class="l-browse-bar__start">
|
|
<button
|
|
v-if="hasParent"
|
|
class="l-browse-bar__nav-to-parent-button c-icon-button c-icon-button--major icon-pointer-left"
|
|
@click="goToParent"
|
|
></button>
|
|
<div
|
|
class="l-browse-bar__object-name--w c-object-label"
|
|
:class="{
|
|
classList,
|
|
'is-missing': domainObject.status === 'missing'
|
|
}"
|
|
>
|
|
<div class="c-object-label__type-icon"
|
|
:class="type.cssClass"
|
|
>
|
|
<span class="is-missing__indicator"
|
|
title="This item is missing"
|
|
></span>
|
|
</div>
|
|
<span
|
|
class="l-browse-bar__object-name c-object-label__name c-input-inline"
|
|
contenteditable
|
|
@blur="updateName"
|
|
@keydown.enter.prevent
|
|
@keyup.enter.prevent="updateNameOnEnterKeyPress"
|
|
>
|
|
{{ domainObject.name }}
|
|
</span>
|
|
</div>
|
|
<div
|
|
class="l-browse-bar__context-actions c-disclosure-button"
|
|
@click.prevent.stop="showContextMenu"
|
|
></div>
|
|
</div>
|
|
|
|
<div class="l-browse-bar__end">
|
|
<view-switcher
|
|
v-if="!isEditing"
|
|
:current-view="currentView"
|
|
:views="views"
|
|
@setView="setView"
|
|
/>
|
|
<!-- Action buttons -->
|
|
<NotebookMenuSwitcher v-if="notebookEnabled"
|
|
:domain-object="domainObject"
|
|
:object-path="openmct.router.path"
|
|
class="c-notebook-snapshot-menubutton"
|
|
/>
|
|
<div class="l-browse-bar__actions">
|
|
<button
|
|
v-if="isViewEditable && !isEditing"
|
|
:title="lockedOrUnlocked"
|
|
class="c-button"
|
|
:class="{
|
|
'icon-lock c-button--caution': domainObject.locked,
|
|
'icon-unlocked': !domainObject.locked
|
|
}"
|
|
@click="toggleLock(!domainObject.locked)"
|
|
></button>
|
|
<button
|
|
v-if="isViewEditable && !isEditing && !domainObject.locked"
|
|
class="l-browse-bar__actions__edit c-button c-button--major icon-pencil"
|
|
title="Edit"
|
|
@click="edit()"
|
|
></button>
|
|
|
|
<div
|
|
v-if="isEditing"
|
|
class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
|
>
|
|
<button
|
|
class="c-button--menu c-button--major icon-save"
|
|
title="Save"
|
|
@click.stop="toggleSaveMenu"
|
|
></button>
|
|
<div
|
|
v-show="showSaveMenu"
|
|
class="c-menu"
|
|
>
|
|
<ul>
|
|
<li
|
|
class="icon-save"
|
|
title="Save and Finish Editing"
|
|
@click="saveAndFinishEditing"
|
|
>
|
|
Save and Finish Editing
|
|
</li>
|
|
<li
|
|
class="icon-save"
|
|
title="Save and Continue Editing"
|
|
@click="saveAndContinueEditing"
|
|
>
|
|
Save and Continue Editing
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
v-if="isEditing"
|
|
class="l-browse-bar__actions c-button icon-x"
|
|
title="Cancel Editing"
|
|
@click="promptUserandCancelEditing()"
|
|
></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import ViewSwitcher from './ViewSwitcher.vue';
|
|
import NotebookMenuSwitcher from '@/plugins/notebook/components/notebook-menu-switcher.vue';
|
|
|
|
const PLACEHOLDER_OBJECT = {};
|
|
|
|
export default {
|
|
inject: ['openmct'],
|
|
components: {
|
|
NotebookMenuSwitcher,
|
|
ViewSwitcher
|
|
},
|
|
data: function () {
|
|
return {
|
|
notebookTypes: [],
|
|
showViewMenu: false,
|
|
showSaveMenu: false,
|
|
domainObject: PLACEHOLDER_OBJECT,
|
|
viewKey: undefined,
|
|
isEditing: this.openmct.editor.isEditing(),
|
|
notebookEnabled: this.openmct.types.get('notebook')
|
|
}
|
|
},
|
|
computed: {
|
|
classList() {
|
|
const classList = this.domainObject.classList;
|
|
if (!classList || !classList.length) {
|
|
return '';
|
|
}
|
|
|
|
return classList.join(' ');
|
|
},
|
|
currentView() {
|
|
return this.views.filter(v => v.key === this.viewKey)[0] || {};
|
|
},
|
|
views() {
|
|
return this
|
|
.openmct
|
|
.objectViews
|
|
.get(this.domainObject)
|
|
.map((p) => {
|
|
return {
|
|
key: p.key,
|
|
cssClass: p.cssClass,
|
|
name: p.name
|
|
};
|
|
});
|
|
},
|
|
hasParent() {
|
|
return this.domainObject !== PLACEHOLDER_OBJECT &&
|
|
this.parentUrl !== '#/browse'
|
|
},
|
|
parentUrl() {
|
|
let objectKeyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
|
let hash = window.location.hash;
|
|
return hash.slice(0, hash.lastIndexOf('/' + objectKeyString));
|
|
},
|
|
type() {
|
|
let objectType = this.openmct.types.get(this.domainObject.type);
|
|
if (!objectType) {
|
|
return {}
|
|
}
|
|
return objectType.definition;
|
|
},
|
|
isViewEditable() {
|
|
let currentViewKey = this.currentView.key;
|
|
if (currentViewKey !== undefined) {
|
|
let currentViewProvider = this.openmct.objectViews.getByProviderKey(currentViewKey);
|
|
return currentViewProvider.canEdit && currentViewProvider.canEdit(this.domainObject);
|
|
}
|
|
return false;
|
|
},
|
|
lockedOrUnlocked() {
|
|
if (this.domainObject.locked) {
|
|
return 'Locked for editing - click to unlock.';
|
|
} else {
|
|
return 'Unlocked for editing - click to lock.';
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
domainObject() {
|
|
if (this.mutationObserver) {
|
|
this.mutationObserver();
|
|
}
|
|
this.mutationObserver = this.openmct.objects.observe(this.domainObject, '*', (domainObject) => {
|
|
this.domainObject = domainObject;
|
|
});
|
|
}
|
|
},
|
|
mounted: function () {
|
|
document.addEventListener('click', this.closeViewAndSaveMenu);
|
|
window.addEventListener('beforeunload', this.promptUserbeforeNavigatingAway);
|
|
|
|
this.openmct.editor.on('isEditing', (isEditing) => {
|
|
this.isEditing = isEditing;
|
|
});
|
|
},
|
|
beforeDestroy: function () {
|
|
if (this.mutationObserver) {
|
|
this.mutationObserver();
|
|
}
|
|
document.removeEventListener('click', this.closeViewAndSaveMenu);
|
|
window.removeEventListener('click', this.promptUserbeforeNavigatingAway);
|
|
},
|
|
methods: {
|
|
toggleSaveMenu() {
|
|
this.showSaveMenu = !this.showSaveMenu;
|
|
},
|
|
closeViewAndSaveMenu() {
|
|
this.showViewMenu = false;
|
|
this.showSaveMenu = false;
|
|
},
|
|
updateName(event) {
|
|
if (event.target.innerText !== this.domainObject.name && event.target.innerText.match(/\S/)) {
|
|
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
|
}
|
|
},
|
|
updateNameOnEnterKeyPress(event) {
|
|
event.target.blur();
|
|
},
|
|
setView(view) {
|
|
this.viewKey = view.key;
|
|
this.openmct.router.updateParams({
|
|
view: this.viewKey
|
|
});
|
|
},
|
|
edit() {
|
|
this.openmct.editor.edit();
|
|
},
|
|
promptUserandCancelEditing() {
|
|
let dialog = this.openmct.overlays.dialog({
|
|
iconClass: 'alert',
|
|
message: 'Any unsaved changes will be lost. Are you sure you want to continue?',
|
|
buttons: [
|
|
{
|
|
label: 'Ok',
|
|
emphasis: true,
|
|
callback: () => {
|
|
this.openmct.editor.cancel().then(() => {
|
|
//refresh object view
|
|
this.openmct.layout.$refs.browseObject.show(this.domainObject, this.viewKey, true);
|
|
});
|
|
dialog.dismiss();
|
|
}
|
|
},
|
|
{
|
|
label: 'Cancel',
|
|
callback: () => {
|
|
dialog.dismiss();
|
|
}
|
|
}
|
|
]
|
|
});
|
|
},
|
|
promptUserbeforeNavigatingAway(event) {
|
|
if(this.openmct.editor.isEditing()) {
|
|
event.preventDefault();
|
|
event.returnValue = '';
|
|
}
|
|
},
|
|
saveAndFinishEditing() {
|
|
let dialog = this.openmct.overlays.progressDialog({
|
|
progressPerc: 'unknown',
|
|
message: 'Do not navigate away from this page or close this browser tab while this message is displayed.',
|
|
iconClass: 'info',
|
|
title: 'Saving'
|
|
});
|
|
|
|
return this.openmct.editor.save().then(()=> {
|
|
dialog.dismiss();
|
|
this.openmct.notifications.info('Save successful');
|
|
}).catch((error) => {
|
|
dialog.dismiss();
|
|
this.openmct.notifications.error('Error saving objects');
|
|
console.error(error);
|
|
});
|
|
},
|
|
saveAndContinueEditing() {
|
|
this.saveAndFinishEditing().then(() => {
|
|
this.openmct.editor.edit();
|
|
});
|
|
},
|
|
showContextMenu(event) {
|
|
this.openmct.contextMenu._showContextMenuForObjectPath(this.openmct.router.path, event.clientX, event.clientY);
|
|
},
|
|
goToParent() {
|
|
window.location.hash = this.parentUrl;
|
|
},
|
|
toggleLock(flag) {
|
|
this.openmct.objects.mutate(this.domainObject, 'locked', flag);
|
|
}
|
|
}
|
|
}
|
|
</script>
|