This commit is contained in:
rizrmd 2024-05-19 05:27:09 +07:00
parent df15447ebc
commit 6c60efe0e3
16 changed files with 374 additions and 92 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,9 +29,9 @@ export const edUndoManager = async (p: PG) => {
!evt.shiftKey !evt.shiftKey
) { ) {
if (active.comp_id) { if (active.comp_id) {
p.sync.yjs.um("comp", "redo", active.comp_id); p.sync?.yjs.um("comp", "redo", active.comp_id);
} else { } else {
p.sync.yjs.um("page", "redo", p.page.cur.id); p.sync?.yjs.um("page", "redo", p.page.cur.id);
} }
return; return;
} }
@ -42,9 +42,9 @@ export const edUndoManager = async (p: PG) => {
evt.shiftKey evt.shiftKey
) { ) {
if (active.comp_id) { if (active.comp_id) {
p.sync.yjs.um("comp", "redo", active.comp_id); p.sync?.yjs.um("comp", "redo", active.comp_id);
} else { } else {
p.sync.yjs.um("page", "redo", p.page.cur.id); p.sync?.yjs.um("page", "redo", p.page.cur.id);
} }
return; return;
} }
@ -55,9 +55,9 @@ export const edUndoManager = async (p: PG) => {
!evt.shiftKey !evt.shiftKey
) { ) {
if (active.comp_id) { if (active.comp_id) {
p.sync.yjs.um("comp", "undo", active.comp_id); p.sync?.yjs.um("comp", "undo", active.comp_id);
} else { } else {
p.sync.yjs.um("page", "undo", p.page.cur.id); p.sync?.yjs.um("page", "undo", p.page.cur.id);
} }
} }
} }

View File

