diff --git a/apps/client/src/widgets/Breadcrumb.tsx b/apps/client/src/widgets/Breadcrumb.tsx
index 83ff966b8..c218f7cea 100644
--- a/apps/client/src/widgets/Breadcrumb.tsx
+++ b/apps/client/src/widgets/Breadcrumb.tsx
@@ -14,6 +14,7 @@ import NoteLink from "./react/NoteLink";
import link_context_menu from "../menus/link_context_menu";
import { TitleEditor } from "./collections/board";
import server from "../services/server";
+import { NoteInfoBadge } from "./BreadcrumbBadges";
const COLLAPSE_THRESHOLD = 5;
const INITIAL_ITEMS = 2;
@@ -119,7 +120,10 @@ function BreadcrumbItem({ index, notePath, noteContext, notePathLength }: { inde
}
if (index === notePathLength - 1) {
- return ;
+ return <>
+
+
+ >;
}
return ;
diff --git a/apps/client/src/widgets/BreadcrumbBadges.css b/apps/client/src/widgets/BreadcrumbBadges.css
index 7d6405159..a8fcd6657 100644
--- a/apps/client/src/widgets/BreadcrumbBadges.css
+++ b/apps/client/src/widgets/BreadcrumbBadges.css
@@ -9,63 +9,87 @@
flex-shrink: 1;
overflow: hidden;
--badge-radius: 12px;
+}
- .breadcrumb-badge {
- display: flex;
- align-items: center;
- padding: 2px 6px;
- border-radius: var(--badge-radius);
- font-size: 0.75em;
- background-color: var(--color, transparent);
- color: white;
- min-width: 0;
- flex-shrink: 1;
+.breadcrumb-badge {
+ display: flex;
+ align-items: center;
+ padding: 2px 6px;
+ border-radius: var(--badge-radius);
+ font-size: 0.75em;
+ background-color: var(--color, transparent);
+ color: white;
+ min-width: 0;
+ flex-shrink: 1;
- &.clickable {
- cursor: pointer;
+ &.clickable {
+ cursor: pointer;
- &:hover {
- background-color: color-mix(in srgb, var(--color, --badge-background-color) 80%, black);
- }
- }
-
- &.temporarily-editable-badge { --color: #4fa52b; }
- &.read-only-badge { --color: #e33f3b; }
- &.share-badge { --color: #3b82f6; }
- &.backlinks-badge { color: var(--badge-text-color); }
-
- a {
- color: inherit;
- text-decoration: none;
- }
-
- > * {
- min-width: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
+ &:hover {
+ background-color: color-mix(in srgb, var(--color, --badge-background-color) 80%, black);
}
}
- .dropdown {
+ &.temporarily-editable-badge { --color: #4fa52b; }
+ &.read-only-badge { --color: #e33f3b; }
+ &.share-badge { --color: #3b82f6; }
+ &.backlinks-badge { color: var(--badge-text-color); }
+
+ a {
+ color: inherit !important;
+ text-decoration: none;
+ }
+
+ > * {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- border-radius: var(--badge-radius);
-
- &.dropdown-backlinks-badge .dropdown-menu {
- min-width: 500px;
- }
-
- .breadcrumb-badge {
- border-radius: 0;
- }
-
- .btn {
- border: 0;
- margin: 0;
- padding: 0;
- }
+ }
+}
+
+.breadcrumb-dropdown-badge {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ border-radius: var(--badge-radius);
+
+ &.dropdown-backlinks-badge .dropdown-menu {
+ min-width: 500px;
+ }
+
+ &.dropdown-note-info-badge {
+ .dropdown-menu.show ul {
+ list-style-type: none;
+ padding: 0.5em;
+ margin: 0;
+ display: table;
+
+ li {
+ display: table-row;
+
+ > strong {
+ display: table-cell;
+ padding: 0.2em 0;
+ }
+
+ > span {
+ display: table-cell;
+ user-select: text;
+ padding-left: 2em;
+ }
+ }
+ }
+ }
+
+ .breadcrumb-badge {
+ border-radius: 0;
+ }
+
+ .btn {
+ border: 0;
+ margin: 0;
+ padding: 0;
}
}
diff --git a/apps/client/src/widgets/BreadcrumbBadges.tsx b/apps/client/src/widgets/BreadcrumbBadges.tsx
index 0e3cf986f..9f8b0de93 100644
--- a/apps/client/src/widgets/BreadcrumbBadges.tsx
+++ b/apps/client/src/widgets/BreadcrumbBadges.tsx
@@ -5,11 +5,14 @@ import { ComponentChildren, MouseEventHandler } from "preact";
import { useRef } from "preact/hooks";
import { t } from "../services/i18n";
+import { formatDateTime } from "../utils/formatters";
import { BacklinksList, useBacklinkCount } from "./FloatingButtonsDefinitions";
import Dropdown, { DropdownProps } from "./react/Dropdown";
import { useIsNoteReadOnly, useNoteContext, useStaticTooltip } from "./react/hooks";
import Icon from "./react/Icon";
+import { NoteSizeWidget, useNoteMetadata } from "./ribbon/NoteInfoTab";
import { useShareInfo } from "./shared_info";
+import FNote from "../entities/fnote";
export default function BreadcrumbBadges() {
return (
@@ -21,6 +24,35 @@ export default function BreadcrumbBadges() {
);
}
+export function NoteInfoBadge({ note }: { note: FNote | null | undefined }) {
+ const { metadata, ...sizeProps } = useNoteMetadata(note);
+
+ return (note &&
+
+
+
+
+ {note.type} {note.mime && ({note.mime})}} />
+ {note.noteId}} />
+ } />
+
+
+ );
+}
+
+function NoteInfoValue({ text, title, value }: { text: string; title?: string, value: ComponentChildren }) {
+ return (
+
+ {text}{": "}
+ {value}
+
+ );
+}
+
function ReadOnlyBadge() {
const { note, noteContext } = useNoteContext();
const { isReadOnly, enableEditing } = useIsNoteReadOnly(note, noteContext);
@@ -83,7 +115,7 @@ function BacklinksBadge() {
}
interface BadgeProps {
- text: string;
+ text?: string;
icon?: string;
className: string;
tooltip?: string;
@@ -123,15 +155,21 @@ function BadgeWithDropdown({ children, tooltip, className, dropdownOptions, ...p
}) {
return (
}
noDropdownListStyle
noSelectButtonStyle
hideToggleArrow
title={tooltip}
titlePosition="bottom"
- dropdownOptions={{ popperConfig: { placement: "bottom", strategy: "fixed" } }}
{...dropdownOptions}
+ dropdownOptions={{
+ ...dropdownOptions?.dropdownOptions,
+ popperConfig: {
+ ...dropdownOptions?.dropdownOptions?.popperConfig,
+ placement: "bottom", strategy: "fixed"
+ }
+ }}
>{children}
);
}
diff --git a/apps/client/src/widgets/NoteTitleDetails.tsx b/apps/client/src/widgets/NoteTitleDetails.tsx
index 58f4da0f7..c9992578f 100644
--- a/apps/client/src/widgets/NoteTitleDetails.tsx
+++ b/apps/client/src/widgets/NoteTitleDetails.tsx
@@ -9,26 +9,12 @@ import { useRef } from "preact/hooks";
export default function NoteTitleDetails() {
const { note, noteContext } = useNoteContext();
- const { metadata } = useNoteMetadata(note);
const isHiddenNote = note?.noteId.startsWith("_");
const isDefaultView = noteContext?.viewScope?.viewMode === "default";
- const items: ComponentChild[] = [
- (isDefaultView && !isHiddenNote && metadata?.dateCreated &&
- ),
- (isDefaultView && !isHiddenNote && metadata?.dateModified &&
- )
- ].filter(item => !!item);
+ const items: ComponentChild[] = [].filter(item => !!item);
- return (
+ return items.length && (
{joinElements(items, " • ")}
diff --git a/apps/client/src/widgets/ribbon/NoteInfoTab.tsx b/apps/client/src/widgets/ribbon/NoteInfoTab.tsx
index 888412867..8180f74a6 100644
--- a/apps/client/src/widgets/ribbon/NoteInfoTab.tsx
+++ b/apps/client/src/widgets/ribbon/NoteInfoTab.tsx
@@ -1,6 +1,5 @@
import { useEffect, useState } from "preact/hooks";
import { t } from "../../services/i18n";
-import { TabContext } from "./ribbon-interface";
import { MetadataResponse, NoteSizeResponse, SubtreeSizeResponse } from "@triliumnext/commons";
import server from "../../services/server";
import Button from "../react/Button";
@@ -13,8 +12,8 @@ import FNote from "../../entities/fnote";
const isNewLayout = isExperimentalFeatureEnabled("new-layout");
-export default function NoteInfoTab({ note }: TabContext) {
- const { isLoading, metadata, noteSizeResponse, subtreeSizeResponse, requestSizeInfo } = useNoteMetadata(note);
+export default function NoteInfoTab({ note }: { note: FNote | null | undefined }) {
+ const { metadata, ...sizeProps } = useNoteMetadata(note);
return (
@@ -42,23 +41,7 @@ export default function NoteInfoTab({ note }: TabContext) {
{t("note_info_widget.note_size")}:
- {!isLoading && !noteSizeResponse && !subtreeSizeResponse && (
-
- )}
-
-
- {formatSize(noteSizeResponse?.noteSize)}
- {" "}
- {subtreeSizeResponse && subtreeSizeResponse.subTreeNoteCount > 1 &&
- {t("note_info_widget.subtree_size", { size: formatSize(subtreeSizeResponse.subTreeSize), count: subtreeSizeResponse.subTreeNoteCount })}
- }
- {isLoading && }
-
+
>
@@ -67,6 +50,28 @@ export default function NoteInfoTab({ note }: TabContext) {
);
}
+export function NoteSizeWidget({ isLoading, noteSizeResponse, subtreeSizeResponse, requestSizeInfo }: Omit
, "metadata">) {
+ return <>
+ {!isLoading && !noteSizeResponse && !subtreeSizeResponse && (
+
+ )}
+
+
+ {formatSize(noteSizeResponse?.noteSize)}
+ {" "}
+ {subtreeSizeResponse && subtreeSizeResponse.subTreeNoteCount > 1 &&
+ {t("note_info_widget.subtree_size", { size: formatSize(subtreeSizeResponse.subTreeSize), count: subtreeSizeResponse.subTreeNoteCount })}
+ }
+ {isLoading && }
+
+ >;
+}
+
export function useNoteMetadata(note: FNote | null | undefined) {
const [ isLoading, setIsLoading ] = useState(false);
const [ noteSizeResponse, setNoteSizeResponse ] = useState();
diff --git a/apps/client/src/widgets/ribbon/RibbonDefinition.ts b/apps/client/src/widgets/ribbon/RibbonDefinition.ts
index a76e97140..e2779e287 100644
--- a/apps/client/src/widgets/ribbon/RibbonDefinition.ts
+++ b/apps/client/src/widgets/ribbon/RibbonDefinition.ts
@@ -132,7 +132,7 @@ export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
{
title: t("note_info_widget.title"),
icon: "bx bx-info-circle",
- show: ({ note }) => !!note,
+ show: ({ note }) => !isNewLayout && !!note,
content: NoteInfoTab,
toggleCommand: "toggleRibbonTabNoteInfo"
}