mirror of
https://github.com/zadam/trilium.git
synced 2025-11-03 13:09:01 +01:00
feat(react/ribbon): port view type
This commit is contained in:
parent
652114c7b5
commit
ce1f5c6204
@ -808,6 +808,14 @@ export function numberObjectsInPlace<T extends object>(items: T[]): Indexed<T>[]
|
|||||||
return items as Indexed<T>[];
|
return items as Indexed<T>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapToKeyValueArray<K extends string | number | symbol, V>(map: Record<K, V>) {
|
||||||
|
const values: { key: K, value: V }[] = [];
|
||||||
|
for (const [ key, value ] of Object.entries(map)) {
|
||||||
|
values.push({ key: key as K, value: value as V });
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
reloadFrontendApp,
|
reloadFrontendApp,
|
||||||
restartDesktopApp,
|
restartDesktopApp,
|
||||||
|
|||||||
45
apps/client/src/widgets/ribbon/CollectionPropertiesTab.tsx
Normal file
45
apps/client/src/widgets/ribbon/CollectionPropertiesTab.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { useMemo } from "preact/hooks";
|
||||||
|
import { t } from "../../services/i18n";
|
||||||
|
import { ViewTypeOptions } from "../../services/note_list_renderer";
|
||||||
|
import FormSelect from "../react/FormSelect";
|
||||||
|
import { TabContext } from "./ribbon-interface";
|
||||||
|
import { mapToKeyValueArray } from "../../services/utils";
|
||||||
|
import { useNoteLabel } from "../react/hooks";
|
||||||
|
import FNote from "../../entities/fnote";
|
||||||
|
import FormGroup from "../react/FormGroup";
|
||||||
|
|
||||||
|
const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
||||||
|
grid: t("book_properties.grid"),
|
||||||
|
list: t("book_properties.list"),
|
||||||
|
calendar: t("book_properties.calendar"),
|
||||||
|
table: t("book_properties.table"),
|
||||||
|
geoMap: t("book_properties.geo-map"),
|
||||||
|
board: t("book_properties.board")
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CollectionPropertiesTab({ note }: TabContext) {
|
||||||
|
return (note &&
|
||||||
|
<div className="book-properties-widget">
|
||||||
|
<CollectionTypeSwitcher note={note} />
|
||||||
|
|
||||||
|
<div className="book-properties-container">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CollectionTypeSwitcher({ note }: { note: FNote }) {
|
||||||
|
const collectionTypes = useMemo(() => mapToKeyValueArray(VIEW_TYPE_MAPPINGS), []);
|
||||||
|
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: "flex", alignItems: "baseline" }}>
|
||||||
|
<span style={{ whiteSpace: "nowrap" }}>{t("book_properties.view_type")}: </span>
|
||||||
|
<FormSelect
|
||||||
|
currentValue={viewType ?? "grid"} onChange={setViewType}
|
||||||
|
values={collectionTypes}
|
||||||
|
keyProperty="key" titleProperty="value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ import NotePathsTab from "./NotePathsTab";
|
|||||||
import NoteMapTab from "./NoteMapTab";
|
import NoteMapTab from "./NoteMapTab";
|
||||||
import OwnedAttributesTab from "./OwnedAttributesTab";
|
import OwnedAttributesTab from "./OwnedAttributesTab";
|
||||||
import InheritedAttributesTab from "./InheritedAttributesTab";
|
import InheritedAttributesTab from "./InheritedAttributesTab";
|
||||||
|
import CollectionPropertiesTab from "./CollectionPropertiesTab";
|
||||||
|
|
||||||
interface TitleContext {
|
interface TitleContext {
|
||||||
note: FNote | null | undefined;
|
note: FNote | null | undefined;
|
||||||
@ -71,9 +72,11 @@ const TAB_CONFIGURATION = numberObjectsInPlace<TabConfiguration>([
|
|||||||
activate: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
|
activate: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// BookPropertiesWidget
|
|
||||||
title: t("book_properties.book_properties"),
|
title: t("book_properties.book_properties"),
|
||||||
icon: "bx bx-book"
|
icon: "bx bx-book",
|
||||||
|
content: CollectionPropertiesTab,
|
||||||
|
show: ({ note }) => note?.type === "book",
|
||||||
|
toggleCommand: "toggleRibbonTabBookProperties"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("note_properties.info"),
|
title: t("note_properties.info"),
|
||||||
@ -157,7 +160,7 @@ export default function Ribbon() {
|
|||||||
const filteredTabs = useMemo(() => TAB_CONFIGURATION.filter(tab => typeof tab.show === "boolean" ? tab.show : tab.show?.(titleContext)), [ titleContext, note ]);
|
const filteredTabs = useMemo(() => TAB_CONFIGURATION.filter(tab => typeof tab.show === "boolean" ? tab.show : tab.show?.(titleContext)), [ titleContext, note ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="ribbon-container" style={{ contain: "none" }}>
|
<div className="ribbon-container" style={{ contain: "none" }}>
|
||||||
<div className="ribbon-top-row">
|
<div className="ribbon-top-row">
|
||||||
<div className="ribbon-tab-container">
|
<div className="ribbon-tab-container">
|
||||||
{filteredTabs.map(({ title, icon, index }) => (
|
{filteredTabs.map(({ title, icon, index }) => (
|
||||||
|
|||||||
@ -351,3 +351,40 @@
|
|||||||
padding: 14px 12px 13px 12px;
|
padding: 14px 12px 13px 12px;
|
||||||
}
|
}
|
||||||
/* #endregion */
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Book properties */
|
||||||
|
.book-properties-widget {
|
||||||
|
padding: 12px 12px 6px 12px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-widget > * {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-container > div {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-container > .type-number > label {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-container input[type="checkbox"] {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book-properties-container label {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-overflow: clip;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
/* #endregion */
|
||||||
@ -5,72 +5,6 @@ import type FNote from "../../entities/fnote.js";
|
|||||||
import type { EventData } from "../../components/app_context.js";
|
import type { EventData } from "../../components/app_context.js";
|
||||||
import { bookPropertiesConfig, BookProperty } from "./book_properties_config.js";
|
import { bookPropertiesConfig, BookProperty } from "./book_properties_config.js";
|
||||||
import attributes from "../../services/attributes.js";
|
import attributes from "../../services/attributes.js";
|
||||||
import type { ViewTypeOptions } from "../../services/note_list_renderer.js";
|
|
||||||
|
|
||||||
const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
|
||||||
grid: t("book_properties.grid"),
|
|
||||||
list: t("book_properties.list"),
|
|
||||||
calendar: t("book_properties.calendar"),
|
|
||||||
table: t("book_properties.table"),
|
|
||||||
geoMap: t("book_properties.geo-map"),
|
|
||||||
board: t("book_properties.board")
|
|
||||||
};
|
|
||||||
|
|
||||||
const TPL = /*html*/`
|
|
||||||
<div class="book-properties-widget">
|
|
||||||
<style>
|
|
||||||
.book-properties-widget {
|
|
||||||
padding: 12px 12px 6px 12px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-widget > * {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-container > div {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-container > .type-number > label {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-container input[type="checkbox"] {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.book-properties-container label {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-overflow: clip;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div style="display: flex; align-items: baseline">
|
|
||||||
<span style="white-space: nowrap">${t("book_properties.view_type")}: </span>
|
|
||||||
|
|
||||||
<select class="view-type-select form-select form-select-sm">
|
|
||||||
${Object.entries(VIEW_TYPE_MAPPINGS)
|
|
||||||
.filter(([type]) => type !== "raster")
|
|
||||||
.map(([type, label]) => `
|
|
||||||
<option value="${type}">${label}</option>
|
|
||||||
`).join("")}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="book-properties-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
||||||
|
|
||||||
@ -78,28 +12,7 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
private $propertiesContainer!: JQuery<HTMLElement>;
|
private $propertiesContainer!: JQuery<HTMLElement>;
|
||||||
private labelsToWatch: string[] = [];
|
private labelsToWatch: string[] = [];
|
||||||
|
|
||||||
get name() {
|
|
||||||
return "bookProperties";
|
|
||||||
}
|
|
||||||
|
|
||||||
get toggleCommand() {
|
|
||||||
return "toggleRibbonTabBookProperties";
|
|
||||||
}
|
|
||||||
|
|
||||||
isEnabled() {
|
|
||||||
return this.note && this.note.type === "book";
|
|
||||||
}
|
|
||||||
|
|
||||||
getTitle() {
|
|
||||||
return {
|
|
||||||
show: this.isEnabled(),
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
doRender() {
|
doRender() {
|
||||||
this.$widget = $(TPL);
|
|
||||||
this.contentSized();
|
|
||||||
|
|
||||||
this.$viewTypeSelect = this.$widget.find(".view-type-select");
|
this.$viewTypeSelect = this.$widget.find(".view-type-select");
|
||||||
this.$viewTypeSelect.on("change", () => this.toggleViewType(String(this.$viewTypeSelect.val())));
|
this.$viewTypeSelect.on("change", () => this.toggleViewType(String(this.$viewTypeSelect.val())));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user