From a1d7737551c14ddd28af1f8d33ae1b76edc2bb85 Mon Sep 17 00:00:00 2001 From: zadam Date: Thu, 3 Jun 2021 23:34:40 +0200 Subject: [PATCH] right pane restoration for custom widgets --- TODO | 1 + src/public/app/layouts/desktop_layout.js | 103 ++++++++++-------- src/public/app/widgets/collapsible_widget.js | 99 +---------------- .../containers/right_pane_container.js | 27 +++++ src/public/stylesheets/style.css | 46 ++++++++ 5 files changed, 134 insertions(+), 142 deletions(-) create mode 100644 TODO create mode 100644 src/public/app/widgets/containers/right_pane_container.js diff --git a/TODO b/TODO new file mode 100644 index 000000000..8b4755848 --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +- remove zen mode diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index e233b6036..16915ed99 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -38,6 +38,7 @@ 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"; +import RightPaneContainer from "../widgets/containers/right_pane_container.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -76,64 +77,74 @@ export default class DesktopLayout { ) .child(new LeftPaneContainer() .hideInZenMode() - .css("width", "300px") .child(new QuickSearchWidget()) .child(appContext.mainTreeWidget) .child(...this.customWidgets.get('left-pane')) ) .child(new FlexContainer('column') - .id('center-pane') .css("flex-grow", "1") .child(new FlexContainer('row').overflowing() .child(new TabRowWidget()) .child(new TitleBarButtonsWidget()) .css('height', '40px') ) - .child(new SplitNoteContainer(() => - new FlexContainer('column') - .css("flex-grow", "1") - .child(new FlexContainer('row').class('title-row') - .css('align-items: center;') - .cssBlock('.title-row > * { margin: 5px; }') - .overflowing() - .child(new NoteIconWidget()) - .child(new NoteTitleWidget()) - .child(new SpacerWidget(1)) - .child(new ClosePaneButton()) - .child(new CreatePaneButton()) + .child(new FlexContainer('row') + .filling() + .child(new FlexContainer('column') + .filling() + .id('center-pane') + .child(new SplitNoteContainer(() => + new FlexContainer('column') + .css("flex-grow", "1") + .child(new FlexContainer('row').class('title-row') + .css('align-items: center;') + .cssBlock('.title-row > * { margin: 5px; }') + .overflowing() + .child(new NoteIconWidget()) + .child(new NoteTitleWidget()) + .child(new SpacerWidget(1)) + .child(new ClosePaneButton()) + .child(new CreatePaneButton()) + ) + .child( + 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") + .command("showNoteRevisions") + .titlePlacement("bottom")) + .button(new NoteActionsWidget()) + ) + .child(new NoteUpdateStatusWidget()) + .child( + new ScrollingContainer() + .child(new SqlTableSchemasWidget()) + .child(new NoteDetailWidget()) + .child(new NoteListWidget()) + .child(new SearchResultWidget()) + .child(new SqlResultWidget()) + ) + .child(...this.customWidgets.get('center-pane')) + ) ) - .child( - 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") - .command("showNoteRevisions") - .titlePlacement("bottom")) - .button(new NoteActionsWidget()) - ) - .child(new NoteUpdateStatusWidget()) - .child( - new ScrollingContainer() - .child(new SqlTableSchemasWidget()) - .child(new NoteDetailWidget()) - .child(new NoteListWidget()) - .child(new SearchResultWidget()) - .child(new SqlResultWidget()) - ) - .child(...this.customWidgets.get('center-pane')) + ) + .child(new RightPaneContainer() + .hideInZenMode() + .css("width", "300px") + .child(...this.customWidgets.get('right-pane')) ) ) ); diff --git a/src/public/app/widgets/collapsible_widget.js b/src/public/app/widgets/collapsible_widget.js index cea9a86bd..e5563fb7f 100644 --- a/src/public/app/widgets/collapsible_widget.js +++ b/src/public/app/widgets/collapsible_widget.js @@ -1,30 +1,10 @@ import NoteContextAwareWidget from "./note_context_aware_widget.js"; -import options from "../services/options.js"; const WIDGET_TPL = `
- +
-
+
`; @@ -32,8 +12,6 @@ const WIDGET_TPL = ` export default class CollapsibleWidget extends NoteContextAwareWidget { get widgetTitle() { return "Untitled widget"; } - get headerActions() { return []; } - get help() { return {}; } doRender() { @@ -44,85 +22,14 @@ export default class CollapsibleWidget extends NoteContextAwareWidget { this.$bodyWrapper = this.$widget.find('.body-wrapper'); this.$bodyWrapper.attr('id', this.componentId); // for toggle to work we need id - // not using constructor name because of webpack mangling class names ... - this.widgetName = this.widgetTitle.replace(/[^[a-zA-Z0-9]/g, "_"); - - this.$toggleButton = this.$widget.find('.widget-toggle-button'); - this.$toggleIcon = this.$widget.find('.widget-toggle-icon'); - - const collapsed = options.is(this.widgetName + 'Collapsed'); - if (!collapsed) { - this.$bodyWrapper.collapse("show"); - } - - this.updateToggleIcon(collapsed); - - // using immediate variants of the event so that the previous collapse is not caught - this.$bodyWrapper.on('hide.bs.collapse', () => this.toggleCollapsed(true)); - this.$bodyWrapper.on('show.bs.collapse', () => this.toggleCollapsed(false)); - this.$body = this.$bodyWrapper.find('.card-body'); - this.$title = this.$widget.find('.widget-title'); + this.$title = this.$widget.find('.card-header'); this.$title.text(this.widgetTitle); - this.$help = this.$widget.find('.widget-help'); - - if (this.help.title) { - this.$help.attr("title", this.help.title); - this.$help.attr("href", this.help.url || "javascript:"); - - if (!this.help.url) { - this.$help.addClass('no-link'); - } - } - else { - this.$help.hide(); - } - - this.$headerActions = this.$widget.find('.widget-header-actions'); - this.$headerActions.append(this.headerActions); - this.initialized = this.doRenderBody(); - - this.decorateWidget(); } - toggleCollapsed(collapse) { - this.updateToggleIcon(collapse); - - options.save(this.widgetName + 'Collapsed', collapse.toString()); - - this.triggerEvent(`widgetCollapsedStateChanged`, {widgetName: this.widgetName, collapse}); - } - - updateToggleIcon(collapse) { - if (collapse) { - this.$toggleIcon - .addClass("bx-chevron-right") - .removeClass("bx-chevron-down") - .attr("title", "Show"); - } else { - this.$toggleIcon - .addClass("bx-chevron-down") - .removeClass("bx-chevron-right") - .attr("title", "Hide"); - } - } - - /** - * This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered - * separately but should behave uniformly for the user. - */ - widgetCollapsedStateChangedEvent({widgetName, collapse}) { - if (widgetName === this.widgetName) { - this.$bodyWrapper.toggleClass('show', !collapse); - } - } - - /** for overriding */ - decorateWidget() {} - /** for overriding */ async doRenderBody() {} diff --git a/src/public/app/widgets/containers/right_pane_container.js b/src/public/app/widgets/containers/right_pane_container.js new file mode 100644 index 000000000..f5f637575 --- /dev/null +++ b/src/public/app/widgets/containers/right_pane_container.js @@ -0,0 +1,27 @@ +import FlexContainer from "./flex_container.js"; + +export default class RightPaneContainer extends FlexContainer { + constructor() { + super('column'); + + this.id('right-pane'); + this.css('height', '100%'); + } + + isEnabled() { + return super.isEnabled() && this.children.length > 0 && !!this.children.find(ch => ch.isEnabled()); + } + + handleEventInChildren(name, data) { + const promise = super.handleEventInChildren(name, data); + + if (['activeContextChanged', 'noteSwitchedAndActivated', 'noteSwitched'].includes(name)) { + // right pane is displayed only if some child widget is active + // we'll reevaluate the visibility based on events which are probable to cause visibility change + // but these events needs to be finished and only then we check + promise.then(() => this.toggleInt(this.isEnabled())); + } + + return promise; + } +} diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 5ef4ef4fd..939638bb2 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -909,3 +909,49 @@ ul.fancytree-container li { input { background-color: transparent !important; } + + +#right-pane { + overflow: auto; +} + +#right-pane .card { + border: 0; + display: flex; + flex-shrink: 0; + flex-direction: column; +} + +#right-pane .card-header { + background: inherit; + padding: 6px 10px 3px 0; + width: 99%; /* to give minimal right margin */ + background-color: var(--button-background-color); + border-color: var(--button-border-color); + border-width: 0 0 1px 0; + border-radius: 4px; + border-style: solid; + display: flex; + justify-content: space-between; + font-weight: bold; + text-transform: uppercase; + color: var(--muted-text-color) !important; +} + +#right-pane .body-wrapper { + overflow: auto; +} + +#right-pane .card-body { + width: 100%; + padding: 8px; + border: 0; + height: 100%; + overflow: auto; + max-height: 300px; +} + +#right-pane .card-body ul { + padding-left: 25px; + margin-bottom: 5px; +}