mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 12:09:02 +01:00
chore(react/ribbon): port order by
This commit is contained in:
parent
2fd3a875b6
commit
73f20d01e4
@ -23,14 +23,15 @@ interface FormSelectProps<T, Q> extends ValueConfig<T, Q> {
|
||||
name?: string;
|
||||
onChange: OnChangeListener;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combobox component that takes in any object array as data. Each item of the array is rendered as an item, and the key and values are obtained by looking into the object by a specified key.
|
||||
*/
|
||||
export default function FormSelect<T>({ name, id, onChange, style, ...restProps }: FormSelectProps<T, T>) {
|
||||
export default function FormSelect<T>({ name, id, onChange, style, className, ...restProps }: FormSelectProps<T, T>) {
|
||||
return (
|
||||
<FormSelectBody name={name} id={id} onChange={onChange} style={style}>
|
||||
<FormSelectBody name={name} id={id} onChange={onChange} style={style} className={className}>
|
||||
<FormSelectGroup {...restProps} />
|
||||
</FormSelectBody>
|
||||
);
|
||||
@ -39,9 +40,9 @@ export default function FormSelect<T>({ name, id, onChange, style, ...restProps
|
||||
/**
|
||||
* Similar to {@link FormSelect}, but the top-level elements are actually groups.
|
||||
*/
|
||||
export function FormSelectWithGroups<T>({ name, id, values, keyProperty, titleProperty, currentValue, onChange }: FormSelectProps<T, FormSelectGroup<T> | T>) {
|
||||
export function FormSelectWithGroups<T>({ name, id, values, keyProperty, titleProperty, currentValue, onChange, ...restProps }: FormSelectProps<T, FormSelectGroup<T> | T>) {
|
||||
return (
|
||||
<FormSelectBody name={name} id={id} onChange={onChange}>
|
||||
<FormSelectBody name={name} id={id} onChange={onChange} {...restProps}>
|
||||
{values.map((item) => {
|
||||
if (!item) return <></>;
|
||||
if (typeof item === "object" && "items" in item) {
|
||||
@ -60,13 +61,13 @@ export function FormSelectWithGroups<T>({ name, id, values, keyProperty, titlePr
|
||||
)
|
||||
}
|
||||
|
||||
function FormSelectBody({ id, name, children, onChange, style }: { id?: string, name?: string, children: ComponentChildren, onChange: OnChangeListener, style?: CSSProperties }) {
|
||||
function FormSelectBody({ id, name, children, onChange, style, className }: { id?: string, name?: string, children: ComponentChildren, onChange: OnChangeListener, style?: CSSProperties, className?: string }) {
|
||||
return (
|
||||
<select
|
||||
id={id}
|
||||
class="form-select"
|
||||
onChange={e => onChange((e.target as HTMLInputElement).value)}
|
||||
style={style}
|
||||
className={`form-select ${className ?? ""}`}
|
||||
>
|
||||
{children}
|
||||
</select>
|
||||
|
||||
@ -29,6 +29,7 @@ interface SearchOption {
|
||||
tooltip?: string;
|
||||
// TODO: Make mandatory once all components are ported.
|
||||
component?: (props: SearchOptionProps) => VNode;
|
||||
defaultValue?: string;
|
||||
additionalAttributesToDelete?: { type: "label" | "relation", name: string }[];
|
||||
}
|
||||
|
||||
@ -52,6 +53,7 @@ const SEARCH_OPTIONS: SearchOption[] = [
|
||||
{
|
||||
attributeName: "searchScript",
|
||||
attributeType: "relation",
|
||||
defaultValue: "root",
|
||||
icon: "bx bx-code",
|
||||
label: t("search_definition.search_script"),
|
||||
component: SearchScriptOption
|
||||
@ -59,9 +61,10 @@ const SEARCH_OPTIONS: SearchOption[] = [
|
||||
{
|
||||
attributeName: "ancestor",
|
||||
attributeType: "relation",
|
||||
defaultValue: "root",
|
||||
icon: "bx bx-filter-alt",
|
||||
label: t("search_definition.ancestor"),
|
||||
component: AncestorOption,
|
||||
component: AncestorOption,
|
||||
additionalAttributesToDelete: [ { type: "label", name: "ancestorDepth" } ]
|
||||
},
|
||||
{
|
||||
@ -83,8 +86,11 @@ const SEARCH_OPTIONS: SearchOption[] = [
|
||||
{
|
||||
attributeName: "orderBy",
|
||||
attributeType: "label",
|
||||
defaultValue: "relevancy",
|
||||
icon: "bx bx-arrow-from-top",
|
||||
label: t("search_definition.order_by")
|
||||
label: t("search_definition.order_by"),
|
||||
component: OrderByOption,
|
||||
additionalAttributesToDelete: [ { type: "label", name: "orderDirection" } ]
|
||||
},
|
||||
{
|
||||
attributeName: "limit",
|
||||
@ -162,15 +168,12 @@ export default function SearchDefinitionTab({ note, ntxId }: TabContext) {
|
||||
<tr>
|
||||
<td className="title-column">{t("search_definition.add_search_option")}</td>
|
||||
<td colSpan={2} className="add-search-option">
|
||||
{searchOptions?.availableOptions.map(({ icon, label, tooltip, attributeName, attributeType }) => (
|
||||
{searchOptions?.availableOptions.map(({ icon, label, tooltip, attributeName, attributeType, defaultValue }) => (
|
||||
<Button
|
||||
icon={icon}
|
||||
text={label}
|
||||
title={tooltip}
|
||||
onClick={() => {
|
||||
const defaultValue = (attributeType === "relation" ? "root" : "");
|
||||
attributes.setAttribute(note, attributeType, attributeName, defaultValue);
|
||||
}}
|
||||
onClick={() => attributes.setAttribute(note, attributeType, attributeName, defaultValue ?? "")}
|
||||
/>
|
||||
))}
|
||||
</td>
|
||||
@ -436,4 +439,47 @@ function IncludeArchivedNotesOption({ ...restProps }: SearchOptionProps) {
|
||||
titleIcon="bx bx-archive" title={t("include_archived_notes.include_archived_notes")}
|
||||
{...restProps}
|
||||
/>
|
||||
}
|
||||
|
||||
function OrderByOption({ note, ...restProps }: SearchOptionProps) {
|
||||
const [ orderBy, setOrderBy ] = useNoteLabel(note, "orderBy");
|
||||
const [ orderDirection, setOrderDirection ] = useNoteLabel(note, "orderDirection");
|
||||
|
||||
return <SearchOption
|
||||
titleIcon="bx bx-arrow-from-top"
|
||||
title={t("order_by.order_by")}
|
||||
note={note} {...restProps}
|
||||
>
|
||||
<FormSelect
|
||||
className="w-auto d-inline"
|
||||
currentValue={orderBy ?? "relevancy"} onChange={setOrderBy}
|
||||
keyProperty="value" titleProperty="title"
|
||||
values={[
|
||||
{ value: "relevancy", title: t("order_by.relevancy") },
|
||||
{ value: "title", title: t("order_by.title") },
|
||||
{ value: "dateCreated", title: t("order_by.date_created") },
|
||||
{ value: "dateModified", title: t("order_by.date_modified") },
|
||||
{ value: "contentSize", title: t("order_by.content_size") },
|
||||
{ value: "contentAndAttachmentsSize", title: t("order_by.content_and_attachments_size") },
|
||||
{ value: "contentAndAttachmentsAndRevisionsSize", title: t("order_by.content_and_attachments_and_revisions_size") },
|
||||
{ value: "revisionCount", title: t("order_by.revision_count") },
|
||||
{ value: "childrenCount", title: t("order_by.children_count") },
|
||||
{ value: "parentCount", title: t("order_by.parent_count") },
|
||||
{ value: "ownedLabelCount", title: t("order_by.owned_label_count") },
|
||||
{ value: "ownedRelationCount", title: t("order_by.owned_relation_count") },
|
||||
{ value: "targetRelationCount", title: t("order_by.target_relation_count") },
|
||||
{ value: "random", title: t("order_by.random") }
|
||||
]}
|
||||
/>
|
||||
{" "}
|
||||
<FormSelect
|
||||
className="w-auto d-inline"
|
||||
currentValue={orderDirection ?? "asc"} onChange={setOrderDirection}
|
||||
keyProperty="value" titleProperty="title"
|
||||
values={[
|
||||
{ value: "asc", title: t("order_by.asc") },
|
||||
{ value: "desc", title: t("order_by.desc") }
|
||||
]}
|
||||
/>
|
||||
</SearchOption>
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
import AbstractSearchOption from "./abstract_search_option.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
|
||||
const TPL = /*html*/`
|
||||
<tr data-search-option-conf="orderBy">
|
||||
<td class="title-column">
|
||||
<span class="bx bx-arrow-from-top"></span>
|
||||
${t("order_by.order_by")}
|
||||
</td>
|
||||
<td>
|
||||
<select name="orderBy" class="form-control w-auto d-inline">
|
||||
<option value="relevancy">${t("order_by.relevancy")}</option>
|
||||
<option value="title">${t("order_by.title")}</option>
|
||||
<option value="dateCreated">${t("order_by.date_created")}</option>
|
||||
<option value="dateModified">${t("order_by.date_modified")}</option>
|
||||
<option value="contentSize">${t("order_by.content_size")}</option>
|
||||
<option value="contentAndAttachmentsSize">${t("order_by.content_and_attachments_size")}</option>
|
||||
<option value="contentAndAttachmentsAndRevisionsSize">${t("order_by.content_and_attachments_and_revisions_size")}</option>
|
||||
<option value="revisionCount">${t("order_by.revision_count")}</option>
|
||||
<option value="childrenCount">${t("order_by.children_count")}</option>
|
||||
<option value="parentCount">${t("order_by.parent_count")}</option>
|
||||
<option value="ownedLabelCount">${t("order_by.owned_label_count")}</option>
|
||||
<option value="ownedRelationCount">${t("order_by.owned_relation_count")}</option>
|
||||
<option value="targetRelationCount">${t("order_by.target_relation_count")}</option>
|
||||
<option value="random">${t("order_by.random")}</option>
|
||||
</select>
|
||||
|
||||
<select name="orderDirection" class="form-control w-auto d-inline">
|
||||
<option value="asc">${t("order_by.asc")}</option>
|
||||
<option value="desc">${t("order_by.desc")}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="button-column">
|
||||
<span class="bx bx-x icon-action search-option-del"></span>
|
||||
</td>
|
||||
</tr>`;
|
||||
|
||||
export default class OrderBy extends AbstractSearchOption {
|
||||
|
||||
static async create(noteId: string) {
|
||||
await AbstractSearchOption.setAttribute(noteId, "label", "orderBy", "relevancy");
|
||||
await AbstractSearchOption.setAttribute(noteId, "label", "orderDirection", "asc");
|
||||
}
|
||||
|
||||
doRender() {
|
||||
const $option = $(TPL);
|
||||
|
||||
const $orderBy = $option.find("select[name=orderBy]");
|
||||
$orderBy.on("change", async () => {
|
||||
const orderBy = String($orderBy.val());
|
||||
|
||||
await this.setAttribute("label", "orderBy", orderBy);
|
||||
});
|
||||
$orderBy.val(this.note.getLabelValue("orderBy") ?? "");
|
||||
|
||||
const $orderDirection = $option.find("select[name=orderDirection]");
|
||||
$orderDirection.on("change", async () => {
|
||||
const orderDirection = String($orderDirection.val());
|
||||
|
||||
await this.setAttribute("label", "orderDirection", orderDirection);
|
||||
});
|
||||
$orderDirection.val(this.note.getLabelValue("orderDirection") || "asc");
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
async deleteOption() {
|
||||
await this.deleteAttribute("label", "orderDirection");
|
||||
|
||||
await super.deleteOption();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user