@ -5,6 +5,7 @@ import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
import { EDGlobal, IMeta, active } from "../../../logic/ed-global"; import { EDGlobal, IMeta, active } from "../../../logic/ed-global";
import { treeRebuild } from "../../../logic/tree/build"; import { treeRebuild } from "../../../logic/tree/build";
import { EdPropLabel } from "./prop-label"; import { EdPropLabel } from "./prop-label";
import { devItem } from "../../../../vi/render/script/dev-item";
export const w = window as any; export const w = window as any;
@ -55,6 +56,7 @@ export const EdPropInstanceButton: FC<{
} }
} }
if (meta.mitem) arg._item = devItem(p.page.meta, meta.mitem, p.page.cur.id);
const btn_fn = new Function( const btn_fn = new Function(
...Object.keys(arg), ...Object.keys(arg),
`return ${cprop.valueBuilt}` `return ${cprop.valueBuilt}`
@ -79,28 +81,7 @@ export const EdPropInstanceButton: FC<{
key={idx} key={idx}
className="flex flex-1 items-stretch bg-white border hover:border-blue-500 hover:bg-blue-50 rounded-sm select-none cursor-pointer" className="flex flex-1 items-stretch bg-white border hover:border-blue-500 hover:bg-blue-50 rounded-sm select-none cursor-pointer"
onClick={() => { onClick={() => {
e.onClick(async (arg: Record<string, FNCompDef>) => { e.onClick(async () => {}, props);
const src = {} as Record<string, string>;
Object.entries(arg).map(([k, v]) => {
src[k] = v.value;
});
const result = await _api.code_build(src);
for (const [k, v] of Object.entries(result)) {
arg[k].valueBuilt = v;
}
const parent = mprop.parent as TypedMap<
Record<string, FMCompDef>
>;
mprop.doc?.transact(() => {
for (const [k, v] of Object.entries(arg)) {
const map = new Y.Map();
syncronize(map, v);
parent.set(k, map as any);
}
});
await treeRebuild(p);
p.render();
}, props);
}} }}
> >
<div className="flex items-center"> <div className="flex items-center">

View File

@ -1,10 +1,249 @@
import { IItem } from "../../../../utils/types/item"; import { IItem, MItem } from "../../../../utils/types/item";
import { FNCompDef } from "../../../../utils/types/meta-fn";
import { IMeta } from "../../utils/types"; import { IMeta } from "../../utils/types";
type PrasiEdit = { const w = window as unknown as {
update: (fn: () => Promise<void> | void) => void; prasiEdit: Record<string, Record<string, SingleChange[]>>;
}; };
export const devItem = (meta: IMeta) => { type SingleChange =
return { ...meta.item, update: async () => {} } as IItem & PrasiEdit; | { type: "set"; name: string; value: any }
| ({ type: "prop"; name: string } & PropVal);
type PropVal =
| { mode: "string"; value: string }
| { mode: "raw"; value: string; valueBuilt?: string }
| { mode: "jsx"; value: null | (IItem & PrasiEdit) };
type ParentArg = {
item: IItem & PrasiEdit;
child_type: "jsx" | "child";
child_idx: number;
};
type PrasiEdit = {
edit: {
setValue: <T extends keyof IItem>(name: T, value: IItem[T]) => void;
setProp: (name: string, value: PropVal | string) => void;
pending: SingleChange[];
readonly childs: (IItem & PrasiEdit)[];
readonly parent: null | ParentArg;
commit: () => Promise<void>;
readonly props?: Record<string, PropVal>;
};
};
export const devItem = (
metas: Record<string, IMeta>,
mitem: MItem,
page_id: string
) => {
if (!w.prasiEdit) {
w.prasiEdit = {};
}
let pedit = w.prasiEdit[page_id];
if (!pedit) {
w.prasiEdit[page_id] = {};
pedit = w.prasiEdit[page_id];
}
const initChanges = () => {
const id = mitem.get("id") || "";
let changes = pedit[id];
if (!changes) {
pedit[id] = [];
changes = pedit[id];
}
return changes;
};
const item = mitem.toJSON() as IItem;
return {
...item,
edit: {
get props() {
if (item.component?.props) {
const result: Record<string, PropVal> = {};
for (const [k, v] of Object.entries(item.component.props)) {
if (v.value === v.valueBuilt) {
result[k] = JSON.parse(v.value);
} else if (v.meta?.type === "content-element") {
const content = mitem
.get("component")
?.get("props")
?.get(k)
?.get("content");
if (content) {
result[k] = {
mode: "jsx",
value: devItem(metas, content, page_id),
};
} else {
result[k] = {
mode: "jsx",
value: null as any,
};
}
} else {
result[k] = {
mode: "raw",
value: v.value,
valueBuilt: v.valueBuilt,
};
}
}
return result;
}
return undefined;
},
get pending() {
return [];
},
async commit() {
const result = {} as Record<string, any>;
for (const [item_id, changes] of Object.entries(pedit)) {
if (mitem) {
const item = mitem.toJSON();
const props = item?.component?.props as Record<string, FNCompDef>;
const src = {} as Record<string, string>;
for (const c of changes) {
if (c.type === "prop" && props) {
if (props[c.name]) {
if (c.mode === "string") {
props[c.name].value = JSON.stringify(c.value);
props[c.name].valueBuilt = JSON.stringify(c.value);
} else if (c.mode === "raw") {
props[c.name].value = c.value;
if (c.valueBuilt) {
props[c.name].valueBuilt = c.valueBuilt;
} else {
src[c.name] = c.value;
}
} else if (c.mode === "jsx") {
if (!props[c.name]) {
props[c.name] = {
meta: { type: "content-element" },
} as any;
}
if (c.value) {
props[c.name].content = formatChilds([c.value])[0];
}
}
}
} else {
if (c.type === "set" && typeof c.value === "object") {
for (const [k, v] of Object.entries(c.value) as any) {
item[k] = v;
}
}
}
}
const result = await _api.code_build(src);
for (const [k, v] of Object.entries(result)) {
props[k].valueBuilt = v;
}
result[item_id] = item;
}
}
if (mitem) {
mitem.doc?.transact(() => {
for (const [k, v] of Object.entries(result)) {
const m = metas[k];
if (m.mitem) {
syncronize(m.mitem as any, v);
}
}
});
}
},
setValue(name, value) {
const changes = initChanges();
let _value: any = value;
if (name === "childs") {
_value = formatChilds(value as any);
}
changes.push({ type: "set", name, value: _value });
},
setProp(name, value) {
const changes = initChanges();
if (typeof value === "string") {
changes.push({
type: "prop",
mode: "string",
name,
value,
});
} else {
if (value.mode === "string") {
changes.push({
type: "prop",
mode: "string",
name,
value: value.value,
});
} else if (value.mode === "raw") {
changes.push({
type: "prop",
mode: "raw",
name,
value: value.value,
valueBuilt: value.valueBuilt,
});
} else if (value.mode === "jsx") {
changes.push({
type: "prop",
mode: "jsx",
name,
value: value.value,
});
}
}
},
get childs() {
const item = mitem?.toJSON() as IItem;
if (item.childs) {
return item.childs.map((e) => {
const mitem = metas[e.id].mitem;
if (mitem) return devItem(metas, mitem, page_id);
});
}
return [];
},
get parent() {
if (mitem) {
const parent = mitem.parent.toJSON();
if (Array.isArray(parent)) {
const parent_id = (mitem.parent?.parent as any).get("id");
const parent_meta = metas[parent_id].mitem;
if (parent_meta) {
return {
item: devItem(metas, parent_meta, page_id),
child_type: "child",
child_idx: parent.findIndex((e) => e.id === item.id),
};
}
}
}
return null;
},
},
} as IItem & PrasiEdit;
};
const formatChilds = (childs: (IItem & PrasiEdit)[]) => {
const result = childs.map((e) => {
const item: any = { ...e };
delete item.edit;
return item;
});
return result;
}; };

View File

@ -61,7 +61,9 @@ export const viEvalScript = (
PassProp: script?.PassProp, PassProp: script?.PassProp,
ErrorBox: ErrorBox, ErrorBox: ErrorBox,
newElement: () => {}, newElement: () => {},
_item: meta.mitem ? devItem(meta) : meta.item, _item: meta.mitem
? devItem(vi.meta, meta.mitem, vi.page.cur.id)
: meta.item,
_meta: vi.meta, _meta: vi.meta,
render: (jsx: ReactNode) => { render: (jsx: ReactNode) => {
let result = jsx; let result = jsx;

View File

@ -47,7 +47,7 @@ export const baseTypings = `
}; };
const children: RElement; const children: RElement;
type PrasiItemSingle = { type IItem = {
id: string; id: string;
name: string; name: string;
type: "item" | "text"; type: "item" | "text";
@ -66,12 +66,42 @@ export const baseTypings = `
{ type: "string" | "raw"; value: string; valueBuilt?: string } { type: "string" | "raw"; value: string; valueBuilt?: string }
>; >;
}; };
childs: PrasiItemSingle[]; childs: IItem[];
}; };
type SingleChange = { type: "set" | "prop"; name: string; value: any };
type PropVal = string | { type: "raw"; value: string; valueBuilt?: string };
type ChildArg = {
name: string;
} & (
| {
type?: "text";
item?: Partial<IItem>;
}
| ItemArg
);
type ItemArg = {
type?: "item";
component?: { id: string; prop?: Record<string, PropVal> };
item?: Partial<IItem>;
childs?: ChildArg[];
};
type ParentArg = ItemArg & { parent?: ItemArg & PrasiEdit } & PrasiEdit;
type PrasiEdit = { type PrasiEdit = {
update: (fn: () => Promise<void> | void) => void; edit: {
} setValue: <T extends keyof IItem>(name: T, value: IItem[T]) => void;
type PrasiItem = PrasiItemSingle & PrasiEdit; setProp: (name: string, value: PropVal) => void;
pending: SingleChange[];
childs: ChildArg[];
parent: ParentArg;
commit: () => Promise<void>;
};
};
type PrasiItem = IItem & PrasiEdit;
const _item: undefined | PrasiItem; const _item: undefined | PrasiItem;