diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index 065969df8..bd924768f 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -788,6 +788,22 @@ export function arrayEqual(a: T[], b: T[]) { return true; } +type Indexed = T & { index: number }; + +/** + * Given an object array, alters every object in the array to have an index field assigned to it. + * + * @param items the objects to be numbered. + * @returns the same object for convenience, with the type changed to indicate the new index field. + */ +export function numberObjectsInPlace(items: T[]): Indexed[] { + let index = 0; + for (const item of items) { + (item as Indexed).index = index++; + } + return items as Indexed[]; +} + export default { reloadFrontendApp, restartDesktopApp, diff --git a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx index 8c34ccff1..e517f3894 100644 --- a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx +++ b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx @@ -3,7 +3,7 @@ import Dropdown from "../react/Dropdown"; import { NOTE_TYPES } from "../../services/note_types"; import { FormDropdownDivider, FormListBadge, FormListItem } from "../react/FormList"; import { getAvailableLocales, t } from "../../services/i18n"; -import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEventBeta, useTriliumOption, useTriliumOptionBeta, useTriliumOptionJson } from "../react/hooks"; +import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumEventBeta, useTriliumOption, useTriliumOptionBeta, useTriliumOptionJson } from "../react/hooks"; import mime_types from "../../services/mime_types"; import { Locale, NoteType, ToggleInParentResponse } from "@triliumnext/commons"; import server from "../../services/server"; @@ -17,10 +17,9 @@ import branches from "../../services/branches"; import sync from "../../services/sync"; import appContext from "../../components/app_context"; import HelpButton from "../react/HelpButton"; +import { TabContext } from "./ribbon-interface"; -export default function BasicPropertiesTab() { - const { note } = useNoteContext(); - +export default function BasicPropertiesTab({ note }: TabContext) { return (
diff --git a/apps/client/src/widgets/ribbon/Ribbon.tsx b/apps/client/src/widgets/ribbon/Ribbon.tsx index dd2d0228b..15510e517 100644 --- a/apps/client/src/widgets/ribbon/Ribbon.tsx +++ b/apps/client/src/widgets/ribbon/Ribbon.tsx @@ -1,24 +1,21 @@ -import { useState } from "preact/hooks"; +import { useMemo, useState } from "preact/hooks"; import FNote from "../../entities/fnote"; import { t } from "../../services/i18n"; import { useNoteContext } from "../react/hooks"; import "./style.css"; import { VNode } from "preact"; import BasicPropertiesTab from "./BasicPropertiesTab"; - -type TitleFn = string | ((context: TabContext) => string); - -interface TabContext { - note: FNote | null | undefined; -} - +import { numberObjectsInPlace } from "../../services/utils"; +import { TabContext } from "./ribbon-interface"; interface TabConfiguration { - title: TitleFn; + title: string | ((context: TabContext) => string); icon: string; - content?: () => VNode; + // TODO: Mark as required after porting them all. + content?: (context: TabContext) => VNode; + show?: (context: TabContext) => boolean; } -const TAB_CONFIGURATION: TabConfiguration[] = [ +const TAB_CONFIGURATION = numberObjectsInPlace([ { title: t("classic_editor_toolbar.title"), icon: "bx bx-text" @@ -63,7 +60,8 @@ const TAB_CONFIGURATION: TabConfiguration[] = [ // BasicProperties title: t("basic_properties.basic_properties"), icon: "bx bx-slider", - content: BasicPropertiesTab + content: BasicPropertiesTab, + show: ({note}) => !note?.isLaunchBarConfig() }, { // OwnedAttributeListWidget @@ -94,31 +92,31 @@ const TAB_CONFIGURATION: TabConfiguration[] = [ // NoteInfoWidget title: t("note_info_widget.title"), icon: "bx bx-info-circle" - }, - -]; + } +]); export default function Ribbon() { const { note } = useNoteContext(); const context: TabContext = { note }; - const [ activeTab, setActiveTab ] = useState(8); - const activeTabConfiguration = activeTab ? TAB_CONFIGURATION[activeTab] : undefined; + const [ activeTabIndex, setActiveTabIndex ] = useState(); + const filteredTabs = useMemo(() => TAB_CONFIGURATION.filter(tab => tab.show?.(context)), [ context, note ]) + const activeTabConfiguration = activeTabIndex ? filteredTabs.find(tab => tab.index === activeTabIndex) : undefined; return (
- {TAB_CONFIGURATION.map(({ title, icon }, i) => ( + {filteredTabs.map(({ title, icon, index }) => ( { - if (activeTab !== i) { - setActiveTab(i); + if (activeTabIndex !== index) { + setActiveTabIndex(index); } else { // Collapse - setActiveTab(undefined); + setActiveTabIndex(undefined); } }} /> @@ -129,7 +127,7 @@ export default function Ribbon() {
- {activeTabConfiguration?.content && activeTabConfiguration.content()} + {activeTabConfiguration?.content && activeTabConfiguration.content({ note })}
diff --git a/apps/client/src/widgets/ribbon/ribbon-interface.ts b/apps/client/src/widgets/ribbon/ribbon-interface.ts new file mode 100644 index 000000000..c321675a3 --- /dev/null +++ b/apps/client/src/widgets/ribbon/ribbon-interface.ts @@ -0,0 +1,5 @@ +import FNote from "../../entities/fnote"; + +export interface TabContext { + note: FNote | null | undefined; +} diff --git a/apps/client/src/widgets/switch.ts b/apps/client/src/widgets/switch.ts deleted file mode 100644 index c31be8646..000000000 --- a/apps/client/src/widgets/switch.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { t } from "../services/i18n.js"; -import NoteContextAwareWidget from "./note_context_aware_widget.js"; - -export default class SwitchWidget extends NoteContextAwareWidget { - - doRender() { - this.$widget = $(TPL); - this.$switchButton = this.$widget.find(".switch-button"); - - this.$switchToggle = this.$widget.find(".switch-toggle"); - this.$switchName = this.$widget.find(".switch-name"); - this.$helpButton = this.$widget.find(".switch-help-button"); - } - - switchOff() {} - switchOn() {} - - /** Gets or sets whether the switch is toggled. */ - get isToggled() { - return this.currentState; - } - - set isToggled(state) { - this.currentState = !!state; - - this.$switchButton.toggleClass("on", this.currentState); - } - - /** Gets or sets whether the switch is enabled. */ - get canToggle() { - return !this.$switchButton.hasClass("disabled"); - } - - set canToggle(isEnabled) { - if (isEnabled) { - this.isToggled = this.currentState; // Reapply the correct tooltip - } else { - this.$switchButton.attr("title", this.disabledTooltip); - } - } -}