add label/relation from menu

This commit is contained in:
zadam 2020-07-14 23:29:37 +02:00
parent 528418aecb
commit 3d02f82c77
4 changed files with 93 additions and 52 deletions

View file

@ -7,10 +7,10 @@ class ContextMenu {
$(document).on('click', () => this.hide()); $(document).on('click', () => this.hide());
} }
async show(options) { async show(options) {
this.options = options; this.options = options;
this.$widget.empty(); this.$widget.empty();
this.addItems(this.$widget, options.items); this.addItems(this.$widget, options.items);
@ -27,7 +27,7 @@ class ContextMenu {
// in such case we'll position it above click coordinates so it will fit into client // in such case we'll position it above click coordinates so it will fit into client
const clientHeight = document.documentElement.clientHeight; const clientHeight = document.documentElement.clientHeight;
const contextMenuHeight = this.$widget.outerHeight() + 30; const contextMenuHeight = this.$widget.outerHeight() + 30;
let top; let top, left;
if (this.options.y + contextMenuHeight > clientHeight) { if (this.options.y + contextMenuHeight > clientHeight) {
top = clientHeight - contextMenuHeight - 10; top = clientHeight - contextMenuHeight - 10;
@ -35,10 +35,17 @@ class ContextMenu {
top = this.options.y - 10; top = this.options.y - 10;
} }
if (this.options.orientation === 'left') {
left = this.options.x - this.$widget.outerWidth() + 20;
}
else {
left = this.options.x - 20;
}
this.$widget.css({ this.$widget.css({
display: "block", display: "block",
top: top, top: top,
left: this.options.x - 20 left: left
}).addClass("show"); }).addClass("show");
} }
@ -113,4 +120,4 @@ class ContextMenu {
const contextMenu = new ContextMenu(); const contextMenu = new ContextMenu();
export default contextMenu; export default contextMenu;

View file

@ -6,7 +6,7 @@ import BasicWidget from "./basic_widget.js";
import noteAutocompleteService from "../services/note_autocomplete.js"; import noteAutocompleteService from "../services/note_autocomplete.js";
const TPL = ` const TPL = `
<div class="attr-detail" style="display: none;"> <div class="attr-detail">
<style> <style>
.attr-detail { .attr-detail {
display: block; display: block;
@ -14,7 +14,7 @@ const TPL = `
border: 1px solid var(--main-border-color); border: 1px solid var(--main-border-color);
border-radius: 4px; border-radius: 4px;
z-index: 1000; z-index: 1000;
padding: 10px; padding: 15px;
position: absolute; position: absolute;
max-width: 600px; max-width: 600px;
max-height: 600px; max-height: 600px;
@ -76,13 +76,15 @@ const TPL = `
</tr> </tr>
</table> </table>
<br/> <div class="related-notes-container">
<br/>
<h5 class="related-notes-tile">Other notes with this label</h5> <h5 class="related-notes-tile">Other notes with this label</h5>
<ul class="related-notes-list"></ul> <ul class="related-notes-list"></ul>
<div class="related-notes-more-notes"></div> <div class="related-notes-more-notes"></div>
</div>
</div>`; </div>`;
@ -91,9 +93,11 @@ const DISPLAYED_NOTES = 10;
export default class AttributeDetailWidget extends BasicWidget { export default class AttributeDetailWidget extends BasicWidget {
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$relatedNotesTitle = this.$widget.find('.related-notes-tile');
this.$relatedNotesList = this.$widget.find('.related-notes-list'); this.$relatedNotesContainer = this.$widget.find('.related-notes-container');
this.$relatedNotesMoreNotes = this.$widget.find('.related-notes-more-notes'); this.$relatedNotesTitle = this.$relatedNotesContainer.find('.related-notes-tile');
this.$relatedNotesList = this.$relatedNotesContainer.find('.related-notes-list');
this.$relatedNotesMoreNotes = this.$relatedNotesContainer.find('.related-notes-more-notes');
this.$attrEditName = this.$widget.find('.attr-edit-name'); this.$attrEditName = this.$widget.find('.attr-edit-name');
this.$attrEditName.on('keyup', () => this.updateParent()); this.$attrEditName.on('keyup', () => this.updateParent());
@ -130,6 +134,8 @@ export default class AttributeDetailWidget extends BasicWidget {
this.hide(); this.hide();
} }
}); });
this.toggleInt(false); // initial state is hidden
} }
async showAttributeDetail({allAttributes, attribute, isOwned, x, y}) { async showAttributeDetail({allAttributes, attribute, isOwned, x, y}) {
@ -142,8 +148,6 @@ export default class AttributeDetailWidget extends BasicWidget {
this.allAttributes = allAttributes; this.allAttributes = allAttributes;
this.attribute = attribute; this.attribute = attribute;
this.toggleInt(true);
let {results, count} = await server.post('search-related', attribute); let {results, count} = await server.post('search-related', attribute);
for (const res of results) { for (const res of results) {
@ -153,31 +157,32 @@ export default class AttributeDetailWidget extends BasicWidget {
results = results.filter(({noteId}) => noteId !== this.noteId); results = results.filter(({noteId}) => noteId !== this.noteId);
if (results.length === 0) { if (results.length === 0) {
this.$relatedNotesTitle.hide(); this.$relatedNotesContainer.hide();
} }
else { else {
this.$relatedNotesContainer.show();
this.$relatedNotesTitle.text(`Other notes with ${attribute.type} name "${attribute.name}"`); this.$relatedNotesTitle.text(`Other notes with ${attribute.type} name "${attribute.name}"`);
}
this.$relatedNotesList.empty(); this.$relatedNotesList.empty();
const displayedResults = results.length <= DISPLAYED_NOTES ? results : results.slice(0, DISPLAYED_NOTES); const displayedResults = results.length <= DISPLAYED_NOTES ? results : results.slice(0, DISPLAYED_NOTES);
const displayedNotes = await treeCache.getNotes(displayedResults.map(res => res.noteId)); const displayedNotes = await treeCache.getNotes(displayedResults.map(res => res.noteId));
for (const note of displayedNotes) { for (const note of displayedNotes) {
const notePath = treeService.getSomeNotePath(note); const notePath = treeService.getSomeNotePath(note);
const $noteLink = await linkService.createNoteLink(notePath, {showNotePath: true}); const $noteLink = await linkService.createNoteLink(notePath, {showNotePath: true});
this.$relatedNotesList.append( this.$relatedNotesList.append(
$("<li>").append($noteLink) $("<li>").append($noteLink)
); );
} }
if (results.length > DISPLAYED_NOTES) { if (results.length > DISPLAYED_NOTES) {
this.$relatedNotesMoreNotes.show().text(`... and ${count - DISPLAYED_NOTES} more.`); this.$relatedNotesMoreNotes.show().text(`... and ${count - DISPLAYED_NOTES} more.`);
} }
else { else {
this.$relatedNotesMoreNotes.hide(); this.$relatedNotesMoreNotes.hide();
}
} }
if (isOwned) { if (isOwned) {
@ -212,11 +217,14 @@ export default class AttributeDetailWidget extends BasicWidget {
.setSelectedNotePath(attribute.value); .setSelectedNotePath(attribute.value);
} }
this.$attrEditInheritable.prop("checked", !!attribute.isInheritable); this.$attrEditInheritable
.prop("checked", !!attribute.isInheritable)
.attr('disabled', () => !isOwned);
this.$widget.css("left", x - this.$widget.width() / 2); this.toggleInt(true);
this.$widget.css("top", y + 30);
this.$widget.show(); this.$widget.css("left", x - this.$widget.outerWidth() / 2);
this.$widget.css("top", y + 25);
} }
updateParent() { updateParent() {

View file

@ -51,7 +51,9 @@ class BasicWidget extends Component {
this.$widget.addClass('component') this.$widget.addClass('component')
.prop('component', this); .prop('component', this);
this.toggleInt(this.isEnabled()); if (!this.isEnabled()) {
this.toggleInt(false);
}
if (this.cssEl) { if (this.cssEl) {
const css = this.cssEl.trim().startsWith('<style>') ? this.cssEl : `<style>${this.cssEl}</style>`; const css = this.cssEl.trim().startsWith('<style>') ? this.cssEl : `<style>${this.cssEl}</style>`;

View file

@ -326,12 +326,13 @@ export default class NoteAttributesWidget extends TabAwareWidget {
contextMenuService.show({ contextMenuService.show({
x: e.pageX, x: e.pageX,
y: e.pageY, y: e.pageY,
orientation: 'left',
items: [ items: [
{title: "Add new label", command: "addNewLabel", uiIcon: "hash"}, {title: "Add new label", command: "addNewLabel", uiIcon: "hash"},
{title: "Add new relation", command: "addNewRelation", uiIcon: "transfer"}, {title: "Add new relation", command: "addNewRelation", uiIcon: "transfer"},
{title: "----"}, {title: "----"},
{title: "Add new label definition", command: "addNewRelation", uiIcon: "empty"}, {title: "Add new label definition", command: "addNewLabelDefinition", uiIcon: "empty"},
{title: "Add new relation definition", command: "addNewRelation", uiIcon: "empty"}, {title: "Add new relation definition", command: "addNewRelationDefinition", uiIcon: "empty"},
], ],
selectMenuItemHandler: async ({command}) => { selectMenuItemHandler: async ({command}) => {
const attrs = this.parseAttributes(); const attrs = this.parseAttributes();
@ -340,20 +341,43 @@ export default class NoteAttributesWidget extends TabAwareWidget {
return; return;
} }
let type, name;
if (command === 'addNewLabel') { if (command === 'addNewLabel') {
attrs.push({ type = 'label';
type: 'label', name = 'fillName';
name: 'fillName', }
value: '', else if (command === 'addNewRelation') {
isInheritable: false type = 'relation';
}); name = 'fillName';
}
else if (command === 'addNewLabelDefinition') {
type = 'label';
name = 'label:fillName';
}
else if (command === 'addNewRelationDefinition') {
type = 'label';
name = 'relation:fillName';
}
else {
return;
}
await this.renderOwnedAttributes(attrs); attrs.push({
type,
name,
value: '',
isInheritable: false
});
this.$editor.scrollTop(this.$editor[0].scrollHeight); await this.renderOwnedAttributes(attrs);
const rect = this.$editor[0].getBoundingClientRect(); this.$editor.scrollTop(this.$editor[0].scrollHeight);
const rect = this.$editor[0].getBoundingClientRect();
setTimeout(() => {
// showing a little bit later because there's a conflict with outside click closing the attr detail
this.attributeDetailWidget.showAttributeDetail({ this.attributeDetailWidget.showAttributeDetail({
allAttributes: attrs, allAttributes: attrs,
attribute: attrs[attrs.length - 1], attribute: attrs[attrs.length - 1],
@ -361,7 +385,7 @@ export default class NoteAttributesWidget extends TabAwareWidget {
x: (rect.left + rect.right) / 2, x: (rect.left + rect.right) / 2,
y: rect.bottom y: rect.bottom
}); });
} }, 100);
} }
}); });
}); });