[Notebook] Press Enter to save notebook entries (#3580)

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
This commit is contained in:
Nikhil 2021-02-18 09:31:45 -08:00 committed by GitHub
parent b7085f7f62
commit 7623a0648f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 112 deletions

View File

@ -97,7 +97,8 @@
:selected-page="getSelectedPage()"
:selected-section="getSelectedSection()"
:read-only="false"
@updateEntries="updateEntries"
@deleteEntry="deleteEntry"
@updateEntry="updateEntry"
/>
</div>
</div>
@ -111,7 +112,7 @@ import Search from '@/ui/components/search.vue';
import SearchResults from './SearchResults.vue';
import Sidebar from './Sidebar.vue';
import { clearDefaultNotebook, getDefaultNotebook, setDefaultNotebook, setDefaultNotebookSection, setDefaultNotebookPage } from '../utils/notebook-storage';
import { addNotebookEntry, createNewEmbed, getNotebookEntries, mutateObject } from '../utils/notebook-entries';
import { addNotebookEntry, createNewEmbed, getEntryPosById, getNotebookEntries, mutateObject } from '../utils/notebook-entries';
import objectUtils from 'objectUtils';
import { throttle } from 'lodash';
@ -244,6 +245,37 @@ export default {
section
};
},
deleteEntry(entryId) {
const self = this;
const entryPos = getEntryPosById(entryId, this.internalDomainObject, this.selectedSection, this.selectedPage);
if (entryPos === -1) {
this.openmct.notifications.alert('Warning: unable to delete entry');
console.error(`unable to delete entry ${entryId} from section ${this.selectedSection}, page ${this.selectedPage}`);
return;
}
const dialog = this.openmct.overlays.dialog({
iconClass: 'alert',
message: 'This action will permanently delete this entry. Do you wish to continue?',
buttons: [
{
label: "Ok",
emphasis: true,
callback: () => {
const entries = getNotebookEntries(self.internalDomainObject, self.selectedSection, self.selectedPage);
entries.splice(entryPos, 1);
self.updateEntries(entries);
dialog.dismiss();
}
},
{
label: "Cancel",
callback: () => dialog.dismiss()
}
]
});
},
dragOver(event) {
event.preventDefault();
event.dataTransfer.dropEffect = "copy";
@ -540,6 +572,13 @@ export default {
setDefaultNotebookSection(section);
},
updateEntry(entry) {
const entries = getNotebookEntries(this.internalDomainObject, this.selectedSection, this.selectedPage);
const entryPos = getEntryPosById(entry.id, this.internalDomainObject, this.selectedSection, this.selectedPage);
entries[entryPos] = entry;
this.updateEntries(entries);
},
updateEntries(entries) {
const configuration = this.internalDomainObject.configuration;
const notebookEntries = configuration.entries || {};

View File

@ -12,11 +12,15 @@
<div class="c-ne__content">
<div :id="entry.id"
class="c-ne__text"
:class="{'c-ne__input' : !readOnly }"
tabindex="0"
:class="{ 'c-ne__input' : !readOnly }"
:contenteditable="!readOnly"
@blur="updateEntryValue($event, entry.id)"
@focus="updateCurrentEntryValue($event, entry.id)"
>{{ entry.text }}</div>
@blur="updateEntryValue($event)"
@keydown.enter.exact.prevent
@keyup.enter.exact.prevent="forceBlur($event)"
v-text="entry.text"
>
</div>
<div class="c-snapshots c-ne__embeds">
<NotebookEmbed v-for="embed in entry.embeds"
:key="embed.id"
@ -33,6 +37,7 @@
>
<button class="c-icon-button c-icon-button--major icon-trash"
title="Delete this entry"
tabindex="-1"
@click="deleteEntry"
>
</button>
@ -57,7 +62,7 @@
<script>
import NotebookEmbed from './NotebookEmbed.vue';
import { createNewEmbed, getEntryPosById, getNotebookEntries } from '../utils/notebook-entries';
import { createNewEmbed } from '../utils/notebook-entries';
import Moment from 'moment';
export default {
@ -103,11 +108,6 @@ export default {
}
}
},
data() {
return {
currentEntryValue: ''
};
},
computed: {
createdOnDate() {
return this.formatTime(this.entry.createdOn, 'YYYY-MM-DD');
@ -117,10 +117,20 @@ export default {
}
},
mounted() {
this.updateEntries = this.updateEntries.bind(this);
this.dropOnEntry = this.dropOnEntry.bind(this);
},
methods: {
addNewEmbed(objectPath) {
const bounds = this.openmct.time.bounds();
const snapshotMeta = {
bounds,
link: null,
objectPath,
openmct: this.openmct
};
const newEmbed = createNewEmbed(snapshotMeta);
this.entry.embeds.push(newEmbed);
},
cancelEditMode(event) {
const isEditing = this.openmct.editor.isEditing();
if (isEditing) {
@ -132,63 +142,23 @@ export default {
event.dataTransfer.dropEffect = "copy";
},
deleteEntry() {
const self = this;
const entryPosById = self.entryPosById(self.entry.id);
if (entryPosById === -1) {
return;
}
const dialog = this.openmct.overlays.dialog({
iconClass: 'alert',
message: 'This action will permanently delete this entry. Do you wish to continue?',
buttons: [
{
label: "Ok",
emphasis: true,
callback: () => {
const entries = getNotebookEntries(self.domainObject, self.selectedSection, self.selectedPage);
entries.splice(entryPosById, 1);
self.updateEntries(entries);
dialog.dismiss();
}
},
{
label: "Cancel",
callback: () => {
dialog.dismiss();
}
}
]
});
this.$emit('deleteEntry', this.entry.id);
},
dropOnEntry($event) {
event.stopImmediatePropagation();
const snapshotId = $event.dataTransfer.getData('openmct/snapshot/id');
if (snapshotId.length) {
this.moveSnapshot(snapshotId);
return;
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
this.snapshotContainer.removeSnapshot(snapshotId);
this.entry.embeds.push(snapshot);
} else {
const data = $event.dataTransfer.getData('openmct/domain-object-path');
const objectPath = JSON.parse(data);
this.addNewEmbed(objectPath);
}
const data = $event.dataTransfer.getData('openmct/domain-object-path');
const objectPath = JSON.parse(data);
const entryPos = this.entryPosById(this.entry.id);
const bounds = this.openmct.time.bounds();
const snapshotMeta = {
bounds,
link: null,
objectPath,
openmct: this.openmct
};
const newEmbed = createNewEmbed(snapshotMeta);
const entries = getNotebookEntries(this.domainObject, this.selectedSection, this.selectedPage);
const currentEntryEmbeds = entries[entryPos].embeds;
currentEntryEmbeds.push(newEmbed);
this.updateEntries(entries);
},
entryPosById(entryId) {
return getEntryPosById(entryId, this.domainObject, this.selectedSection, this.selectedPage);
this.$emit('updateEntry', this.entry);
},
findPositionInArray(array, id) {
let position = -1;
@ -203,15 +173,12 @@ export default {
return position;
},
forceBlur(event) {
event.target.blur();
},
formatTime(unixTime, timeFormat) {
return Moment.utc(unixTime).format(timeFormat);
},
moveSnapshot(snapshotId) {
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
this.entry.embeds.push(snapshot);
this.updateEntry(this.entry);
this.snapshotContainer.removeSnapshot(snapshotId);
},
navigateToPage() {
this.$emit('changeSectionPage', {
sectionId: this.result.section.id,
@ -227,15 +194,8 @@ export default {
removeEmbed(id) {
const embedPosition = this.findPositionInArray(this.entry.embeds, id);
this.entry.embeds.splice(embedPosition, 1);
this.updateEntry(this.entry);
},
updateCurrentEntryValue($event) {
if (this.readOnly) {
return;
}
const target = $event.target;
this.currentEntryValue = target ? target.textContent : '';
this.$emit('updateEntry', this.entry);
},
updateEmbed(newEmbed) {
this.entry.embeds.some(e => {
@ -247,44 +207,14 @@ export default {
return found;
});
this.updateEntry(this.entry);
this.$emit('updateEntry', this.entry);
},
updateEntry(newEntry) {
const entries = getNotebookEntries(this.domainObject, this.selectedSection, this.selectedPage);
entries.some(entry => {
const found = (entry.id === newEntry.id);
if (found) {
entry = newEntry;
}
return found;
});
this.updateEntries(entries);
},
updateEntryValue($event, entryId) {
if (!this.domainObject || !this.selectedSection || !this.selectedPage) {
return;
updateEntryValue($event) {
const value = $event.target.innerText;
if (value !== this.entry.text && value.match(/\S/)) {
this.entry.text = value;
this.$emit('updateEntry', this.entry);
}
const target = $event.target;
if (!target) {
return;
}
const entryPos = this.entryPosById(entryId);
const value = target.textContent.trim();
if (this.currentEntryValue !== value) {
target.textContent = value;
const entries = getNotebookEntries(this.domainObject, this.selectedSection, this.selectedPage);
entries[entryPos].text = value;
this.updateEntries(entries);
}
},
updateEntries(entries) {
this.$emit('updateEntries', entries);
}
}
};

View File

@ -292,6 +292,8 @@
&:focus {
background: $colorInputBg;
}
white-space: pre-wrap;
}
&__section-and-page {