wip fix tree

This commit is contained in:
Rizky 2023-11-25 11:43:31 +07:00
parent d92a722bb9
commit 462b8e19f6
10 changed files with 153 additions and 127 deletions

View File

@ -112,6 +112,7 @@ export const serverWalkMap = (
const item = {} as unknown as IItem; const item = {} as unknown as IItem;
mapItem(mitem, item); mapItem(mitem, item);
if (override_id) { if (override_id) {
item.originalId = item.id;
item.id = override_id; item.id = override_id;
} }
@ -167,6 +168,7 @@ export const serverWalkMap = (
ref_ids = {}; ref_ids = {};
} }
const original_id = item.id; const original_id = item.id;
mapItem(mcomp, item); mapItem(mcomp, item);
item.id = original_id; item.id = original_id;
@ -208,10 +210,11 @@ export const serverWalkMap = (
} }
if (scope) pcomp.scope[item.id].s = scope; if (scope) pcomp.scope[item.id].s = scope;
if (!parent_mcomp) { if (!parent_mcomp) {
p.scope[item.id] = { p.scope[item.id] = {
p: arg.parent_ids, p: arg.parent_ids,
n: item.name, n: item.name,
s: null, s: null,
c: item.component?.id, c: item.component?.id,
}; };
@ -241,12 +244,17 @@ export const serverWalkMap = (
} }
if (arg.parent_mcomp && !arg.is_prop) { if (arg.parent_mcomp && !arg.is_prop) {
let id = item.originalId || item.id;
const pcomp = p.scope_comps[arg.parent_mcomp.id]; const pcomp = p.scope_comps[arg.parent_mcomp.id];
pcomp.scope[item.id] = { p: arg.parent_ids, n: item.name, s: null }; pcomp.scope[id] = {
p: arg.parent_ids,
n: item.name,
s: null,
};
const js = item.adv?.js; const js = item.adv?.js;
if (typeof js === "string") { if (typeof js === "string") {
const scope = parseJs(js); const scope = parseJs(js);
if (scope) pcomp.scope[item.id].s = scope; if (scope) pcomp.scope[id].s = scope;
} }
} else { } else {
if (!(item_comp && item_comp.id)) { if (!(item_comp && item_comp.id)) {

View File

@ -1,80 +1,86 @@
import recast from "recast"; import recast from "recast";
import babel from "recast/parsers/babel-ts"; import babel from "recast/parsers/babel-ts";
export const parseJs = (code: string) => { export const parseJs = (code: string) => {
const ast = recast.parse(code, {
parser: babel,
});
const local = { name: "", value: "", index: 0 }; const local = { name: "", value: "", index: 0 };
const passprop: Record<string, { value: string; index: number }> = {}; const passprop: Record<string, { value: string; index: number }> = {};
recast.visit(ast, {
visitJSXOpeningElement({ node }) {
if (node.name.type === "JSXIdentifier" && node.attributes) {
if (node.name.name === "Local") {
for (const attr of node.attributes) {
if (
attr.type === "JSXAttribute" &&
attr.name.type === "JSXIdentifier"
) {
if (
attr.name.name === "name" &&
attr.value?.type === "StringLiteral"
) {
local.name = attr.value.value;
}
if (
attr.name.name === "value" &&
attr.value &&
attr.value.type === "JSXExpressionContainer" &&
attr.value.expression.type === "ObjectExpression" &&
attr.value.expression.loc
) {
const loc = attr.value.expression.loc as any;
local.value = code.substring(loc.start.index, loc.end.index);
local.index = loc.start.index;
}
}
}
} else if (node.name.name === "PassProp") {
for (const attr of node.attributes) {
if (
attr.type === "JSXAttribute" &&
attr.name.type === "JSXIdentifier"
) {
if (
attr.name.name === "value" &&
attr.value &&
attr.value.type === "JSXExpressionContainer" &&
attr.value.expression.loc
) {
const loc = attr.value.expression.loc as any;
passprop[attr.name.name] = {
value: code.substring(loc.start.index, loc.end.index),
index: loc.start.index,
};
}
}
}
}
}
return true;
},
});
const result = {} as { const result = {} as {
local: typeof local | undefined; local: typeof local | undefined;
passprop: typeof passprop | undefined; passprop: typeof passprop | undefined;
props: Record<string, { name: string; value: string }>; props: Record<string, { name: string; value: string }>;
}; };
if (local.name) { try {
result.local = local; const ast = recast.parse(code, {
} parser: babel,
if (Object.keys(passprop).length > 0) { });
result.passprop = passprop;
}
if (Object.keys(result).length > 0) { recast.visit(ast, {
return result; visitJSXOpeningElement({ node }) {
if (node.name.type === "JSXIdentifier" && node.attributes) {
if (node.name.name === "Local") {
for (const attr of node.attributes) {
if (
attr.type === "JSXAttribute" &&
attr.name.type === "JSXIdentifier"
) {
if (
attr.name.name === "name" &&
attr.value?.type === "StringLiteral"
) {
local.name = attr.value.value;
}
if (
attr.name.name === "value" &&
attr.value &&
attr.value.type === "JSXExpressionContainer" &&
attr.value.expression.type === "ObjectExpression" &&
attr.value.expression.loc
) {
const loc = attr.value.expression.loc as any;
local.value = code.substring(loc.start.index, loc.end.index);
local.index = loc.start.index;
}
}
}
} else if (node.name.name === "PassProp") {
for (const attr of node.attributes) {
if (
attr.type === "JSXAttribute" &&
attr.name.type === "JSXIdentifier"
) {
if (
attr.name.name === "value" &&
attr.value &&
attr.value.type === "JSXExpressionContainer" &&
attr.value.expression.loc
) {
const loc = attr.value.expression.loc as any;
passprop[attr.name.name] = {
value: code.substring(loc.start.index, loc.end.index),
index: loc.start.index,
};
}
}
}
}
}
return true;
},
});
if (local.name) {
result.local = local;
}
if (Object.keys(passprop).length > 0) {
result.passprop = passprop;
}
if (Object.keys(result).length > 0) {
return result;
}
} catch (e) {
// console.error(code, "\n", e);
} }
return result;
}; };

View File

@ -177,6 +177,7 @@ export const EDGlobal = {
comp: { comp: {
doc: null as null | DComp, doc: null as null | DComp,
item: null as null | IItem, item: null as null | IItem,
tree: [] as NodeModel<EdMeta>[],
list: {} as Record< list: {} as Record<
string, string,
{ {

View File

@ -38,7 +38,6 @@ export const edInitSync = (p: PG) => {
navigate(`/ed/`); navigate(`/ed/`);
} }
}); });
console.log("site not equal");
return false; return false;
} }
@ -55,7 +54,6 @@ export const edInitSync = (p: PG) => {
.then((e) => { .then((e) => {
if (e) navigate(`/ed/${params.site_id}/${e.id}`); if (e) navigate(`/ed/${params.site_id}/${e.id}`);
}); });
console.log("page not found");
return false; return false;
} }
} }

