feat(react/ribbon): start porting search definitions (buttons)

This commit is contained in:
Elian Doran
2025-08-24 11:38:50 +03:00
parent b607d1e628
commit ad85ee3531
4 changed files with 140 additions and 112 deletions

View File

@@ -22,6 +22,7 @@ import NoteMapTab from "./NoteMapTab";
import OwnedAttributesTab from "./OwnedAttributesTab"; import OwnedAttributesTab from "./OwnedAttributesTab";
import InheritedAttributesTab from "./InheritedAttributesTab"; import InheritedAttributesTab from "./InheritedAttributesTab";
import CollectionPropertiesTab from "./CollectionPropertiesTab"; import CollectionPropertiesTab from "./CollectionPropertiesTab";
import SearchDefinitionTab from "./SearchDefinitionTab";
interface TitleContext { interface TitleContext {
note: FNote | null | undefined; note: FNote | null | undefined;
@@ -60,9 +61,11 @@ const TAB_CONFIGURATION = numberObjectsInPlace<TabConfiguration>([
(note.hasLabel("executeDescription") || note.hasLabel("executeButton")) (note.hasLabel("executeDescription") || note.hasLabel("executeButton"))
}, },
{ {
// SearchDefinitionWidget
title: t("search_definition.search_parameters"), title: t("search_definition.search_parameters"),
icon: "bx bx-search" icon: "bx bx-search",
content: SearchDefinitionTab,
activate: true,
show: ({ note }) => note?.type === "search"
}, },
{ {
title: t("edited_notes.title"), title: t("edited_notes.title"),

View File

@@ -0,0 +1,80 @@
import { t } from "../../services/i18n";
import Button from "../react/Button";
import { TabContext } from "./ribbon-interface";
interface SearchOption {
searchOption: string;
icon: string;
label: string;
tooltip?: string;
}
const SEARCH_OPTIONS: SearchOption[] = [
{
searchOption: "searchString",
icon: "bx bx-text",
label: t("search_definition.search_string")
},
{
searchOption: "searchScript",
icon: "bx bx-code",
label: t("search_definition.search_script")
},
{
searchOption: "ancestor",
icon: "bx bx-filter-alt",
label: t("search_definition.ancestor")
},
{
searchOption: "fastSearch",
icon: "bx bx-run",
label: t("search_definition.fast_search"),
tooltip: t("search_definition.fast_search_description")
},
{
searchOption: "includeArchivedNotes",
icon: "bx bx-archive",
label: t("search_definition.include_archived"),
tooltip: t("search_definition.include_archived_notes_description")
},
{
searchOption: "orderBy",
icon: "bx bx-arrow-from-top",
label: t("search_definition.order_by")
},
{
searchOption: "limit",
icon: "bx bx-stop",
label: t("search_definition.limit"),
tooltip: t("search_definition.limit_description")
},
{
searchOption: "debug",
icon: "bx bx-bug",
label: t("search_definition.debug"),
tooltip: t("search_definition.debug_description")
}
];
export default function SearchDefinitionTab({ note }: TabContext) {
return (
<div className="search-definition-widget">
<div className="search-settings">
<table className="search-setting-table">
<tr>
<td className="title-column">{t("search_definition.add_search_option")}</td>
<td colSpan={2} className="add-search-option">
{SEARCH_OPTIONS.map(({ icon, label, tooltip }) => (
<Button
icon={icon}
text={label}
title={tooltip}
/>
))}
</td>
</tr>
</table>
</div>
</div>
)
}

View File

@@ -388,3 +388,55 @@
white-space: nowrap; white-space: nowrap;
} }
/* #endregion */ /* #endregion */
/* #region Search definition */
.search-setting-table {
margin-top: 0;
margin-bottom: 7px;
width: 100%;
border-collapse: separate;
border-spacing: 10px;
}
.search-setting-table div {
white-space: nowrap;
}
.search-setting-table .button-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
text-align: right;
}
.search-setting-table .title-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
}
.search-setting-table .button-column .dropdown-menu {
white-space: normal;
}
.attribute-list hr {
height: 1px;
border-color: var(--main-border-color);
position: relative;
top: 4px;
margin-top: 5px;
margin-bottom: 0;
}
.search-definition-widget input:invalid {
border: 3px solid red;
}
.add-search-option button {
margin: 3px;
}
.dropdown-header {
background-color: var(--accented-background-color);
}
/* #endregion */

View File

@@ -22,106 +22,10 @@ import type { AttributeType } from "../../entities/fattribute.js";
import { renderReactWidget } from "../react/react_utils.jsx"; import { renderReactWidget } from "../react/react_utils.jsx";
const TPL = /*html*/` const TPL = /*html*/`
<div class="search-definition-widget"> <div class="">
<style> <div class="">
.search-setting-table {
margin-top: 0;
margin-bottom: 7px;
width: 100%;
border-collapse: separate;
border-spacing: 10px;
}
.search-setting-table div {
white-space: nowrap;
}
.search-setting-table .button-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
text-align: right;
}
.search-setting-table .title-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
}
.search-setting-table .button-column .dropdown-menu {
white-space: normal;
}
.attribute-list hr {
height: 1px;
border-color: var(--main-border-color);
position: relative;
top: 4px;
margin-top: 5px;
margin-bottom: 0;
}
.search-definition-widget input:invalid {
border: 3px solid red;
}
.add-search-option button {
margin-top: 5px; /* to give some spacing when buttons overflow on the next line */
}
.dropdown-header {
background-color: var(--accented-background-color);
}
</style>
<div class="search-settings">
<table class="search-setting-table">
<tr> <tr>
<td class="title-column">${t("search_definition.add_search_option")}</td> <td>
<td colspan="2" class="add-search-option">
<button type="button" class="btn btn-sm" data-search-option-add="searchString">
<span class="bx bx-text"></span>
${t("search_definition.search_string")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="searchScript">
<span class="bx bx-code"></span>
${t("search_definition.search_script")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="ancestor">
<span class="bx bx-filter-alt"></span>
${t("search_definition.ancestor")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="fastSearch"
title="${t("search_definition.fast_search_description")}">
<span class="bx bx-run"></span>
${t("search_definition.fast_search")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="includeArchivedNotes"
title="${t("search_definition.include_archived_notes_description")}">
<span class="bx bx-archive"></span>
${t("search_definition.include_archived")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="orderBy">
<span class="bx bx-arrow-from-top"></span>
${t("search_definition.order_by")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="limit" title="${t("search_definition.limit_description")}">
<span class="bx bx-stop"></span>
${t("search_definition.limit")}
</button>
<button type="button" class="btn btn-sm" data-search-option-add="debug" title="${t("search_definition.debug_description")}">
<span class="bx bx-bug"></span>
${t("search_definition.debug")}
</button>
<div class="dropdown" style="display: inline-block;"> <div class="dropdown" style="display: inline-block;">
<button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="bx bxs-zap"></span> <span class="bx bxs-zap"></span>
@@ -180,17 +84,6 @@ export default class SearchDefinitionWidget extends NoteContextAwareWidget {
return "searchDefinition"; return "searchDefinition";
} }
isEnabled() {
return this.note && this.note.type === "search";
}
getTitle() {
return {
show: this.isEnabled(),
activate: true
};
}
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.contentSized(); this.contentSized();