diff --git a/app/web/src/nova/ed/panel/popup/script/monaco.tsx b/app/web/src/nova/ed/panel/popup/script/monaco.tsx index 2d78b497..77ffd034 100644 --- a/app/web/src/nova/ed/panel/popup/script/monaco.tsx +++ b/app/web/src/nova/ed/panel/popup/script/monaco.tsx @@ -21,6 +21,8 @@ const scriptEdit = { timeout: null as any, }; +const IMPORT_SEPARATOR = "//SCRIPT//"; + const encode = new TextEncoder(); export type MonacoEditor = Parameters[0]; export const EdScriptMonaco: FC<{}> = () => { @@ -34,11 +36,12 @@ export const EdScriptMonaco: FC<{}> = () => { historyOpen: false, mode: "", imports: "", + active_id: "", idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"), }); const Editor = jscript.editor; - if (!Editor) return null; + if (!Editor) return ; let meta: IMeta | null = p.page.meta[active.item_id]; if (active.comp_id) { @@ -62,9 +65,13 @@ export const EdScriptMonaco: FC<{}> = () => { if (monaco && editor) { const type = p.ui.popup.script.type; - if (local.mode !== p.ui.popup.script.mode) { + if ( + local.mode !== p.ui.popup.script.mode || + local.active_id !== active.item_id + ) { local.init = false; local.mode = p.ui.popup.script.mode; + local.active_id = active.item_id; } if (!local.init) { @@ -102,69 +109,86 @@ export const EdScriptMonaco: FC<{}> = () => { { types: {}, values: {} } ); if (meta) { - let end_hide = 0; - if (type === "prop-master") { - const nmodel = monaco.editor.createModel( - val, - "typescript", - monaco.Uri.parse("file:///active.tsx") - ); - editor.setModel(nmodel); - } else { - const nmodel = monaco.editor.createModel( - val, - "typescript", - monaco.Uri.parse("file:///active.tsx") - ); - editor.setModel(nmodel); - const { exports, imports } = declareScope(p, meta, monaco); - console.log( - Object.keys(imports).map((e) => [ - p.page.meta[e].item.name, - exports[e], - ]) - ); - // const added = new Set(); - // const im = imports[active.item_id]; - // const im_flat = {} as Record; - // for (const [var_name, item] of Object.entries(im)) { - // const file_name = `${item.id}_${item.type}.tsx`; - // if (!im_flat[file_name]) im_flat[file_name] = []; - // im_flat[file_name].push(var_name); - // } - // console.log(im_flat, exports); - // if (active_src) { - // const end_hide = - // active_src.split("//!!start")[0].split("\n").length + 1; - // const range = new monaco.Range(1, 0, end_hide, 0); - // (editor as any).setHiddenAreas([range]); - // } - } - editor.trigger("fold", "editor.foldAllMarkerRegions", {}); - await jsMount(editor, monaco, p); + switch (type) { + case "prop-master": + { + const nmodel = monaco.editor.createModel( + val, + "typescript", + monaco.Uri.parse("file:///active.tsx") + ); + editor.setModel(nmodel); + } + break; + case "prop-instance": + { + const nmodel = monaco.editor.createModel( + val, + "typescript", + monaco.Uri.parse("file:///active.tsx") + ); + editor.setModel(nmodel); + const constrainedInstance = constrainedEditor(monaco); + constrainedInstance.initializeIn(editor); + const model = editor.getModel(); + constrainedInstance.removeRestrictionsIn(model); + const frange = model?.getFullModelRange(); + if (frange) { + // const ranges = [ + // { + // range: [ + // end_hide + 1, + // `export const ${p.ui.popup.script.prop_name} = ` + // .length, + // frange.getEndPosition().lineNumber, + // frange.getEndPosition().column, + // ], + // allowMultiline: true, + // }, + // ]; + // constrainedInstance.addRestrictionsTo(model, ranges); + } + } + break; + case "item": + { + const { exports, imports } = declareScope(p, meta, monaco); + const im = imports[active.item_id]; + const im_src = []; - if (type === "prop-instance") { - const constrainedInstance = constrainedEditor(monaco); - constrainedInstance.initializeIn(editor); - const model = editor.getModel(); - constrainedInstance.removeRestrictionsIn(model); - const frange = model?.getFullModelRange(); - if (frange) { - const ranges = [ - { - range: [ - end_hide + 1, - `export const ${p.ui.popup.script.prop_name} = `.length, - frange.getEndPosition().lineNumber, - frange.getEndPosition().column, - ], - allowMultiline: true, - }, - ]; - constrainedInstance.addRestrictionsTo(model, ranges); - } + if (im) { + for (const [var_name, item] of Object.entries(im)) { + im_src.push( + `import { ${var_name} } from "./${item.id}_${var_name}_${item.type}";` + ); + } + } + for (const [k, v] of Object.entries(exports)) { + addScope(p, monaco, `file:///${k}`, v); + } + let active_src = + im_src.length > 0 + ? `${im_src.join("\n")}\n${IMPORT_SEPARATOR}\n${val}` + : val; + const model = monaco.editor.createModel( + active_src, + "typescript", + monaco.Uri.parse("file:///active.tsx") + ); + editor.setModel(model); + editor.trigger("fold", "editor.foldAllMarkerRegions", {}); + if (active_src) { + const end_hide = active_src + .split(IMPORT_SEPARATOR)[0] + .split("\n").length; + const range = new monaco.Range(1, 1, end_hide, 1); + (editor as any).setHiddenAreas([range]); + } + } + break; } } + await jsMount(editor, monaco, p); } else { const model = monaco.editor.createModel( val, @@ -184,7 +208,7 @@ export const EdScriptMonaco: FC<{}> = () => { })(); }, [active.item_id, local.monaco, local.editor, p.ui.popup.script.mode]); - if (!meta) return null; + if (!meta) return ; const item = meta.item; const adv = meta.mitem?.get("adv")?.toJSON() || {}; @@ -201,8 +225,8 @@ export const EdScriptMonaco: FC<{}> = () => { ?.getValue() .replace(/\{\s*children\s*\}/gi, newval); - if (curval.includes("/** IMPORT MODULE **/")) { - curval = curval.split("/** IMPORT MODULE **/\n").pop() || ""; + if (curval.includes(IMPORT_SEPARATOR)) { + curval = curval.split(IMPORT_SEPARATOR + "\n").pop() || ""; } const text = trim( @@ -215,7 +239,7 @@ export const EdScriptMonaco: FC<{}> = () => { let final_src = text; if (local.imports) { - final_src = `${local.imports}\n/** IMPORT MODULE **/\n${text}`; + final_src = `${local.imports}\n${IMPORT_SEPARATOR}\n${text}`; } local.editor.executeEdits(null, [ { @@ -263,6 +287,7 @@ export const EdScriptMonaco: FC<{}> = () => { { css: "scss", js: "typescript", html: "html" }[p.ui.popup.script.mode] } onChange={(value) => { + return; const stype = p.ui.popup.script.type; if ((value || "").includes("/** SOURCE START **/")) { const valparts = (value || "").split("/** SOURCE START **/\n"); diff --git a/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx b/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx index 9964f49b..b33f7bd3 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx @@ -37,19 +37,6 @@ export const extractExport = (p: PG, m: IMeta) => { } } - if (m.script?.scope) { - for (const [k, v] of Object.entries(m.script.scope)) { - if (k === "key") continue; - result[k] = { - type: "scope", - id: m.item.id, - start: 0, - end: 0, - val: "null as any", - }; - } - } - if (script?.props) { for (const [k, v] of Object.entries(script.props)) { result[k] = { diff --git a/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx index 9656eccb..8c280c6c 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx @@ -46,29 +46,34 @@ export const declareScope = (p: PG, meta: IMeta, monaco: Monaco) => { let prev_m = null as null | IMeta; for (const m of cur_path) { if (!exports[m.item.id]) { - const export_types = { - local: [] as string[], - prop: [] as string[], - passprop: [] as string[], - scope: [] as string[], - }; extract_exports[m.item.id] = extractExport(p, m); for (const [k, v] of Object.entries(extract_exports[m.item.id])) { + let src = ""; if (v.type !== "local") { - export_types[v.type].push(`export const ${k} = ${v.val};`); + src = `export const ${k} = ${v.val};`; } else { - export_types[v.type].push(`\ - const ${k}__local = ${v.val}; - export const ${k}: typeof ${k}__local & { render: ()=>void } = ${k}__local as any;`); + src = `\ + const ${k}__local = ${v.val}; + export const ${k}: typeof ${k}__local & { render: ()=>void } = ${k}__local as any;`; } + exports[`${m.item.id}_${k}_${v.type}.tsx`] = src; } - for (const [k, v] of Object.entries(export_types)) { - if (v.length > 0) { - exports[`${m.item.id}_${k}.tsx`] = v.join("\n"); + } + + if ( + m.item.id === active.item_id && + m.item.component?.id === active.comp_id && + active.comp_id + ) { + for (const [k, v] of Object.entries(extract_exports[m.item.id])) { + if (!imports[m.item.id]) imports[m.item.id] = {}; + if (v.type === "prop") { + imports[m.item.id][k] = v; } } } + if (prev_m && extract_exports[prev_m.item.id]) { imports[m.item.id] = {}; if (imports[prev_m.item.id]) { diff --git a/app/web/src/nova/ed/panel/popup/script/workbench.tsx b/app/web/src/nova/ed/panel/popup/script/workbench.tsx index 5d71f94e..2113a41d 100644 --- a/app/web/src/nova/ed/panel/popup/script/workbench.tsx +++ b/app/web/src/nova/ed/panel/popup/script/workbench.tsx @@ -1,11 +1,27 @@ -import { useGlobal } from "web-utils"; +import { useGlobal, useLocal } from "web-utils"; import { IItem } from "../../../../../utils/types/item"; import { EDGlobal, active } from "../../../logic/ed-global"; import { EdScriptMonaco } from "./monaco"; import { EdScriptSnippet } from "./snippet"; +import { useEffect } from "react"; +import { Loading } from "../../../../../utils/ui/loading"; export const EdScriptWorkbench = () => { const p = useGlobal(EDGlobal, "EDITOR"); + const local = useLocal({ active_id: "" }); + + useEffect(() => { + if (!local.active_id) { + local.active_id = active.item_id; + local.render(); + } else { + setTimeout(() => { + local.active_id = active.item_id; + local.render(); + }, 200); + } + }, [active.item_id]); + return (
@@ -52,7 +68,11 @@ export const EdScriptWorkbench = () => { )}
- + {local.active_id === active.item_id ? ( + + ) : ( + + )}
diff --git a/app/web/src/nova/ed/panel/tree/node/item/action.tsx b/app/web/src/nova/ed/panel/tree/node/item/action.tsx index 0d67285e..1bccb295 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action.tsx @@ -3,6 +3,7 @@ import { useGlobal } from "web-utils"; import { Tooltip } from "../../../../../../utils/ui/tooltip"; import { EDGlobal, IMeta, active } from "../../../../logic/ed-global"; import { getMetaById } from "../../../../logic/active/get-meta"; +import { treeRebuild } from "../../../../logic/tree/build"; export const EdTreeAction = ({ node, @@ -139,6 +140,7 @@ export const EdTreeAction = ({ active.item_id = active.instance.item_id || ""; active.instance.comp_id = ""; active.instance.item_id = ""; + treeRebuild(p); p.render(); } }} diff --git a/app/web/src/utils/script/mount.tsx b/app/web/src/utils/script/mount.tsx index 9206e874..dd720f8b 100644 --- a/app/web/src/utils/script/mount.tsx +++ b/app/web/src/utils/script/mount.tsx @@ -53,15 +53,42 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => { if (p) { monaco.editor.registerEditorOpener({ - openCodeEditor(source, r, selectionOrPosition) { + openCodeEditor(source, r, _sel) { if (p) { - p.ui.popup.script.mode === "js"; - if (r.scheme === "file" && r.path) { const args = r.path.split("_"); - if (args.length === 4) { - const { cur, id, meta } = extractLoc(args, p); - console.log(cur, id, meta.item.name); + if (args.length === 3) { + const loc = extractLoc(args, p); + console.log(loc.meta); + if (loc.meta) { + if (loc.meta.item.component?.id && loc.meta.instances) { + active.comp_id = loc.meta.item.component?.id; + active.instance = { + comp_id: loc.meta.item.component?.id, + item_id: loc.meta.item.id, + }; + const item_id = p.comp.list[active.comp_id].tree.find( + (e) => e.parent === "root" + )?.id; + if (item_id) { + active.item_id = item_id as string; + } + } else if ( + loc.meta.parent?.instance_id && + loc.meta.parent.comp_id && + loc.meta.item.originalId + ) { + active.comp_id = loc.meta.parent.comp_id; + active.instance = { + comp_id: active.comp_id, + item_id: loc.meta.parent.instance_id, + }; + active.item_id = loc.meta.item.originalId; + } else { + active.item_id = loc.meta.item.id; + } + p.render(); + } } } } @@ -182,17 +209,19 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => { }; export const extractLoc = (args: string[], p: PG) => { - const [_cur, id, type, _varname] = args; - const cur = _cur.substring(1); - const varname = _varname.substring(0, _varname.length - ".tsx".length); - + const [_id, var_name, _type] = args; + const id = _id.substring(1); + const type = _type.replace(".tsx", ""); let meta = p.page.meta[id]; - if (cur !== "page") { - const comp = p.comp.list[cur]; - if (comp) { - meta = comp.meta[id]; - } + + if (active.comp_id) { + meta = p.comp.list[active.comp_id].meta[id]; } - return { cur, varname, type, id, meta }; + return { + id, + var_name, + type, + meta, + }; };