View File

@ -17,7 +17,6 @@ export const declareScope = async (
} }
if (!s) return; if (!s) return;
s.p.push(active_id); s.p.push(active_id);
monaco.editor.getModels().forEach((model) => { monaco.editor.getModels().forEach((model) => {
@ -29,6 +28,7 @@ export const declareScope = async (
const existing: Record<string, IEachArgScope> = {}; const existing: Record<string, IEachArgScope> = {};
spreadScope(p, s, (arg) => { spreadScope(p, s, (arg) => {
const { name } = arg; const { name } = arg;
const e = existing[name]; const e = existing[name];
if (e && e.s.s) { if (e && e.s.s) {
if (e.type === "local") { if (e.type === "local") {
@ -132,6 +132,7 @@ const spreadScope = (
item = layout.scope[parent_id]; item = layout.scope[parent_id];
} }
} }
if (!item) { if (!item) {
if (comp_id) { if (comp_id) {
item = p.comp.list[comp_id].scope[parent_id]; item = p.comp.list[comp_id].scope[parent_id];

View File

@ -71,21 +71,8 @@ export const EdPopScript = () => {
` `
)} )}
> >
{(!jscript.editor || !jscript.build) && ( {!jscript.editor && <Loading note={"js-editor"} backdrop={false} />}
<> {jscript.editor && <ScriptWorkbench />}
{!jscript.editor && !jscript.build && (
<Loading note={"js-code"} backdrop={false} />
)}
{!jscript.editor && jscript.build && (
<Loading note={"js-editor"} backdrop={false} />
)}
{!jscript.build && jscript.editor && (
<Loading note={"js-build"} backdrop={false} />
)}
</>
)}
{jscript.editor && jscript.build && <ScriptWorkbench />}
</div> </div>
</div> </div>
</Modal> </Modal>

View File

@ -7,10 +7,7 @@ import { EDGlobal } from "../../../logic/ed-global";
import { EdFormSite } from "./site-form"; import { EdFormSite } from "./site-form";
import { EdSiteHead } from "./site-head"; import { EdSiteHead } from "./site-head";
import { EdSiteTree, SiteGroupItem } from "./site-tree"; import { EdSiteTree, SiteGroupItem } from "./site-tree";
import uFuzzy from "@leeoniya/ufuzzy";
import { fuzzy } from "../../../../../utils/ui/fuzzy"; import { fuzzy } from "../../../../../utils/ui/fuzzy";
const uf = new uFuzzy({});
const conf = { group: null as any }; const conf = { group: null as any };

View File

@ -38,7 +38,7 @@ export const EdMonacoWrap = ({
}) => { }) => {
const local = useLocal({}); const local = useLocal({});
if (jscript.pending && (!jscript.editor || !jscript.build)) { if (jscript.pending && !jscript.editor) {
jscript.pending.then(() => { jscript.pending.then(() => {
local.render(); local.render();
}); });
@ -99,7 +99,7 @@ export const EdMonacoWrap = ({
{header} {header}
<div className="relative flex-1"> <div className="relative flex-1">
<div className="absolute inset-0"> <div className="absolute inset-0">
{!jscript.editor || !jscript.build ? ( {!jscript.editor ? (
<Loading note="script-cst" backdrop={false} /> <Loading note="script-cst" backdrop={false} />
) : ( ) : (
children(jscript.editor) children(jscript.editor)

View File

@ -16,21 +16,25 @@ import { doTreeSearch } from "./search";
export const EdTreeBody = () => { export const EdTreeBody = () => {
const p = useGlobal(EDGlobal, "EDITOR"); const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ tree: null as TreeMethods | null }); const local = useLocal({ tree: null as TreeMethods | null, comp_id: "" });
const TypedTree = DNDTree<EdMeta>; const TypedTree = DNDTree<EdMeta>;
indentHook(p, local); indentHook(p, local);
if (active.comp_id && local.comp_id !== active.comp_id) {
local.comp_id = active.comp_id;
const ref = p.comp.list[active.comp_id];
if (ref) {
p.comp.tree = ref.tree;
}
}
let tree: NodeModel<EdMeta>[] = []; let tree: NodeModel<EdMeta>[] = [];
if (p.ui.tree.search) { if (p.ui.tree.search) {
tree = doTreeSearch(p); tree = doTreeSearch(p);
} else { } else {
if ( if (!!active.comp_id) {
active.comp_id && tree = p.comp.tree;
p.comp.list[active.comp_id] &&
p.comp.list[active.comp_id].tree
) {
tree = p.comp.list[active.comp_id].tree;
} else { } else {
tree = p.page.tree; tree = p.page.tree;
} }
@ -39,7 +43,7 @@ export const EdTreeBody = () => {
if (tree.length === 0) if (tree.length === 0)
return ( return (
<div className="flex py-[100px] select-none justify-center flex-1"> <div className="flex py-[100px] select-none justify-center flex-1">
<div className="flex flex-col"> <div className="flex flex-col items-center">
<img <img
draggable={false} draggable={false}
src="/img/empty.png" src="/img/empty.png"
@ -47,7 +51,26 @@ export const EdTreeBody = () => {
width: 50px; width: 50px;
`} `}
/> />
<div className="mt-[20px]">No Item</div> <div className="mt-[20px] text-[12px]"> No Item </div>
{active.comp_id && (
<div
className="flex items-center border border-slate-500 bg-white rounded-sm text-[10px] px-[2px] cursor-pointer hover:bg-purple-100 hover:border-purple-600 mt-5"
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
if (active.comp_id) {
active.comp_id = active.instance.comp_id || "";
active.item_id = active.instance.item_id || "";
active.instance.comp_id = "";
active.instance.item_id = "";
p.render();
}
}}
>
Close Component
</div>
)}
</div> </div>
</div> </div>
); );

View File

@ -30,7 +30,7 @@ export const jscript = {
estree: null as null | typeof estree, estree: null as null | typeof estree,
ts: null as null | typeof ts, ts: null as null | typeof ts,
}, },
async init(render: () => void) { async init(render: () => void, enabled?: { esbuild: boolean }) {
if (this.pending) { if (this.pending) {
await this.pending; await this.pending;
render(); render();
@ -39,9 +39,12 @@ export const jscript = {
this.pending = new Promise<void>(async (resolve) => { this.pending = new Promise<void>(async (resolve) => {
this.events.pendingDone = resolve; this.events.pendingDone = resolve;
const { sendIPC } = await import("./esbuild/ipc"); let sendIPC = null as any;
await initJS(); if (enabled?.esbuild !== false) {
this.events.esbuildLoaded(); sendIPC = (await import("./esbuild/ipc")).sendIPC;
await initJS();
this.events.esbuildLoaded();
}
this.prettier.standalone = ( this.prettier.standalone = (
await import("prettier/standalone") await import("prettier/standalone")
@ -55,29 +58,31 @@ export const jscript = {
e.loader.config({ paths: { vs: "/min/vs" } }); e.loader.config({ paths: { vs: "/min/vs" } });
this.events.editorLoaded(); this.events.editorLoaded();
this.build = async (entry, src, files, verbose?: boolean) => { if (enabled?.esbuild !== false) {
const options: BuildOptions = { this.build = async (entry, src, files, verbose?: boolean) => {
entryPoints: [entry], const options: BuildOptions = {
jsx: "transform", entryPoints: [entry],
bundle: true, jsx: "transform",
format: "cjs", bundle: true,
minify: true, format: "cjs",
minify: true,
};
const res = await sendIPC({
command_: "build",
input_: { ...files, [entry]: src },
options_: options,
});
if (verbose && res.stderr_) {
console.log(res.stderr_);
}
if (res.outputFiles_) return res.outputFiles_[0].text;
return "";
}; };
const res = await sendIPC({
command_: "build",
input_: { ...files, [entry]: src },
options_: options,
});
if (verbose && res.stderr_) { await this.build("el.tsx", `return ""`);
console.log(res.stderr_); }
}
if (res.outputFiles_) return res.outputFiles_[0].text;
return "";
};
await this.build("el.tsx", `return ""`);
render(); render();
}); });
} }