import { NodeModel, NodeRender } from "@minoru/react-dnd-treeview"; import { FC, ReactNode } from "react"; import { useGlobal, useLocal } from "web-utils"; import { EDGlobal, active } from "../../../logic/ed-global"; import { compPicker, reloadCompPicker } from "./comp-reload"; import { treeRebuild } from "../../../logic/tree/build"; import tc from "tinycolor2"; export type CompItem = { id: string; name: string; type: "component" | "folder"; }; export const edPageTreeRender: NodeRender = ( node: NodeModel, { depth, isOpen, onToggle } ) => { const p = useGlobal(EDGlobal, "EDITOR"); const local = useLocal({ renaming: node.id === "", rename_to: "" }); const item = node.data; if (!item) return <>; const isTrashed = !!compPicker.trash.find((e) => e.id === item.id); const addComponent = (e: React.MouseEvent) => { if (isTrashed) { p.ui.popup.comp.preview_id = item.id; p.ui.popup.comp_group = { mouse_event: e, async on_pick(group_id) { await _db.component.update({ where: { id: item.id }, data: { id_component_group: group_id }, }); await reloadCompPicker(p); treeRebuild(p); p.render(); }, }; p.render(); } else { if (p.ui.popup.comp.open) { p.ui.popup.comp.open(item.id); } p.ui.popup.comp.open = null; active.item_id = compPicker.active_id; compPicker.active_id = ""; treeRebuild(p); p.render(); } }; const delComponent = async (comp_id: string) => { if (isTrashed) { if (confirm("Permanently delete this component?")) { await _db.component.delete({ where: { id: p.ui.popup.comp.preview_id }, }); const idx = compPicker.tree.findIndex((e) => e.id === comp_id) + 1; if (idx >= 0 && compPicker.tree[idx]) p.ui.popup.comp.preview_id = compPicker.tree[idx].id as any; compPicker.tree = compPicker.tree.filter((e) => e.id !== comp_id); p.render(); } } else { if (confirm("Move component to trash?")) { await _db.component.update({ where: { id: comp_id }, data: { id_component_group: compPicker.trash_id }, }); await reloadCompPicker(p); p.render(); } } }; return (
{ if (item.type === "folder") { onToggle(); } else { addComponent(e); } }} > {item.type === "component" && }
{item.id === p.page.cur.id && (
)}
{item.type === "folder" && ( <> {isOpen && } {!isOpen && } )}
{local.renaming ? ( { local.renaming = false; item.name = local.rename_to; if (item.id === "") { if (item.name) { _db.page_folder.create({ data: { name: local.rename_to, id_site: p.site.id }, }); } await reloadCompPicker(p); } else { _db.page_folder.update({ where: { id: item.id }, data: { name: local.rename_to }, }); } local.render(); }} className="border px-1 bg-white flex-1 outline-none mr-1 border-blue-500 " onChange={(e) => { local.rename_to = e.currentTarget.value; local.render(); }} onKeyDown={(e) => { if (e.key === "Enter") e.currentTarget.blur(); if (e.key === "Escape") { local.rename_to = item.name; local.render(); e.currentTarget.blur(); } }} /> ) : ( )}
{item.type === "component" && (
{ e.stopPropagation(); delComponent(item.id); }} >
)}
); }; const colorize = (str: string) => { let hash = 0; if (str.length === 0) return ""; for (let i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); hash = hash & hash; } var color = "#"; for (var i = 0; i < 3; i++) { var value = (hash >> (i * 8)) & 255; color += ("00" + value.toString(16)).substr(-2); } return color; }; const Name: FC<{ name: ReactNode }> = ({ name }) => { if (typeof name !== "string") return name; if (name === "__TRASH__") return "Trash"; if (name.startsWith("layout::")) { return (
LAYOUT
{name.substring("layout::".length)}
); } return
{name}
; }; const Pic: FC<{ name: string }> = ({ name }) => { const bg = colorize(name); const fg = tc(bg); return (
{name.split("_").join(" ")}
); }; const CheckIcon = () => (
`, }} >
); const ResetIcon = () => (
`, }} >
); const PlayIcon = () => (
`, }} >
); const DeleteIcon = () => ( ); const FolderClose = () => ( ); const EditIcon = () => ( ); const FolderOpen = () => ( );