wip fix id

This commit is contained in:
Rizky 2023-11-30 02:51:34 +07:00
parent eabbdb1f16
commit d51526e5a0
6 changed files with 220 additions and 88 deletions

View File

@ -0,0 +1,41 @@
import { createId as cuid } from "@paralleldrive/cuid2";
import { IContent } from "../../../../utils/types/general";
export const fillID = (
object: IContent,
modify?: (obj: IContent) => boolean,
currentDepth?: number
) => {
const _depth = (currentDepth || 0) + 1;
if (modify) {
if (modify(object)) {
object.id = cuid();
}
} else {
object.id = cuid();
}
if (
object.type === "item" &&
object.component &&
object.component.id &&
object.component.props
) {
for (const p of Object.values(object.component.props)) {
if (p.meta?.type === "content-element" && p.content) {
fillID(p.content, modify, _depth);
}
}
}
if (object.type !== "text") {
if (object.childs && Array.isArray(object.childs)) {
for (const child of object.childs) {
fillID(child, modify, _depth);
}
}
}
return object;
};

View File

@ -1,6 +1,10 @@
import { useGlobal } from "web-utils";
import { EDGlobal } from "../../../logic/ed-global";
import { EDGlobal, active } from "../../../logic/ed-global";
import { TopBtn } from "../top-btn";
import { loadComponent } from "../../../logic/tree/sync-walk";
import { MContent } from "../../../../../utils/types/general";
import { fillID } from "../../../logic/tree/fill-id";
import { IItem } from "../../../../../utils/types/item";
export const EdCompPicker = () => {
const p = useGlobal(EDGlobal, "EDITOR");
@ -8,7 +12,58 @@ export const EdCompPicker = () => {
return (
<TopBtn
onClick={(e) => {
p.ui.popup.comp.open = (comp_id) => {};
p.ui.popup.comp.open = async (comp_id) => {
let comp_ref = p.comp.list[comp_id];
if (!comp_ref) {
await loadComponent(p, comp_id);
comp_ref = p.comp.list[comp_id];
}
if (!comp_ref) {
alert("Cannot load component!");
return;
}
const comp = comp_ref.doc
.getMap("map")
.get("root")
?.toJSON() as IItem;
if (!comp) {
alert("Failed to load component!");
return;
}
if (!active.item_id) {
const first_id = p.page.entry[0];
if (first_id) {
const first = p.page.meta[first_id];
console.log(first);
}
} else {
const active_meta = p.page.meta[active.item_id];
if (active_meta) {
const item = active_meta.item;
const mitem = active_meta.mitem;
if (item && mitem) {
if (item.type !== "text") {
const map = new Y.Map() as MContent;
if (map) {
comp.originalId = comp.id;
syncronize(map as any, fillID(comp));
const childs = mitem.get("childs");
if (childs) {
childs.push([map]);
}
const newitem = map.toJSON();
active.item_id = newitem.id;
}
}
} else {
alert("Failed to add component!");
}
}
}
};
p.render();
}}
style="slim"

View File

@ -170,6 +170,7 @@ export const edPageTreeRender: NodeRender<CompItem> = (
const Name: FC<{ name: ReactNode }> = ({ name }) => {
if (typeof name !== "string") return name;
if (name === "__TRASH__") return "Trash";
if (name.startsWith("layout::")) {
return (

View File

@ -33,13 +33,32 @@ export const EdPopPage = () => {
if (local.tree) {
const parents: string[] = [];
let cur = pagePicker.tree.find((e) => e.id === p.page.cur.id);
while (cur) {
if (typeof cur.id === "string") {
const parent_id = cur.parent;
parents.push(cur.id);
cur = pagePicker.tree.find((e) => e.id === parent_id);
if (pagePicker.rename_id) {
let cur = pagePicker.tree.find((e) => e.id === pagePicker.rename_id);
while (cur) {
if (typeof cur.id === "string") {
if (parents.includes(cur.id)) {
continue;
}
const parent_id = cur.parent;
parents.push(cur.id);
cur = pagePicker.tree.find((e) => e.id === parent_id);
}
}
} else {
while (cur) {
if (typeof cur.id === "string") {
if (parents.includes(cur.id)) {
continue;
}
const parent_id = cur.parent;
parents.push(cur.id);
cur = pagePicker.tree.find((e) => e.id === parent_id);
}
}
}
if (parents.length <= 1) {
local.tree.open("page-root");
} else {
@ -47,7 +66,12 @@ export const EdPopPage = () => {
}
}
});
}, [p.ui.popup.page.open, p.page.cur.id, pagePicker.site_id]);
}, [
p.ui.popup.page.open,
p.page.cur.id,
pagePicker.site_id,
pagePicker.rename_id,
]);
if (!p.ui.popup.page.open) return null;
@ -102,73 +126,75 @@ export const EdPopPage = () => {
)}
>
<div className="relative flex flex-1 items-stretch text-[14px] overflow-auto">
{pagePicker.status === "loading" && (
{pagePicker.status === "loading" ? (
<Loading note="listing-page" backdrop={false} />
)}
) : (
<>
{pagePicker.ref && (
<DndProvider
backend={HTML5Backend}
options={getBackendOptions({
html5: {
rootElement: pagePicker.ref,
},
})}
>
<TypedTree
ref={(ref) => {
if (local.tree !== ref) {
local.tree = ref;
}
}}
tree={filtered}
rootId={"page-root"}
onDrop={async (newTree: NodeModel<PageItem>[], opt) => {
pagePicker.tree = newTree;
p.render();
{pagePicker.ref && (
<DndProvider
backend={HTML5Backend}
options={getBackendOptions({
html5: {
rootElement: pagePicker.ref,
},
})}
>
<TypedTree
ref={(ref) => {
if (local.tree !== ref) {
local.tree = ref;
}
}}
tree={filtered}
rootId={"page-root"}
onDrop={async (newTree: NodeModel<PageItem>[], opt) => {
pagePicker.tree = newTree;
p.render();
if (!opt.dragSource?.droppable) {
await db.page.update({
where: {
id: opt.dragSourceId as string,
},
data: {
id_folder: (opt.dropTargetId === "root" ||
!opt.dropTargetId
? null
: opt.dropTargetId) as string,
},
select: { id: true },
});
} else {
await db.page_folder.update({
where: {
id: opt.dragSourceId as string,
},
data: {
parent_id: (opt.dropTargetId === "ROOT" ||
!opt.dropTargetId
? null
: opt.dropTargetId) as string,
},
select: {
id: true,
},
});
}
reloadPagePicker(p);
}}
dragPreviewRender={() => <></>}
canDrag={() => true}
canDrop={(tree, opt) => {
if (opt.dropTarget?.data?.type === "page") return false;
if (opt.dropTargetId === "page-root") return false;
return true;
}}
classes={{ root: "flex-1", dropTarget: "dropping" }}
render={edPageTreeRender}
/>
</DndProvider>
if (!opt.dragSource?.droppable) {
await db.page.update({
where: {
id: opt.dragSourceId as string,
},
data: {
id_folder: (opt.dropTargetId === "root" ||
!opt.dropTargetId
? null
: opt.dropTargetId) as string,
},
select: { id: true },
});
} else {
await db.page_folder.update({
where: {
id: opt.dragSourceId as string,
},
data: {
parent_id: (opt.dropTargetId === "ROOT" ||
!opt.dropTargetId
? null
: opt.dropTargetId) as string,
},
select: {
id: true,
},
});
}
reloadPagePicker(p);
}}
dragPreviewRender={() => <></>}
canDrag={() => true}
canDrop={(tree, opt) => {
if (opt.dropTarget?.data?.type === "page") return false;
if (opt.dropTargetId === "page-root") return false;
return true;
}}
classes={{ root: "flex-1", dropTarget: "dropping" }}
render={edPageTreeRender}
/>
</DndProvider>
)}
</>
)}
</div>
</div>

View File

@ -17,6 +17,7 @@ export const pagePicker = {
status: "ready" as "loading" | "ready",
search: "",
render: () => {},
rename_id: ""
};
export const reloadPagePicker = async (p: PG) => {

View File

@ -1,7 +1,7 @@
import { NodeModel, NodeRender } from "@minoru/react-dnd-treeview";
import { FC, ReactNode } from "react";
import { useGlobal, useLocal } from "web-utils";
import { EDGlobal } from "../../../logic/ed-global";
import { FC, ReactNode } from "react";
import { pagePicker, reloadPagePicker } from "./page-reload";
export type PageItem = {
@ -15,9 +15,9 @@ export const edPageTreeRender: NodeRender<PageItem> = (
{ depth, isOpen, onToggle }
) => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ renaming: node.id === "", rename_to: "" });
const local = useLocal({ rename_to: "" });
const item = node.data;
if (!item || !item.name) return <></>;
if (!item) return <></>;
return (
<div
@ -60,27 +60,34 @@ export const edPageTreeRender: NodeRender<PageItem> = (
</>
)}
<div className="flex flex-1 pl-1">
{local.renaming ? (
{pagePicker.rename_id === item.id ? (
<input
value={local.rename_to}
autoFocus
onBlur={async () => {
local.renaming = false;
const rename_id = pagePicker.rename_id;
pagePicker.rename_id = "";
item.name = local.rename_to;
if (item.id === "") {
local.render();
if (item.id === "NEW") {
if (item.name) {
db.page_folder.create({
data: { name: local.rename_to, id_site: p.site.id },
await db.page_folder.create({
data: {
name: local.rename_to,
id_site: p.site.id,
parent_id: rename_id,
},
});
}
await reloadPagePicker(p);
} else {
db.page_folder.update({
await db.page_folder.update({
where: { id: item.id },
data: { name: local.rename_to },
});
}
local.render();
await reloadPagePicker(p);
}}
className="border px-1 bg-white flex-1 outline-none mr-1 border-blue-500 "
onChange={(e) => {
@ -101,7 +108,7 @@ export const edPageTreeRender: NodeRender<PageItem> = (
)}
</div>
{!local.renaming && (
{pagePicker.rename_id !== item.id && (
<div className="flex pr-2 items-stretch h-[18px] space-x-[2px] text-[10px]">
{item.type === "folder" && (
<>
@ -110,15 +117,16 @@ export const edPageTreeRender: NodeRender<PageItem> = (
onClick={(e) => {
e.stopPropagation();
pagePicker.tree.push({
id: "",
id: "NEW",
parent: item.id,
text: "",
data: {
id: "",
id: "NEW",
name: "",
type: "folder",
},
});
pagePicker.rename_id = "NEW";
p.render();
}}
>
@ -148,7 +156,7 @@ export const edPageTreeRender: NodeRender<PageItem> = (
e.stopPropagation();
if (item.type === "folder") {
local.rename_to = item.name;
local.renaming = true;
pagePicker.rename_id = item.id;
local.render();
} else {
p.ui.popup.page.form = item;