From 2447a5005fc76ee0f25f645cfcfa5c65f54b671b Mon Sep 17 00:00:00 2001 From: Rizky Date: Tue, 28 Nov 2023 14:01:12 +0700 Subject: [PATCH] wip fix search --- .../nova/ed/panel/popup/page/page-popup.tsx | 31 +++++++++++++++--- .../nova/ed/panel/popup/page/page-reload.ts | 17 ++++++---- .../nova/ed/panel/popup/page/page-tree.tsx | 32 +++++++++++++++---- .../src/nova/ed/panel/tree/node/item/name.tsx | 4 +-- app/web/src/utils/ui/fuzzy.tsx | 12 ++++--- 5 files changed, 73 insertions(+), 23 deletions(-) diff --git a/app/web/src/nova/ed/panel/popup/page/page-popup.tsx b/app/web/src/nova/ed/panel/popup/page/page-popup.tsx index 7b44e41f..1c2b2c83 100644 --- a/app/web/src/nova/ed/panel/popup/page/page-popup.tsx +++ b/app/web/src/nova/ed/panel/popup/page/page-popup.tsx @@ -7,13 +7,18 @@ import { } from "@minoru/react-dnd-treeview"; import { useEffect } from "react"; import { HTML5Backend } from "react-dnd-html5-backend"; -import { useGlobal, useLocal, waitUntil } from "web-utils"; +import { deepClone, useGlobal, useLocal, waitUntil } from "web-utils"; import { Loading } from "../../../../../utils/ui/loading"; import { Modal } from "../../../../../utils/ui/modal"; import { EDGlobal } from "../../../logic/ed-global"; -import { pagePicker, reloadPagePicker } from "./page-reload"; +import { + pagePicker, + pagePickerRootItem, + reloadPagePicker, +} from "./page-reload"; import { PageItem, edPageTreeRender } from "./page-tree"; import { EdFormPage } from "./page-form"; +import { fuzzy } from "../../../../../utils/ui/fuzzy"; export const EdPopPage = () => { const p = useGlobal(EDGlobal, "EDITOR"); @@ -35,7 +40,7 @@ export const EdPopPage = () => { cur = pagePicker.tree.find((e) => e.id === parent_id); } } - if (parents.length === 0) { + if (parents.length <= 1) { local.tree.open("page-root"); } else { local.tree.open(parents); @@ -51,6 +56,24 @@ export const EdPopPage = () => { reloadPagePicker(p); } + let filtered = pagePicker.tree; + if (pagePicker.search) { + const result = fuzzy( + deepClone(pagePicker.tree), + { pk: "id", search: ["text", "data.url"] as any }, + pagePicker.search + ); + + if (!result.find((e) => e.id === "root")) { + filtered = [...result, pagePickerRootItem]; + } else { + filtered = result; + } + filtered.map((e) => { + if (e.id !== "root") e.parent = "root"; + }); + } + return ( <> { local.tree = ref; } }} - tree={pagePicker.tree} + tree={filtered} rootId={"page-root"} onDrop={async (newTree: NodeModel[], opt) => { pagePicker.tree = newTree; diff --git a/app/web/src/nova/ed/panel/popup/page/page-reload.ts b/app/web/src/nova/ed/panel/popup/page/page-reload.ts index 87ad9c97..59fa6c21 100644 --- a/app/web/src/nova/ed/panel/popup/page/page-reload.ts +++ b/app/web/src/nova/ed/panel/popup/page/page-reload.ts @@ -2,11 +2,20 @@ import { NodeModel } from "@minoru/react-dnd-treeview"; import { PG } from "../../../logic/ed-global"; import { PageItem } from "./page-tree"; +export const pagePickerRootItem = { + id: "root", + parent: "page-root", + text: "pages", + droppable: true, + data: { id: "root", name: "pages", type: "folder" as "folder" | "page" }, +}; + export const pagePicker = { site_id: "", ref: null as any, tree: [] as NodeModel[], status: "ready" as "loading" | "ready", + search: "", render: () => {}, }; @@ -33,13 +42,7 @@ export const reloadPagePicker = async (p: PG) => { pagePicker.tree = []; const tree = pagePicker.tree; - tree.push({ - id: "root", - parent: "page-root", - text: "pages", - droppable: true, - data: { id: "root", name: "pages", type: "folder" }, - }); + tree.push(pagePickerRootItem); for (const page of pages) { tree.push({ diff --git a/app/web/src/nova/ed/panel/popup/page/page-tree.tsx b/app/web/src/nova/ed/panel/popup/page/page-tree.tsx index a7bba1ed..e7327da2 100644 --- a/app/web/src/nova/ed/panel/popup/page/page-tree.tsx +++ b/app/web/src/nova/ed/panel/popup/page/page-tree.tsx @@ -1,7 +1,7 @@ import { NodeModel, NodeRender } from "@minoru/react-dnd-treeview"; import { useGlobal, useLocal } from "web-utils"; import { EDGlobal } from "../../../logic/ed-global"; -import { FC } from "react"; +import { FC, ReactNode } from "react"; import { pagePicker, reloadPagePicker } from "./page-reload"; export type PageItem = { @@ -17,7 +17,7 @@ export const edPageTreeRender: NodeRender = ( const p = useGlobal(EDGlobal, "EDITOR"); const local = useLocal({ renaming: node.id === "", rename_to: "" }); const item = node.data; - if (!item) return <>; + if (!item || !item.name) return <>; return (
= ( }} /> ) : ( - + )}
@@ -199,13 +199,33 @@ export const edPageTreeRender: NodeRender = ( )} -
{item.url}
+
+ {item.id === "root" ? ( + { + e.preventDefault(); + e.stopPropagation(); + }} + spellCheck={false} + onChange={(e) => { + pagePicker.search = e.currentTarget.value; + pagePicker.render(); + }} + value={pagePicker.search} + type="search" + placeholder="Search.." + /> + ) : ( + item.url + )} +
); }; -const Name: FC<{ name: string }> = ({ name }) => { - if (name.startsWith("layout:")) { +const Name: FC<{ name: ReactNode }> = ({ name }) => { + if (typeof name === "string" && name.startsWith("layout:")) { return (
diff --git a/app/web/src/nova/ed/panel/tree/node/item/name.tsx b/app/web/src/nova/ed/panel/tree/node/item/name.tsx index d84a237c..d8a60aa6 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/name.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/name.tsx @@ -96,7 +96,7 @@ const Name: FC<{ name: string; is_jsx_prop: boolean }> = ({ ); } - if (name.startsWith("jsx:")) { + if (typeof name === "string" && name.startsWith("jsx:")) { return (
@@ -112,7 +112,7 @@ const Name: FC<{ name: string; is_jsx_prop: boolean }> = ({ ); } - if (name.startsWith("jsx=")) { + if (typeof name === "string" && name.startsWith("jsx=")) { return (
( @@ -21,7 +23,7 @@ export const fuzzy = ( if (!result[id]) { result[id] = { idx, row }; } else { - result[id].row[f] = row[f]; + set(result[id].row, f, get(row, f)); } } } @@ -39,7 +41,7 @@ const fuzzySingle = ( search: string ) => { const [idxs, info] = uf.search( - array.map((e) => e[field]) as string[], + [...array.map((e) => get(e, field) || "")] as string[], search ); @@ -49,7 +51,7 @@ const fuzzySingle = ( for (const idx of idxs) { const item = array[idx]; const range = [...info.ranges[ri++]]; - const val = item[field] as string; + const val = get(item, field) as string; let cur = range.shift(); let openBold = false; @@ -86,7 +88,9 @@ const fuzzySingle = ( dangerouslySetInnerHTML={{ __html: text }} /> ); - result.push({ ...item, [field]: el }); + const newitem = { ...item }; + set(newitem, field, el); + result.push(newitem); } return result; }