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 { 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";
|
||||
import CollectionProperties from "./note_bars/CollectionProperties";
|
||||
import { useNoteContext, useNoteProperty } from "./react/hooks";
|
||||
|
||||
export default function NoteTitleDetails() {
|
||||
const { note, noteContext } = useNoteContext();
|
||||
const isHiddenNote = note?.noteId.startsWith("_");
|
||||
const isDefaultView = noteContext?.viewScope?.viewMode === "default";
|
||||
const { note } = useNoteContext();
|
||||
const noteType = useNoteProperty(note, "type");
|
||||
|
||||
const items: ComponentChild[] = [].filter(item => !!item);
|
||||
|
||||
return items.length && (
|
||||
return (
|
||||
<div className="title-details">
|
||||
{joinElements(items, " • ")}
|
||||
{note && noteType === "book" && <CollectionProperties note={note} />}
|
||||
</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 {
|
||||
margin-bottom: 0.2em;
|
||||
opacity: 0.65;
|
||||
padding-bottom: 0.2em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@ import FormCheckbox from "../react/FormCheckbox";
|
||||
import FormTextBox from "../react/FormTextBox";
|
||||
import { ComponentChildren } from "preact";
|
||||
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"),
|
||||
list: t("book_properties.list"),
|
||||
calendar: t("book_properties.calendar"),
|
||||
@ -24,24 +24,31 @@ const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
||||
presentation: t("book_properties.presentation")
|
||||
};
|
||||
|
||||
const isNewLayout = isExperimentalFeatureEnabled("new-layout");
|
||||
|
||||
export default function CollectionPropertiesTab({ note }: TabContext) {
|
||||
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
||||
const defaultViewType = (note?.type === "search" ? "list" : "grid");
|
||||
const viewTypeWithDefault = (viewType ?? defaultViewType) as ViewTypeOptions;
|
||||
const properties = bookPropertiesConfig[viewTypeWithDefault].properties;
|
||||
const [viewType, setViewType] = useViewType(note);
|
||||
const properties = bookPropertiesConfig[viewType].properties;
|
||||
|
||||
return (
|
||||
<div className="book-properties-widget">
|
||||
{note && (
|
||||
<>
|
||||
<CollectionTypeSwitcher viewType={viewTypeWithDefault} setViewType={setViewType} />
|
||||
<BookProperties viewType={viewTypeWithDefault} note={note} properties={properties} />
|
||||
{!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 }) {
|
||||
const collectionTypes = useMemo(() => mapToKeyValueArray(VIEW_TYPE_MAPPINGS), []);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user