mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 23:29:02 +02:00
feat(react/ribbon): reintroduce button collection properties
This commit is contained in:
parent
ce1f5c6204
commit
ea1397de63
@ -19,9 +19,10 @@ export interface ButtonProps {
|
|||||||
size?: "normal" | "small" | "micro";
|
size?: "normal" | "small" | "micro";
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
triggerCommand?: CommandNames;
|
triggerCommand?: CommandNames;
|
||||||
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = memo(({ name, buttonRef: _buttonRef, className, text, onClick, keyboardShortcut, icon, primary, disabled, size, style, triggerCommand }: ButtonProps) => {
|
const Button = memo(({ name, buttonRef: _buttonRef, className, text, onClick, keyboardShortcut, icon, primary, disabled, size, style, triggerCommand, ...restProps }: ButtonProps) => {
|
||||||
// Memoize classes array to prevent recreation
|
// Memoize classes array to prevent recreation
|
||||||
const classes = useMemo(() => {
|
const classes = useMemo(() => {
|
||||||
const classList: string[] = ["btn"];
|
const classList: string[] = ["btn"];
|
||||||
@ -65,6 +66,7 @@ const Button = memo(({ name, buttonRef: _buttonRef, className, text, onClick, ke
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
style={style}
|
style={style}
|
||||||
data-trigger-command={triggerCommand}
|
data-trigger-command={triggerCommand}
|
||||||
|
{...restProps}
|
||||||
>
|
>
|
||||||
{icon && <span className={`bx ${icon}`}></span>}
|
{icon && <span className={`bx ${icon}`}></span>}
|
||||||
{text} {shortcutElements}
|
{text} {shortcutElements}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { useMemo } from "preact/hooks";
|
import { useContext, useMemo } from "preact/hooks";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import { ViewTypeOptions } from "../../services/note_list_renderer";
|
import { ViewTypeOptions } from "../../services/note_list_renderer";
|
||||||
import FormSelect from "../react/FormSelect";
|
import FormSelect from "../react/FormSelect";
|
||||||
import { TabContext } from "./ribbon-interface";
|
import { TabContext } from "./ribbon-interface";
|
||||||
import { mapToKeyValueArray } from "../../services/utils";
|
import { mapToKeyValueArray } from "../../services/utils";
|
||||||
import { useNoteLabel } from "../react/hooks";
|
import { useNoteLabel } from "../react/hooks";
|
||||||
|
import { bookPropertiesConfig, BookProperty, ButtonProperty } from "../ribbon_widgets/book_properties_config";
|
||||||
|
import Button from "../react/Button";
|
||||||
|
import { ParentComponent } from "../react/react_utils";
|
||||||
import FNote from "../../entities/fnote";
|
import FNote from "../../entities/fnote";
|
||||||
import FormGroup from "../react/FormGroup";
|
|
||||||
|
|
||||||
const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
||||||
grid: t("book_properties.grid"),
|
grid: t("book_properties.grid"),
|
||||||
@ -18,19 +20,20 @@ const VIEW_TYPE_MAPPINGS: Record<ViewTypeOptions, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function CollectionPropertiesTab({ note }: TabContext) {
|
export default function CollectionPropertiesTab({ note }: TabContext) {
|
||||||
|
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
||||||
|
const viewTypeWithDefault = viewType ?? "grid";
|
||||||
|
const properties = bookPropertiesConfig[viewTypeWithDefault].properties;
|
||||||
|
|
||||||
return (note &&
|
return (note &&
|
||||||
<div className="book-properties-widget">
|
<div className="book-properties-widget">
|
||||||
<CollectionTypeSwitcher note={note} />
|
<CollectionTypeSwitcher viewType={viewTypeWithDefault} setViewType={setViewType} />
|
||||||
|
<BookProperties note={note} properties={properties} />
|
||||||
<div className="book-properties-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function CollectionTypeSwitcher({ note }: { note: FNote }) {
|
function CollectionTypeSwitcher({ viewType, setViewType }: { viewType: string, setViewType: (newValue: string) => void }) {
|
||||||
const collectionTypes = useMemo(() => mapToKeyValueArray(VIEW_TYPE_MAPPINGS), []);
|
const collectionTypes = useMemo(() => mapToKeyValueArray(VIEW_TYPE_MAPPINGS), []);
|
||||||
const [ viewType, setViewType ] = useNoteLabel(note, "viewType");
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", alignItems: "baseline" }}>
|
<div style={{ display: "flex", alignItems: "baseline" }}>
|
||||||
@ -42,4 +45,40 @@ function CollectionTypeSwitcher({ note }: { note: FNote }) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function BookProperties({ note, properties }: { note: FNote, properties: BookProperty[] }) {
|
||||||
|
return (
|
||||||
|
<div className="book-properties-container">
|
||||||
|
{properties.map(property => (
|
||||||
|
<div className={`type-${property}`}>
|
||||||
|
{mapPropertyView({ note, property })}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapPropertyView({ note, property }: { note: FNote, property: BookProperty }) {
|
||||||
|
switch (property.type) {
|
||||||
|
case "button":
|
||||||
|
return <ButtonPropertyView note={note} property={property} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ButtonPropertyView({ note, property }: { note: FNote, property: ButtonProperty }) {
|
||||||
|
const parentComponent = useContext(ParentComponent);
|
||||||
|
|
||||||
|
return <Button
|
||||||
|
text={property.label}
|
||||||
|
title={property.title}
|
||||||
|
icon={property.icon}
|
||||||
|
onClick={() => {
|
||||||
|
if (!parentComponent) return;
|
||||||
|
property.onClick({
|
||||||
|
note,
|
||||||
|
triggerCommand: parentComponent.triggerCommand.bind(parentComponent)
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
}
|
}
|
@ -40,18 +40,6 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleViewType(type: string) {
|
|
||||||
if (!this.noteId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!VIEW_TYPE_MAPPINGS.hasOwnProperty(type)) {
|
|
||||||
throw new Error(t("book_properties.invalid_view_type", { type }));
|
|
||||||
}
|
|
||||||
|
|
||||||
await attributeService.setLabel(this.noteId, "viewType", type);
|
|
||||||
}
|
|
||||||
|
|
||||||
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||||
if (loadResults.getAttributeRows().find((attr) =>
|
if (loadResults.getAttributeRows().find((attr) =>
|
||||||
attr.noteId === this.noteId
|
attr.noteId === this.noteId
|
||||||
@ -85,25 +73,6 @@ export default class BookPropertiesWidget extends NoteContextAwareWidget {
|
|||||||
$label.prepend($checkbox);
|
$label.prepend($checkbox);
|
||||||
$container.append($label);
|
$container.append($label);
|
||||||
break;
|
break;
|
||||||
case "button":
|
|
||||||
const $button = $("<button>", {
|
|
||||||
type: "button",
|
|
||||||
class: "btn btn-sm"
|
|
||||||
}).text(property.label);
|
|
||||||
if (property.title) {
|
|
||||||
$button.attr("title", property.title);
|
|
||||||
}
|
|
||||||
if (property.icon) {
|
|
||||||
$button.prepend($("<span>", { class: property.icon }));
|
|
||||||
}
|
|
||||||
$button.on("click", () => {
|
|
||||||
property.onClick({
|
|
||||||
note,
|
|
||||||
triggerCommand: this.triggerCommand.bind(this)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
$container.append($button);
|
|
||||||
break;
|
|
||||||
case "number":
|
case "number":
|
||||||
const $numberInput = $("<input>", {
|
const $numberInput = $("<input>", {
|
||||||
type: "number",
|
type: "number",
|
||||||
|
@ -15,7 +15,7 @@ interface CheckBoxProperty {
|
|||||||
bindToLabel: string
|
bindToLabel: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ButtonProperty {
|
export interface ButtonProperty {
|
||||||
type: "button",
|
type: "button",
|
||||||
label: string;
|
label: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user