prasi-bun/app/web/src/nova/view/render/meta/script/comp-propval.tsx

131 lines
3.9 KiB
TypeScript

import { createAPI, createDB } from "../../../../../utils/script/init-api";
import { IItem } from "../../../../../utils/types/item";
import { FNCompDef } from "../../../../../utils/types/meta-fn";
import { IMeta } from "../../../../ed/logic/ed-global";
import { VG } from "../../../logic/global";
import { extractNavigate, preload } from "../../../logic/router";
import { ViewMeta } from "../meta";
import { mergeScopeUpwards } from "./merge-upward";
const jsxProps = {} as Record<string, any>;
export const compPropVal = (
v: VG,
meta: IMeta,
scopeIndex?: Record<string, any>
) => {
let props = {} as Record<string, FNCompDef>;
let cprops = [] as [string, FNCompDef][];
const item = meta.item;
if (item.type === "item" && item.component?.id) {
const icomp = item.component;
if (icomp) {
props = icomp.props;
cprops = Object.entries({ ...icomp.props });
if (!v.script.db) v.script.db = createDB(v.script.api_url);
if (!v.script.api) v.script.api = createAPI(v.script.api_url);
const w = window as any;
const finalScope = mergeScopeUpwards(v, item.id, scopeIndex);
const args = {
...w.exports,
...finalScope,
db: v.script.db,
api: v.script.api,
};
const result: any = {};
for (const [name, _prop] of cprops) {
const prop = props[name] || _prop;
let value: any = null;
if (prop.valueBuilt) {
const fn = new Function(
...Object.keys(args),
`return ${prop.valueBuilt}`
);
try {
value = fn(...Object.values(args)) || null;
const navs = extractNavigate(prop.valueBuilt || "");
if (navs.length > 0) {
navs.map((nav) => preload(v, nav));
}
} catch (e) {
const cname = meta.item.name;
console.warn(e);
console.warn(
`ERROR in Component [${cname}], in prop [${name}]:\n ` +
prop.value
);
}
}
if (prop.meta?.type === "content-element") {
if (!(typeof value === "object" && !!value && value._jsx)) {
const id = `${meta.item.id}-${name}`;
if (!jsxProps[id]) {
jsxProps[id] = {
_jsx: true,
Comp: ({
parent_id,
scopeIndex,
}: {
parent_id: string;
scopeIndex?: Record<string, any>;
}) => {
if (prop.content) {
const meta = v.meta[prop.content.id] as IMeta;
let parent = v.meta[parent_id];
if (meta && parent) {
meta.parent_item.id = parent_id;
return (
<ViewMeta
id={prop.content.id}
scopeIndex={scopeIndex}
/>
);
}
}
return <></>;
},
};
}
value = jsxProps[id];
}
}
result[name] = value;
}
meta.propval = result;
const propvis: any = {};
for (const [name, _prop] of cprops) {
const prop = props[name] || _prop;
if (prop.visible) {
const finalArgs = { ...args, ...result };
try {
const fn = new Function(
...Object.keys(finalArgs),
`return ${_prop.visible}`
);
propvis[name] = fn(...Object.values(finalArgs));
} catch (e) {
const cname = meta.item.name;
console.warn(e);
console.warn(
`ERROR in Component [${cname}], in prop [${name}]:\n ` +
prop.visible
);
}
}
}
meta.propvis = propvis;
}
}
};