diff --git a/package-lock.json b/package-lock.json index bcf5694db..f935830df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -885,7 +885,7 @@ }, "@webassemblyjs/helper-wasm-section": { "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-ribbon-1.11.0.tgz", "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", "dev": true, "requires": { diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index 0b4e6fe6f..8624651b0 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -5,19 +5,19 @@ import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js"; import TreeSidebarContainer from "../widgets/containers/tree_sidebar_container.js"; import NoteTreeWidget from "../widgets/note_tree.js"; import NoteTitleWidget from "../widgets/note_title.js"; -import OwnedAttributeListWidget from "../widgets/section_widgets/owned_attribute_list.js"; +import OwnedAttributeListWidget from "../widgets/ribbon_widgets/owned_attribute_list.js"; import NoteActionsWidget from "../widgets/buttons/note_actions.js"; import NoteDetailWidget from "../widgets/note_detail.js"; -import CollapsibleSectionContainer from "../widgets/containers/collapsible_section_container.js"; -import PromotedAttributesWidget from "../widgets/section_widgets/promoted_attributes.js"; -import InheritedAttributesWidget from "../widgets/section_widgets/inherited_attribute_list.js"; +import RibbonContainer from "../widgets/containers/ribbon_container.js"; +import PromotedAttributesWidget from "../widgets/ribbon_widgets/promoted_attributes.js"; +import InheritedAttributesWidget from "../widgets/ribbon_widgets/inherited_attribute_list.js"; import NoteListWidget from "../widgets/note_list.js"; -import SearchDefinitionWidget from "../widgets/section_widgets/search_definition.js"; +import SearchDefinitionWidget from "../widgets/ribbon_widgets/search_definition.js"; import SqlResultWidget from "../widgets/sql_result.js"; import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js"; -import FilePropertiesWidget from "../widgets/section_widgets/file_properties.js"; -import ImagePropertiesWidget from "../widgets/section_widgets/image_properties.js"; -import NotePropertiesWidget from "../widgets/section_widgets/note_properties.js"; +import FilePropertiesWidget from "../widgets/ribbon_widgets/file_properties.js"; +import ImagePropertiesWidget from "../widgets/ribbon_widgets/image_properties.js"; +import NotePropertiesWidget from "../widgets/ribbon_widgets/note_properties.js"; import NoteIconWidget from "../widgets/note_icon.js"; import SearchResultWidget from "../widgets/search_result.js"; import SyncStatusWidget from "../widgets/sync_status.js"; @@ -32,12 +32,12 @@ import PaneContainer from "../widgets/containers/pane_container.js"; import SidebarToggleWidget from "../widgets/buttons/sidebar_toggle.js"; import CreatePaneButton from "../widgets/buttons/create_pane_button.js"; import ClosePaneButton from "../widgets/buttons/close_pane_button.js"; -import BasicPropertiesWidget from "../widgets/section_widgets/basic_properties.js"; -import NoteInfoWidget from "../widgets/section_widgets/note_info_widget.js"; -import BookPropertiesWidget from "../widgets/section_widgets/book_properties.js"; -import LinkMapWidget from "../widgets/section_widgets/link_map.js"; -import NotePathsWidget from "../widgets/section_widgets/note_paths.js"; -import SimilarNotesWidget from "../widgets/section_widgets/similar_notes.js"; +import BasicPropertiesWidget from "../widgets/ribbon_widgets/basic_properties.js"; +import NoteInfoWidget from "../widgets/ribbon_widgets/note_info_widget.js"; +import BookPropertiesWidget from "../widgets/ribbon_widgets/book_properties.js"; +import LinkMapWidget from "../widgets/ribbon_widgets/link_map.js"; +import NotePathsWidget from "../widgets/ribbon_widgets/note_paths.js"; +import SimilarNotesWidget from "../widgets/ribbon_widgets/similar_notes.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -103,20 +103,20 @@ export default class DesktopLayout { .child(new CreatePaneButton()) ) .child( - new CollapsibleSectionContainer() - .section(new SearchDefinitionWidget()) - .section(new BasicPropertiesWidget()) - .section(new BookPropertiesWidget()) - .section(new NotePropertiesWidget()) - .section(new FilePropertiesWidget()) - .section(new ImagePropertiesWidget()) - .section(new PromotedAttributesWidget()) - .section(new OwnedAttributeListWidget()) - .section(new InheritedAttributesWidget()) - .section(new NotePathsWidget()) - .section(new LinkMapWidget()) - .section(new SimilarNotesWidget()) - .section(new NoteInfoWidget()) + new RibbonContainer() + .ribbon(new SearchDefinitionWidget()) + .ribbon(new BasicPropertiesWidget()) + .ribbon(new BookPropertiesWidget()) + .ribbon(new NotePropertiesWidget()) + .ribbon(new FilePropertiesWidget()) + .ribbon(new ImagePropertiesWidget()) + .ribbon(new PromotedAttributesWidget()) + .ribbon(new OwnedAttributeListWidget()) + .ribbon(new InheritedAttributesWidget()) + .ribbon(new NotePathsWidget()) + .ribbon(new LinkMapWidget()) + .ribbon(new SimilarNotesWidget()) + .ribbon(new NoteInfoWidget()) .button(new ButtonWidget() .icon('bx bx-history') .title("Note Revisions") diff --git a/src/public/app/widgets/containers/collapsible_section_container.js b/src/public/app/widgets/containers/collapsible_section_container.js deleted file mode 100644 index 346fbaf04..000000000 --- a/src/public/app/widgets/containers/collapsible_section_container.js +++ /dev/null @@ -1,262 +0,0 @@ -import NoteContextAwareWidget from "../note_context_aware_widget.js"; - -const TPL = ` -
- - -
-
-
-
- -
-
`; - -export default class CollapsibleSectionContainer extends NoteContextAwareWidget { - constructor() { - super(); - - this.sectionWidgets = []; - this.buttonWidgets = []; - } - - section(widget) { - super.child(widget); - - this.sectionWidgets.push(widget); - - return this; - } - - button(widget) { - super.child(widget); - - this.buttonWidgets.push(widget); - - return this; - } - - doRender() { - this.$widget = $(TPL); - this.overflowing(); - - this.$titleContainer = this.$widget.find('.section-title-container'); - this.$buttonContainer = this.$widget.find('.section-button-container'); - this.$bodyContainer = this.$widget.find('.section-body-container'); - - for (const sectionWidget of this.sectionWidgets) { - this.$bodyContainer.append( - $('
') - .attr('data-section-component-id', sectionWidget.componentId) - .append(sectionWidget.render()) - ); - } - - for (const buttonWidget of this.buttonWidgets) { - this.$buttonContainer.append(buttonWidget.render()); - } - - this.$titleContainer.on('click', '.section-title-real', e => { - const $sectionTitle = $(e.target).closest('.section-title-real'); - - const activate = !$sectionTitle.hasClass("active"); - - this.$titleContainer.find('.section-title-real').removeClass("active"); - this.$bodyContainer.find('.section-body').removeClass("active"); - - if (activate) { - const sectionComponentId = $sectionTitle.attr('data-section-component-id'); - - this.lastActiveComponentId = sectionComponentId; - - this.$titleContainer.find(`.section-title-real[data-section-component-id="${sectionComponentId}"]`).addClass("active"); - this.$bodyContainer.find(`.section-body[data-section-component-id="${sectionComponentId}"]`).addClass("active"); - - const activeChild = this.getActiveSectionWidget(); - - if (activeChild) { - activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath}); - } - } - else { - this.lastActiveComponentId = null; - } - }); - } - - async refreshWithNote(note, noExplicitActivation = false) { - this.lastNoteType = note.type; - - let $sectionToActivate, $lastActiveSection; - - this.$titleContainer.empty(); - - for (const sectionWidget of this.sectionWidgets) { - const ret = sectionWidget.getTitle(note); - - if (!ret.show) { - continue; - } - - const $sectionTitle = $('
') - .attr('data-section-component-id', sectionWidget.componentId) - .append($('') - .addClass(ret.icon) - .attr("title", ret.title)) - .append(" ") - .append($('').text(ret.title)); - - this.$titleContainer.append($sectionTitle); - this.$titleContainer.append('
'); - - if (ret.activate && !this.lastActiveComponentId && !$sectionToActivate && !noExplicitActivation) { - $sectionToActivate = $sectionTitle; - } - - if (this.lastActiveComponentId === sectionWidget.componentId) { - $lastActiveSection = $sectionTitle; - } - } - - this.$titleContainer.find('.section-title-icon').tooltip(); - - if (!$sectionToActivate) { - $sectionToActivate = $lastActiveSection; - } - - if ($sectionToActivate) { - $sectionToActivate.trigger('click'); - } - else { - this.$bodyContainer.find('.section-body').removeClass("active"); - } - } - - refreshSectionContainerCommand() { - this.refreshWithNote(this.note, true); - } - - async handleEventInChildren(name, data) { - if (['activeContextChanged', 'setNoteContext'].includes(name)) { - // won't trigger .refresh(); - await super.handleEventInChildren('setNoteContext', data); - } - else { - const activeSectionWidget = this.getActiveSectionWidget(); - - // forward events only to active section, inactive ones don't need to be updated - if (activeSectionWidget) { - await activeSectionWidget.handleEvent(name, data); - } - - for (const buttonWidget of this.buttonWidgets) { - await buttonWidget.handleEvent(name, data); - } - } - } - - entitiesReloadedEvent({loadResults}) { - if (loadResults.isNoteReloaded(this.noteId) && this.lastNoteType !== this.note.type) { - // note type influences the list of available sections the most - // check for type is so that we don't update on each title rename - this.lastNoteType = this.note.type; - - this.refresh(); - } - } - - getActiveSectionWidget() { - return this.sectionWidgets.find(ch => ch.componentId === this.lastActiveComponentId) - } -} diff --git a/src/public/app/widgets/containers/ribbon_container.js b/src/public/app/widgets/containers/ribbon_container.js new file mode 100644 index 000000000..1d26a3c9f --- /dev/null +++ b/src/public/app/widgets/containers/ribbon_container.js @@ -0,0 +1,263 @@ +import NoteContextAwareWidget from "../note_context_aware_widget.js"; + +const TPL = ` +
+ + +
+
+
+
+ +
+
`; + +export default class RibbonContainer extends NoteContextAwareWidget { + constructor() { + super(); + + this.ribbonWidgets = []; + this.buttonWidgets = []; + } + + ribbon(widget) { + super.child(widget); + + this.ribbonWidgets.push(widget); + + return this; + } + + button(widget) { + super.child(widget); + + this.buttonWidgets.push(widget); + + return this; + } + + doRender() { + this.$widget = $(TPL); + this.overflowing(); + + this.$tabContainer = this.$widget.find('.ribbon-tab-container'); + this.$buttonContainer = this.$widget.find('.ribbon-button-container'); + this.$bodyContainer = this.$widget.find('.ribbon-body-container'); + + for (const ribbonWidget of this.ribbonWidgets) { + this.$bodyContainer.append( + $('
') + .attr('data-ribbon-component-id', ribbonWidget.componentId) + .append(ribbonWidget.render()) + ); + } + + for (const buttonWidget of this.buttonWidgets) { + this.$buttonContainer.append(buttonWidget.render()); + } + + this.$tabContainer.on('click', '.ribbon-tab-title', e => { + const $ribbonTitle = $(e.target).closest('.ribbon-tab-title'); + + const activate = !$ribbonTitle.hasClass("active"); + + this.$tabContainer.find('.ribbon-tab-title').removeClass("active"); + this.$bodyContainer.find('.ribbon-body').removeClass("active"); + + if (activate) { + const ribbonComponendId = $ribbonTitle.attr('data-ribbon-component-id'); + + this.lastActiveComponentId = ribbonComponendId; + + this.$tabContainer.find(`.ribbon-tab-title[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active"); + this.$bodyContainer.find(`.ribbon-body[data-ribbon-component-id="${ribbonComponendId}"]`).addClass("active"); + + const activeChild = this.getActiveRibbonWidget(); + + if (activeChild) { + activeChild.handleEvent('noteSwitched', {noteContext: this.noteContext, notePath: this.notePath}); + } + } + else { + this.lastActiveComponentId = null; + } + }); + } + + async refreshWithNote(note, noExplicitActivation = false) { + this.lastNoteType = note.type; + + let $ribbonTabToActivate, $lastActiveRibbon; + + this.$tabContainer.empty(); + + for (const ribbonWidget of this.ribbonWidgets) { + const ret = ribbonWidget.getTitle(note); + + if (!ret.show) { + continue; + } + + const $ribbonTitle = $('
') + .attr('data-ribbon-component-id', ribbonWidget.componentId) + .append($('') + .addClass(ret.icon) + .attr("title", ret.title)) + .append(" ") + .append($('').text(ret.title)); + + this.$tabContainer.append($ribbonTitle); + this.$tabContainer.append('
'); + + if (ret.activate && !this.lastActiveComponentId && !$ribbonTabToActivate && !noExplicitActivation) { + $ribbonTabToActivate = $ribbonTitle; + } + + if (this.lastActiveComponentId === ribbonWidget.componentId) { + $lastActiveRibbon = $ribbonTitle; + } + } + + this.$tabContainer.find('.ribbon-tab-title-icon').tooltip(); + + if (!$ribbonTabToActivate) { + $ribbonTabToActivate = $lastActiveRibbon; + } + + if ($ribbonTabToActivate) { + $ribbonTabToActivate.trigger('click'); + } + else { + this.$bodyContainer.find('.ribbon-body').removeClass("active"); + } + } + + refreshRibbonContainerCommand() { + this.refreshWithNote(this.note, true); + } + + async handleEventInChildren(name, data) { + if (['activeContextChanged', 'setNoteContext'].includes(name)) { + // won't trigger .refresh(); + await super.handleEventInChildren('setNoteContext', data); + } + else { + const activeRibbonWidget = this.getActiveRibbonWidget(); + + // forward events only to active ribbon tab, inactive ones don't need to be updated + if (activeRibbonWidget) { + await activeRibbonWidget.handleEvent(name, data); + } + + for (const buttonWidget of this.buttonWidgets) { + await buttonWidget.handleEvent(name, data); + } + } + } + + entitiesReloadedEvent({loadResults}) { + if (loadResults.isNoteReloaded(this.noteId) && this.lastNoteType !== this.note.type) { + // note type influences the list of available ribbon tabs the most + // check for type is so that we don't update on each title rename + this.lastNoteType = this.note.type; + + this.refresh(); + } + } + + getActiveRibbonWidget() { + return this.ribbonWidgets.find(ch => ch.componentId === this.lastActiveComponentId) + } +} diff --git a/src/public/app/widgets/section_widgets/basic_properties.js b/src/public/app/widgets/ribbon_widgets/basic_properties.js similarity index 100% rename from src/public/app/widgets/section_widgets/basic_properties.js rename to src/public/app/widgets/ribbon_widgets/basic_properties.js diff --git a/src/public/app/widgets/section_widgets/book_properties.js b/src/public/app/widgets/ribbon_widgets/book_properties.js similarity index 100% rename from src/public/app/widgets/section_widgets/book_properties.js rename to src/public/app/widgets/ribbon_widgets/book_properties.js diff --git a/src/public/app/widgets/section_widgets/file_properties.js b/src/public/app/widgets/ribbon_widgets/file_properties.js similarity index 100% rename from src/public/app/widgets/section_widgets/file_properties.js rename to src/public/app/widgets/ribbon_widgets/file_properties.js diff --git a/src/public/app/widgets/section_widgets/image_properties.js b/src/public/app/widgets/ribbon_widgets/image_properties.js similarity index 100% rename from src/public/app/widgets/section_widgets/image_properties.js rename to src/public/app/widgets/ribbon_widgets/image_properties.js diff --git a/src/public/app/widgets/section_widgets/inherited_attribute_list.js b/src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js similarity index 100% rename from src/public/app/widgets/section_widgets/inherited_attribute_list.js rename to src/public/app/widgets/ribbon_widgets/inherited_attribute_list.js diff --git a/src/public/app/widgets/section_widgets/link_map.js b/src/public/app/widgets/ribbon_widgets/link_map.js similarity index 99% rename from src/public/app/widgets/section_widgets/link_map.js rename to src/public/app/widgets/ribbon_widgets/link_map.js index 6427301e1..fb90fe114 100644 --- a/src/public/app/widgets/section_widgets/link_map.js +++ b/src/public/app/widgets/ribbon_widgets/link_map.js @@ -211,6 +211,7 @@ export default class LinkMapWidget extends NoteContextAwareWidget { const notes = await froca.getNotes(Object.keys(this.noteIdToLinkCountMap), true); const noteIdToLinkIdMap = {}; + noteIdToLinkIdMap[this.noteId] = new Set(); // for case there are no relations const linksGroupedBySourceTarget = {}; for (const link of Object.values(this.linkIdToLinkMap)) { diff --git a/src/public/app/widgets/section_widgets/note_info_widget.js b/src/public/app/widgets/ribbon_widgets/note_info_widget.js similarity index 100% rename from src/public/app/widgets/section_widgets/note_info_widget.js rename to src/public/app/widgets/ribbon_widgets/note_info_widget.js diff --git a/src/public/app/widgets/section_widgets/note_paths.js b/src/public/app/widgets/ribbon_widgets/note_paths.js similarity index 100% rename from src/public/app/widgets/section_widgets/note_paths.js rename to src/public/app/widgets/ribbon_widgets/note_paths.js diff --git a/src/public/app/widgets/section_widgets/note_properties.js b/src/public/app/widgets/ribbon_widgets/note_properties.js similarity index 100% rename from src/public/app/widgets/section_widgets/note_properties.js rename to src/public/app/widgets/ribbon_widgets/note_properties.js diff --git a/src/public/app/widgets/section_widgets/owned_attribute_list.js b/src/public/app/widgets/ribbon_widgets/owned_attribute_list.js similarity index 100% rename from src/public/app/widgets/section_widgets/owned_attribute_list.js rename to src/public/app/widgets/ribbon_widgets/owned_attribute_list.js diff --git a/src/public/app/widgets/section_widgets/promoted_attributes.js b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js similarity index 99% rename from src/public/app/widgets/section_widgets/promoted_attributes.js rename to src/public/app/widgets/ribbon_widgets/promoted_attributes.js index c8ee17e78..5b8e6441e 100644 --- a/src/public/app/widgets/section_widgets/promoted_attributes.js +++ b/src/public/app/widgets/ribbon_widgets/promoted_attributes.js @@ -290,7 +290,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget { this.refresh(); this.getTitle(this.note); - this.triggerCommand('refreshSectionContainer'); + this.triggerCommand('refreshRibbonContainer'); } } } diff --git a/src/public/app/widgets/section_widgets/search_definition.js b/src/public/app/widgets/ribbon_widgets/search_definition.js similarity index 100% rename from src/public/app/widgets/section_widgets/search_definition.js rename to src/public/app/widgets/ribbon_widgets/search_definition.js diff --git a/src/public/app/widgets/section_widgets/similar_notes.js b/src/public/app/widgets/ribbon_widgets/similar_notes.js similarity index 100% rename from src/public/app/widgets/section_widgets/similar_notes.js rename to src/public/app/widgets/ribbon_widgets/similar_notes.js