diff --git a/app/srv/ws/sync/editor/load-page-comp.ts b/app/srv/ws/sync/editor/load-page-comp.ts index d282fe8f..dc9cb1a6 100644 --- a/app/srv/ws/sync/editor/load-page-comp.ts +++ b/app/srv/ws/sync/editor/load-page-comp.ts @@ -3,7 +3,7 @@ import { ensureMProp, ensurePropContent, } from "../../../../web/src/nova/ed/logic/tree/sync-walk-utils"; -import { MItem } from "../../../../web/src/utils/types/item"; +import { IItem, MItem } from "../../../../web/src/utils/types/item"; import { FNCompDef, FNComponent, @@ -12,12 +12,14 @@ import { parseJs } from "./parser/parse-js"; export const extractMItemProps = (arg: { mitem: MItem; + item: IItem; item_comp: FNComponent; mcomp: MItem; scope: Exclude, undefined>; + content_scope?: Record; mcontent: (mcontent: MItem, prop_name: string) => void; }) => { - const { mitem, item_comp, mcomp, scope } = arg; + const { mitem, item, content_scope, item_comp, mcomp, scope } = arg; const mitem_comp = mitem.get("component"); const mprops = mcomp.get("component")?.get("props")?.toJSON() as Record< @@ -30,6 +32,9 @@ export const extractMItemProps = (arg: { for (const [k, v] of Object.entries(mprops)) { scope.props[k] = { name: k, value: `null as any` }; const mprop = ensureMProp(mitem_props, k, v); + + parseJs(v.value, { item, content_scope }); + item_comp.props[k] = v; if (mprop && v.meta?.type === "content-element") { scope.props[k].value = "null as ReactElement"; diff --git a/app/srv/ws/sync/editor/load-page.ts b/app/srv/ws/sync/editor/load-page.ts index 5aefa599..007a2bcb 100644 --- a/app/srv/ws/sync/editor/load-page.ts +++ b/app/srv/ws/sync/editor/load-page.ts @@ -14,7 +14,7 @@ import { gzipAsync } from "../entity/zlib"; import { SyncConnection } from "../type"; import { loadComponent } from "./load-component"; import { extractMItemProps } from "./load-page-comp"; -import { parseJs } from "./parser/parse-js"; +import { ArgParentMComp, parseJs } from "./parser/parse-js"; export const serverWalkLoad = async ( mitem: MItem, @@ -77,19 +77,6 @@ export const serverWalkLoad = async ( } }; -type ArgParentMComp = EdMeta["parent_mcomp"] & { - id: string; - parent_ids: string[]; - jsx_props: Record< - string, - { - id: string; - mitem: MItem; - parent_mcomp?: ArgParentMComp; - parent_ids: string[]; - } - >; -}; export const serverWalkMap = ( p: { sync: SyncConnection; @@ -102,6 +89,7 @@ export const serverWalkMap = ( parent_ids: string[]; parent_item: EdMeta["parent_item"]; parent_mcomp?: ArgParentMComp; + content_scope?: Record; } ) => { const { mitem, parent_item, parent_mcomp } = arg; @@ -133,10 +121,6 @@ export const serverWalkMap = ( item.id = override_id; } - if (item.name === "render_col") { - console.log(item); - } - const item_comp = item.component; const mitem_comp = mitem.get("component"); if (item_comp && item_comp.id) { @@ -148,6 +132,8 @@ export const serverWalkMap = ( extractMItemProps({ item_comp, mitem, + item, + content_scope: arg.content_scope, mcomp: mitem, scope, mcontent(mcontent) {}, @@ -159,7 +145,10 @@ export const serverWalkMap = ( }; const js = item.adv?.js; if (typeof js === "string") { - const s = parseJs(js); + const s = parseJs(js, { + item, + content_scope: arg.content_scope, + }); const ps = p.scope[item.id].s; if (ps) { if (s?.local) ps.local = s.local; @@ -206,24 +195,27 @@ export const serverWalkMap = ( jsx_props: {}, }; - const content_scope: Record = {}; + const content_scope: Record = {}; extractMItemProps({ item_comp, + item, mitem, mcomp, scope, + content_scope: arg.content_scope, mcontent(mcontent, prop_name) { const id = mcontent.get("id"); if (id) { + let cid = ref_ids[id] || id; parent_mcomp.jsx_props[prop_name] = { - id, + id: cid, mitem: mcontent, parent_mcomp: arg.parent_mcomp, parent_ids: [...arg.parent_ids, item.id], }; - content_scope[prop_name] = mcontent; + content_scope[prop_name] = cid; } }, }); @@ -233,7 +225,10 @@ export const serverWalkMap = ( const js = item.adv?.js; if (typeof js === "string") { - const res = parseJs(js); + const res = parseJs(js, { + item, + content_scope: arg.content_scope, + }); if (res) { scope.local = res.local; scope.passprop = res.passprop; @@ -268,6 +263,7 @@ export const serverWalkMap = ( mitem: mitem as MItem, }, parent_mcomp, + content_scope, }); } } @@ -289,7 +285,10 @@ export const serverWalkMap = ( const js = item.adv?.js; if (typeof js === "string") { - const scope = parseJs(js); + const scope = parseJs(js, { + item, + content_scope: arg.content_scope, + }); if (scope) pcomp.scope[id].s = scope; } } @@ -298,7 +297,10 @@ export const serverWalkMap = ( p.scope[item.id] = { p: arg.parent_ids, n: item.name, s: null }; const js = item.adv?.js; if (typeof js === "string") { - const scope = parseJs(js); + const scope = parseJs(js, { + item, + content_scope: arg.content_scope, + }); if (scope) p.scope[item.id].s = scope; } } @@ -317,6 +319,7 @@ export const serverWalkMap = ( } : undefined, parent_ids: [...arg.parent_ids, item.id], + content_scope: arg.content_scope, }); } }; diff --git a/app/srv/ws/sync/editor/parser/parse-js.ts b/app/srv/ws/sync/editor/parser/parse-js.ts index 6782426e..b549d313 100644 --- a/app/srv/ws/sync/editor/parser/parse-js.ts +++ b/app/srv/ws/sync/editor/parser/parse-js.ts @@ -1,6 +1,30 @@ import recast from "recast"; import babel from "recast/parsers/babel-ts"; -export const parseJs = (code: string) => { +import { IItem, MItem } from "../../../../../web/src/utils/types/item"; +import { EdMeta } from "../../../../../web/src/nova/ed/logic/ed-global"; + +export type ArgParentMComp = EdMeta["parent_mcomp"] & { + id: string; + parent_ids: string[]; + jsx_props: Record< + string, + { + id: string; + mitem: MItem; + parent_mcomp?: ArgParentMComp; + parent_ids: string[]; + } + >; +}; + +export const parseJs = ( + code: string, + arg: { + item: IItem; + content_scope?: Record; + } +) => { + const { item } = arg; const local = { name: "", value: "", index: 0 }; const passprop: Record = {}; const result = {} as { @@ -8,6 +32,7 @@ export const parseJs = (code: string) => { passprop: typeof passprop | undefined; props: Record; }; + try { const ast = recast.parse(code, { parser: babel, @@ -36,12 +61,14 @@ export const parseJs = (code: string) => { attr.value.expression.type === "ObjectExpression" && attr.value.expression.loc ) { - const loc = attr.value.expression.loc as any; const start = attr.value.expression.properties[0].loc?.start; - const end = attr.value.expression.properties[attr.value.expression.properties.length - 1].loc?.end; + const end = + attr.value.expression.properties[ + attr.value.expression.properties.length - 1 + ].loc?.end; - if (typeof start === 'number' && typeof end === 'number') { + if (typeof start === "number" && typeof end === "number") { local.value = code.substring( loc.start.index, loc.end.index @@ -67,7 +94,6 @@ export const parseJs = (code: string) => { value: code.substring(loc.start.index, loc.end.index), index: loc.start.index, }; - } } } diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index 2f26eb16..f6ef262a 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -55,6 +55,7 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { comps: p.comp.list, item_loading: p.ui.tree.item_loading, meta: p.page.meta, + scope: p.page.scope, }, { is_layout: true, @@ -131,6 +132,7 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { item_loading: p.ui.tree.item_loading, meta: p.page.meta, tree: p.page.tree, + scope: p.page.scope, }, { is_layout: false, @@ -160,24 +162,23 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { p.page.building = false; p.render(); p.page.render(); - } }; export const getMRoot = (p: PG) => { - - const root = p.page.doc?.getMap('map').get('root'); + const root = p.page.doc?.getMap("map").get("root"); if (root) { - return p.page.root_id === 'root' + return p.page.root_id === "root" ? root - : p.page.meta[p.page.root_id].mitem?.get('childs')?.get(0); + : p.page.meta[p.page.root_id].mitem?.get("childs")?.get(0); } -} +}; export const getMetaById = (p: PG, id: string) => { if (active.comp_id) { - return p.comp.list[active.comp_id].meta[active.item_id]; + if (p.comp.list[active.comp_id]) + return p.comp.list[active.comp_id].meta[active.item_id]; } else { - return p.page.meta[id] + return p.page.meta[id]; } -} +}; diff --git a/app/web/src/nova/ed/logic/tree/sync-walk.tsx b/app/web/src/nova/ed/logic/tree/sync-walk.tsx index 5c39c95f..b275cc26 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -5,7 +5,7 @@ import { MContent } from "../../../../utils/types/general"; import { IItem, MItem } from "../../../../utils/types/item"; import { FNCompDef, FNComponent } from "../../../../utils/types/meta-fn"; import { MSection } from "../../../../utils/types/section"; -import { EdMeta, PG, active } from "../ed-global"; +import { EdMeta, IScope, PG, active } from "../ed-global"; import { loadCompSnapshot } from "./sync-walk-comp"; import { ensureMItemProps, @@ -66,6 +66,7 @@ export const syncWalkMap = ( comps: PG["comp"]["list"]; meta: Record; component_not_found?: (comp_id: string) => void; + scope?: null | IScope; }, arg: { is_layout: boolean; diff --git a/app/web/src/nova/ed/panel/header/mid/add-item.tsx b/app/web/src/nova/ed/panel/header/mid/add-item.tsx index 405c65b7..15c8eb3a 100644 --- a/app/web/src/nova/ed/panel/header/mid/add-item.tsx +++ b/app/web/src/nova/ed/panel/header/mid/add-item.tsx @@ -1,73 +1,89 @@ import { createId } from "@paralleldrive/cuid2"; -import { useGlobal } from "web-utils"; +import { useGlobal, waitUntil } from "web-utils"; import { MContent } from "../../../../../utils/types/general"; import { IItem } from "../../../../../utils/types/item"; import { EDGlobal, active } from "../../../logic/ed-global"; import { getMetaById } from "../../../logic/tree/build"; import { fillID } from "../../../logic/tree/fill-id"; import { TopBtn } from "../top-btn"; +import { prepSection } from "./prep-section"; export const EdAddItem = () => { const p = useGlobal(EDGlobal, "EDITOR"); - return { - const meta = getMetaById(p, active.item_id); + return ( + { + let meta = getMetaById(p, active.item_id); - if (!meta) { - alert("Please select an item"); - return; - } - - const json = { - id: createId(), - name: `New Item`, - type: "item", - dim: { w: "full", h: "full" }, - childs: [], - adv: { - css: "", - }, - } as IItem; - - let mitem = meta.mitem; - if (mitem) { - if (meta.item.type === 'text' - || (meta.item.type === 'item' && meta.item.component?.id)) { - const parent_id = meta.parent_item.id; - const parent = getMetaById(p, parent_id === 'root' ? meta.item.id : parent_id); - if (!parent) { - alert('Failed to add text!'); - } else { - mitem = parent.mitem; + if (!meta) { + prepSection(p); + await waitUntil(() => getMetaById(p, active.item_id)); + meta = getMetaById(p, active.item_id); } - } + if (!meta) return null; - if (mitem) { - const childs = mitem.get('childs'); - if (childs) { - const map = new Y.Map() as MContent; - syncronize(map as any, fillID(json)); - const childs = mitem.get("childs"); - if (childs) { - childs.push([map]); + const json = { + id: createId(), + name: `New Item`, + type: "item", + dim: { w: "full", h: "full" }, + childs: [], + adv: { + css: "", + }, + } as IItem; + + let mitem = meta.mitem; + if (mitem) { + if ( + meta.item.type === "text" || + (meta.item.type === "item" && meta.item.component?.id) + ) { + const parent_id = meta.parent_item.id; + const parent = getMetaById( + p, + parent_id === "root" ? meta.item.id : parent_id + ); + if (!parent) { + alert("Failed to add text!"); + } else { + mitem = parent.mitem; + } + } + + if (mitem) { + const childs = mitem.get("childs"); + if (childs) { + const map = new Y.Map() as MContent; + syncronize(map as any, fillID(json)); + const childs = mitem.get("childs"); + if (childs) { + childs.push([map]); + } + + active.item_id = map.get("id") || ""; + p.render(); + } } } - } - } - }}> - - - - -} \ No newline at end of file + + + + + ); +}; diff --git a/app/web/src/nova/ed/panel/header/mid/add-section.tsx b/app/web/src/nova/ed/panel/header/mid/add-section.tsx index 9e11219f..6d229dcc 100644 --- a/app/web/src/nova/ed/panel/header/mid/add-section.tsx +++ b/app/web/src/nova/ed/panel/header/mid/add-section.tsx @@ -10,42 +10,49 @@ import { TopBtn } from "../top-btn"; export const EdAddSection = () => { const p = useGlobal(EDGlobal, "EDITOR"); - return { - const meta = getMetaById(p, active.item_id); + return ( + { + const json = { + id: createId(), + name: `New Section`, + type: "section", + dim: { w: "full", h: "full" }, + childs: [], + adv: { + css: "", + }, + } as ISection; - if (!meta) { - alert("Please select an item"); - return; - } + const root = p.page.doc?.getMap("map").get("root"); - const json = { - id: createId(), - name: `New Section`, - type: "section", - dim: { w: "full", h: "full" }, - childs: [], - adv: { - css: "", - }, - } as ISection; - - let mitem = meta.mitem; - if (mitem) { - } - }}> - - - - -} \ No newline at end of file + + + + + ); +}; diff --git a/app/web/src/nova/ed/panel/header/mid/add-text.tsx b/app/web/src/nova/ed/panel/header/mid/add-text.tsx index b26f0fca..01b532e0 100644 --- a/app/web/src/nova/ed/panel/header/mid/add-text.tsx +++ b/app/web/src/nova/ed/panel/header/mid/add-text.tsx @@ -1,76 +1,91 @@ -import { useGlobal } from "web-utils"; -import { TopBtn } from "../top-btn" +import { useGlobal, waitUntil } from "web-utils"; +import { TopBtn } from "../top-btn"; import { EDGlobal, active } from "../../../logic/ed-global"; import { getMetaById } from "../../../logic/tree/build"; import { createId } from "@paralleldrive/cuid2"; import { IText } from "../../../../../utils/types/text"; import { MContent } from "../../../../../utils/types/general"; import { fillID } from "../../../logic/tree/fill-id"; +import { prepSection } from "./prep-section"; export const EdAddText = () => { const p = useGlobal(EDGlobal, "EDITOR"); - return { - const meta = getMetaById(p, active.item_id); + return ( + { + let meta = getMetaById(p, active.item_id); - if (!meta) { - alert("Please select an item"); - return; - } - - const json = { - id: createId(), - name: `New Text`, - type: "text", - dim: { w: "full", h: "full" }, - layout: { align: "center", dir: "col", gap: 0 }, - text: "", - html: "", - adv: { - css: "", - }, - } as IText; - - let mitem = meta.mitem; - if (mitem) { - if (meta.item.type === 'text' - || (meta.item.type === 'item' && meta.item.component?.id)) { - const parent_id = meta.parent_item.id; - const parent = getMetaById(p, parent_id === 'root' ? meta.item.id : parent_id); - if (!parent) { - alert('Failed to add text!'); - } else { - mitem = parent.mitem; + if (!meta) { + prepSection(p); + await waitUntil(() => getMetaById(p, active.item_id)); + meta = getMetaById(p, active.item_id); } - } + if (!meta) return null; - if (mitem) { - const childs = mitem.get('childs'); - if (childs) { - const map = new Y.Map() as MContent; - syncronize(map as any, fillID(json)); - const childs = mitem.get("childs"); - if (childs) { - childs.push([map]); + const json = { + id: createId(), + name: `New Text`, + type: "text", + dim: { w: "full", h: "full" }, + layout: { align: "center", dir: "col", gap: 0 }, + text: "", + html: "", + adv: { + css: "", + }, + } as IText; + + let mitem = meta.mitem; + if (mitem) { + if ( + meta.item.type === "text" || + (meta.item.type === "item" && meta.item.component?.id) + ) { + const parent_id = meta.parent_item.id; + const parent = getMetaById( + p, + parent_id === "root" ? meta.item.id : parent_id + ); + if (!parent) { + alert("Failed to add text!"); + } else { + mitem = parent.mitem; + } + } + + if (mitem) { + const childs = mitem.get("childs"); + if (childs) { + const map = new Y.Map() as MContent; + syncronize(map as any, fillID(json)); + const childs = mitem.get("childs"); + if (childs) { + childs.push([map]); + } + + active.item_id = map.get("id") || ""; + p.render(); + } } } - } - } - - }}> - - - - -} \ No newline at end of file + + + + + ); +}; diff --git a/app/web/src/nova/ed/panel/header/mid/prep-section.tsx b/app/web/src/nova/ed/panel/header/mid/prep-section.tsx new file mode 100644 index 00000000..4d38746b --- /dev/null +++ b/app/web/src/nova/ed/panel/header/mid/prep-section.tsx @@ -0,0 +1,34 @@ +import { createId } from "@paralleldrive/cuid2"; +import { PG, active } from "../../../logic/ed-global"; +import { ISection } from "../../../../../utils/types/section"; +import { MContent } from "../../../../../utils/types/general"; +import { fillID } from "../../../logic/tree/fill-id"; + +export const prepSection = (p: PG) => { + const root = p.page.doc?.getMap("map").get("root"); + + if (root) { + const childs = root.get("childs"); + if (childs) { + if (p.page.tree.length === 0) { + const json = { + id: createId(), + name: `Section`, + type: "section", + dim: { w: "full", h: "full" }, + childs: [], + adv: { + css: "", + }, + } as ISection; + + const map = new Y.Map() as MContent; + syncronize(map as any, fillID(json)); + childs.push([map]); + + active.item_id = json.id; + } + } + } + return; +}; 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 8aaa6454..7e5c1a5a 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 @@ -10,7 +10,7 @@ import { HTML5Backend } from "react-dnd-html5-backend"; 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 { EDGlobal, active } from "../../../logic/ed-global"; import { pagePicker, pagePickerRootItem, @@ -212,6 +212,8 @@ export const EdPopPage = () => { if (isNew) { p.render(); await reloadPagePicker(p); + active.comp_id = ""; + active.item_id = ""; navigate(`/ed/${p.site.id}/${page.id}`); } else { const found = pagePicker.tree.find( diff --git a/app/web/src/nova/ed/panel/popup/script/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope.tsx index a8482d7f..7d95acfd 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope.tsx @@ -11,9 +11,6 @@ export const declareScope = async ( monaco: Monaco ) => { let active_id = active.item_id; - const meta = getMetaById(p, active_id); - const parent = getMetaById(p, meta?.parent_item.id); - let s = deepClone(p.page.scope[active_id]); if (active.comp_id && p.comp.list[active.comp_id]) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/clone.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/clone.tsx index 6f56c83d..d8d95cea 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/clone.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/clone.tsx @@ -6,7 +6,7 @@ import { PG } from "../../../../../logic/ed-global"; import { getMetaById, treeRebuild } from "../../../../../logic/tree/build"; export const edActionClone = (p: PG, item: IContent) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { mitem.doc?.transact(() => { mitem.parent.forEach((e: MContent, idx) => { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/cut.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/cut.tsx index cf5f2142..a4b97d9a 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/cut.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/cut.tsx @@ -13,7 +13,7 @@ export const edActionCut = async (p: PG, item: IContent) => { let str = `prasi-clipboard:` + JSON.stringify(item); navigator.clipboard.writeText(str); - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { mitem.parent.forEach((e, k) => { if (e == mitem) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/detach.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/detach.tsx index b8bbb527..a7aff98e 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/detach.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/detach.tsx @@ -5,7 +5,7 @@ import { getMetaById, treeRebuild } from "../../../../../logic/tree/build"; import { fillID } from "../../../../../../../render/editor/tools/fill-id"; export const edActionDetach = (p: PG, item: IItem) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { const compid = mitem.get("component")?.get("id"); if (compid) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/hide.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/hide.tsx index 35e2386c..a8482031 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/hide.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/hide.tsx @@ -7,7 +7,7 @@ export const edActionHide = ( item: IContent, mode = "toggle" as "toggle" | "switch" ) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { const hidden = mitem.get("hidden"); if (mode === "toggle") { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/new-comp.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/new-comp.tsx index cb47d5a3..a061891e 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/new-comp.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/new-comp.tsx @@ -7,7 +7,7 @@ export const edActionNewComp = ( item: IItem, e: React.MouseEvent ) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { p.ui.popup.comp_group = { mouse_event: e, diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/paste.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/paste.tsx index 7605edc7..592fdb85 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/paste.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/paste.tsx @@ -6,7 +6,7 @@ import { PG, active } from "../../../../../logic/ed-global"; import { getMetaById, treeRebuild } from "../../../../../logic/tree/build"; export const edActionPaste = async (p: PG, item: IContent) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { const res = await navigator.clipboard.readText(); if (typeof res === "string" && res.startsWith("prasi-clipboard:")) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/unwrap.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/unwrap.tsx index e48b068d..2496939c 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/unwrap.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/unwrap.tsx @@ -5,7 +5,7 @@ import { PG } from "../../../../../logic/ed-global"; import { getMetaById, treeRebuild } from "../../../../../logic/tree/build"; export const edActionUnwrap = (p: PG, item: IItem) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { mitem.parent.forEach((e: MContent, idx) => { if (e.get("id") === mitem.get("id")) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/action/wrap.tsx b/app/web/src/nova/ed/panel/tree/node/item/action/wrap.tsx index 6dfc21a5..bffda5eb 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action/wrap.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action/wrap.tsx @@ -7,7 +7,7 @@ import { syncronize } from "y-pojo"; import { getMetaById, treeRebuild } from "../../../../../logic/tree/build"; export const edActionWrap = (p: PG, item: IText | IItem) => { - const mitem = getMetaById(p, item.id).mitem; + const mitem = getMetaById(p, item.id)?.mitem; if (mitem) { mitem.parent.forEach((e: MContent, idx) => { if (e.get("id") === mitem.get("id")) { diff --git a/app/web/src/nova/ed/panel/tree/node/item/indent-hook.ts b/app/web/src/nova/ed/panel/tree/node/item/indent-hook.ts index a5586c14..9a1ab624 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/indent-hook.ts +++ b/app/web/src/nova/ed/panel/tree/node/item/indent-hook.ts @@ -16,15 +16,17 @@ export const expandTreeHook = ( const open = JSON.parse(localStorage.getItem("prasi-tree-open") || "{}"); p.ui.tree.open = open; - let shouldOpen = new Set(open[active.comp_id || p.page.cur.id] || []); + let shouldOpen = new Set( + open[active.comp_id || p.page.cur.id] || [] + ); const cur = getMetaById(p, active.item_id); if (cur && cur.parent_item) { - const id = cur.parent_item.mitem?.get('id'); + const id = cur.parent_item.mitem?.get("id"); if (id) { - let meta: EdMeta | null = getMetaById(p, id); + let meta: EdMeta | undefined = getMetaById(p, id); while (meta) { - const id = cur.parent_item.mitem?.get('id'); + const id = cur.parent_item.mitem?.get("id"); if (id && !shouldOpen.has(id)) { shouldOpen.add(id); meta = getMetaById(p, id); @@ -36,9 +38,11 @@ export const expandTreeHook = ( } if (active.comp_id) { - const root = p.comp.list[active.comp_id].tree.find(e => e.parent === 'root'); - if (root && typeof root.id === 'string') - shouldOpen.add(root.id) + const pcomp = p.comp.list[active.comp_id]; + if (pcomp) { + const root = pcomp.tree.find((e) => e.parent === "root"); + if (root && typeof root.id === "string") shouldOpen.add(root.id); + } } if (shouldOpen.size > 0 && local.tree) { @@ -46,7 +50,7 @@ export const expandTreeHook = ( local.render(); if (active.item_id) { const meta = getMetaById(p, active.item_id); - if (meta && meta.item.type !== 'text') { + if (meta && meta.item.type !== "text") { setTimeout(() => { const el = document.getElementsByClassName(active.item_id); if (el.length > 0) { diff --git a/app/web/src/nova/ed/panel/tree/node/on-drop.tsx b/app/web/src/nova/ed/panel/tree/node/on-drop.tsx index 0ac45840..1212bbef 100644 --- a/app/web/src/nova/ed/panel/tree/node/on-drop.tsx +++ b/app/web/src/nova/ed/panel/tree/node/on-drop.tsx @@ -7,7 +7,7 @@ import { getMetaById } from "../../../logic/tree/build"; export const nodeOnDrop: ( tree: NodeModel[], options: DropOptions -) => void = () => { }; +) => void = () => {}; export const canDrop = (p: PG, arg: DropOptions) => { const { dragSource, dragSourceId, dropTargetId, dropTarget } = arg; @@ -31,7 +31,7 @@ export const canDrop = (p: PG, arg: DropOptions) => { const to = dropTarget.data.item.type; if (from === "section" || from === "item") { - let parent = dropTarget.data; + let parent: EdMeta | undefined = dropTarget.data; while (parent) { if (parent.item.id === dragSource.data.item.id) { return false;