mirror of
https://github.com/zadam/trilium.git
synced 2025-12-12 18:34:24 +01:00
feat(note_bars): view type switcher
This commit is contained in:
parent
0856d3dbdf
commit
0eed72b888
@ -1,46 +1,13 @@
|
|||||||
import { type ComponentChild } from "preact";
|
import CollectionProperties from "./note_bars/CollectionProperties";
|
||||||
|
import { useNoteContext, useNoteProperty } from "./react/hooks";
|
||||||
import { formatDateTime } from "../utils/formatters";
|
|
||||||
import { useNoteContext, useStaticTooltip } from "./react/hooks";
|
|
||||||
import { joinElements } from "./react/react_utils";
|
|
||||||
import { useNoteMetadata } from "./ribbon/NoteInfoTab";
|
|
||||||
import { Trans } from "react-i18next";
|
|
||||||
import { useRef } from "preact/hooks";
|
|
||||||
|
|
||||||
export default function NoteTitleDetails() {
|
export default function NoteTitleDetails() {
|
||||||
const { note, noteContext } = useNoteContext();
|
const { note } = useNoteContext();
|
||||||
const isHiddenNote = note?.noteId.startsWith("_");
|
const noteType = useNoteProperty(note, "type");
|
||||||
const isDefaultView = noteContext?.viewScope?.viewMode === "default";
|
|
||||||
|
|
||||||
const items: ComponentChild[] = [].filter(item => !!item);
|
return (
|
||||||
|
|
||||||
return items.length && (
|
|
||||||
<div className="title-details">
|
<div className="title-details">
|
||||||
{joinElements(items, " • ")}
|
{note && noteType === "book" && <CollectionProperties note={note} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function TextWithValue({ i18nKey, value, valueTooltip }: {
|
|
||||||
i18nKey: string;
|
|
||||||
value: string;
|
|
||||||
valueTooltip: string;
|
|
||||||
}) {
|
|
||||||
const listItemRef = useRef<HTMLLIElement>(null);
|
|
||||||
useStaticTooltip(listItemRef, {
|
|
||||||
selector: "span.value",
|
|
||||||
title: valueTooltip,
|
|
||||||
popperConfig: { placement: "bottom" }
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<li ref={listItemRef}>
|
|
||||||
<Trans
|
|
||||||
i18nKey={i18nKey}
|
|
||||||
components={{
|
|
||||||
Value: <span className="value">{value}</span> as React.ReactElement
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
29
apps/client/src/widgets/note_bars/CollectionProperties.tsx
Normal file
29
apps/client/src/widgets/note_bars/CollectionProperties.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import FNote from "../../entities/fnote";
|
||||||
|
import { ViewTypeOptions } from "../collections/interface";
|
||||||
|
import Dropdown from "../react/Dropdown";
|
||||||
|
import { FormListItem } from "../react/FormList";
|
||||||
|
import { useViewType, VIEW_TYPE_MAPPINGS } from "../ribbon/CollectionPropertiesTab";
|
||||||
|
|
||||||
|
export default function CollectionProperties({ note }: { note: FNote }) {
|
||||||
|
return (
|
||||||
|
<ViewTypeSwitcher note={note} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ViewTypeSwitcher({ note }: { note: FNote }) {
|
||||||
|
const [ viewType, setViewType ] = useViewType(note);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
text={VIEW_TYPE_MAPPINGS[viewType as ViewTypeOptions ?? "grid"]}
|
||||||
|
>
|
||||||
|
{Object.entries(VIEW_TYPE_MAPPINGS).map(([ key, label ]) => (
|
||||||
|
<FormListItem
|
||||||
|
key={key}
|
||||||
|
onClick={() => setViewType(key)}
|
||||||
|
checked={viewType === key}
|
||||||
|
>{label}</FormListItem>
|
||||||
|
))}
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -89,8 +89,7 @@ body.experimental-feature-new-layout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title-details {
|
.title-details {
|
||||||
margin-bottom: 0.2em;
|
padding-bottom: 0.2em;
|
||||||
opacity: 0.65;
|
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,34 +12,41 @@ import FormCheckbox from "../react/FormCheckbox";
|
|||||||
import FormTextBox from "../react/FormTextBox";
|
import FormTextBox from "../react/FormTextBox";
|
||||||
import { ComponentChildren } from "preact";
|
import { ComponentChildren } from "preact";
|
||||||
import { ViewTypeOptions } from "../collections/interface";
|
import { ViewTypeOptions } from "../collections/interface";
|
||||||
import { FormDropdownDivider, FormListItem } from "../react/FormList";
|
import { isExperimentalFeatureEnabled } from "../../services/experimental_features";
|
||||||
|
|
||||||
const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
export const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
||||||
grid: t("book_properties.grid"),
|
grid: t("book_properties.grid"),
|
||||||
list: t("book_properties.list"),
|
list: t("book_properties.list"),
|
||||||
calendar: t("book_properties.calendar"),
|
calendar: t("book_properties.calendar"),
|
||||||
table: t("book_properties.table"),
|
table: t("book_properties.table"),
|
||||||
geoMap: t("book_properties.geo-map"),
|
geoMap: t("book_properties.geo-map"),
|
||||||
board: t("book_properties.board"),
|
board: t("book_properties.board"),
|
||||||
presentation: t("book_properties.presentation")
|
presentation: t("book_properties.presentation")
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CollectionPropertiesTab({ note }: TabContext) {
|
const isNewLayout = isExperimentalFeatureEnabled("new-layout");
|
||||||
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
|
||||||
const defaultViewType = (note?.type === "search" ? "list" : "grid");
|
|
||||||
const viewTypeWithDefault = (viewType ?? defaultViewType) as ViewTypeOptions;
|
|
||||||
const properties = bookPropertiesConfig[viewTypeWithDefault].properties;
|
|
||||||
|
|
||||||
return (
|
export default function CollectionPropertiesTab({ note }: TabContext) {
|
||||||
<div className="book-properties-widget">
|
const [viewType, setViewType] = useViewType(note);
|
||||||
{note && (
|
const properties = bookPropertiesConfig[viewType].properties;
|
||||||
<>
|
|
||||||
<CollectionTypeSwitcher viewType={viewTypeWithDefault} setViewType={setViewType} />
|
return (
|
||||||
<BookProperties viewType={viewTypeWithDefault} note={note} properties={properties} />
|
<div className="book-properties-widget">
|
||||||
</>
|
{note && (
|
||||||
)}
|
<>
|
||||||
</div>
|
{!isNewLayout && <CollectionTypeSwitcher viewType={viewType} setViewType={setViewType} />}
|
||||||
);
|
<BookProperties viewType={viewType} note={note} properties={properties} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useViewType(note: FNote | null | undefined) {
|
||||||
|
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
||||||
|
const defaultViewType = (note?.type === "search" ? "list" : "grid");
|
||||||
|
const viewTypeWithDefault = (viewType ?? defaultViewType) as ViewTypeOptions;
|
||||||
|
return [ viewTypeWithDefault, setViewType ] as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CollectionTypeSwitcher({ viewType, setViewType }: { viewType: string, setViewType: (newValue: string) => void }) {
|
function CollectionTypeSwitcher({ viewType, setViewType }: { viewType: string, setViewType: (newValue: string) => void }) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user