fix
This commit is contained in:
parent
587b3611ca
commit
0a39588932
|
|
@ -142,6 +142,7 @@ export const _ = {
|
||||||
id: newcomp.id,
|
id: newcomp.id,
|
||||||
name: "",
|
name: "",
|
||||||
props: {},
|
props: {},
|
||||||
|
ref_ids: {},
|
||||||
},
|
},
|
||||||
} as IItem
|
} as IItem
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,32 +5,34 @@ export const SyncActionDefinition = {
|
||||||
"load": "2"
|
"load": "2"
|
||||||
},
|
},
|
||||||
"comp": {
|
"comp": {
|
||||||
"list": "3",
|
"new": "3",
|
||||||
"group": "4",
|
"list": "4",
|
||||||
"load": "5"
|
"group": "5",
|
||||||
|
"load": "6"
|
||||||
},
|
},
|
||||||
"page": {
|
"page": {
|
||||||
"list": "6",
|
"list": "7",
|
||||||
"load": "7"
|
"load": "8"
|
||||||
},
|
},
|
||||||
"yjs": {
|
"yjs": {
|
||||||
"um": "8",
|
"um": "9",
|
||||||
"sv_local": "9",
|
"sv_local": "10",
|
||||||
"diff_local": "10",
|
"diff_local": "11",
|
||||||
"sv_remote": "11"
|
"sv_remote": "12"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const SyncActionPaths = {
|
export const SyncActionPaths = {
|
||||||
"0": "site.list",
|
"0": "site.list",
|
||||||
"1": "site.group",
|
"1": "site.group",
|
||||||
"2": "site.load",
|
"2": "site.load",
|
||||||
"3": "comp.list",
|
"3": "comp.new",
|
||||||
"4": "comp.group",
|
"4": "comp.list",
|
||||||
"5": "comp.load",
|
"5": "comp.group",
|
||||||
"6": "page.list",
|
"6": "comp.load",
|
||||||
"7": "page.load",
|
"7": "page.list",
|
||||||
"8": "yjs.um",
|
"8": "page.load",
|
||||||
"9": "yjs.sv_local",
|
"9": "yjs.um",
|
||||||
"10": "yjs.diff_local",
|
"10": "yjs.sv_local",
|
||||||
"11": "yjs.sv_remote"
|
"11": "yjs.diff_local",
|
||||||
|
"12": "yjs.sv_remote"
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import {
|
||||||
EPage,
|
EPage,
|
||||||
ESite,
|
ESite,
|
||||||
} from "../../../web/src/render/ed/logic/ed-global";
|
} from "../../../web/src/render/ed/logic/ed-global";
|
||||||
|
import { IItem } from "../../../web/src/utils/types/item";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
WARNING:
|
WARNING:
|
||||||
|
|
@ -22,8 +23,10 @@ export const SyncActions = {
|
||||||
load: async (id: string) => ({}) as ESite | void,
|
load: async (id: string) => ({}) as ESite | void,
|
||||||
},
|
},
|
||||||
comp: {
|
comp: {
|
||||||
|
new: async (arg: { group_id: string; item: IItem }) => {},
|
||||||
list: () => ({}) as Record<string, Exclude<component, "content_tree">>,
|
list: () => ({}) as Record<string, Exclude<component, "content_tree">>,
|
||||||
group: () => ({}) as Record<string, string[]>,
|
group: async (id_site: string) =>
|
||||||
|
({}) as Record<string, { id: string; name: string; comps: string[] }>,
|
||||||
load: async (id: string) => ({}) as EComp | void,
|
load: async (id: string) => ({}) as EComp | void,
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { SAction } from "../actions";
|
||||||
|
import { SyncConnection } from "../type";
|
||||||
|
|
||||||
|
export const comp_group: SAction["comp"]["group"] = async function (
|
||||||
|
this: SyncConnection,
|
||||||
|
id_site
|
||||||
|
) {
|
||||||
|
const result: Awaited<ReturnType<SAction["comp"]["group"]>> = {};
|
||||||
|
const groups = await db.component_group.findMany({
|
||||||
|
where: {
|
||||||
|
component_site: {
|
||||||
|
some: {
|
||||||
|
id_site,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const g of groups) {
|
||||||
|
result[g.id] = {
|
||||||
|
id: g.id,
|
||||||
|
name: g.name,
|
||||||
|
comps: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
@ -1,21 +1,65 @@
|
||||||
import { syncronize } from "y-pojo";
|
import { syncronize } from "y-pojo";
|
||||||
import { docs } from "../entity/docs";
|
import { SAction } from "../actions";
|
||||||
|
import { conns } from "../entity/conn";
|
||||||
|
import { Y, docs } from "../entity/docs";
|
||||||
import { snapshot } from "../entity/snapshot";
|
import { snapshot } from "../entity/snapshot";
|
||||||
|
import { user } from "../entity/user";
|
||||||
import { gzipAsync } from "../entity/zlib";
|
import { gzipAsync } from "../entity/zlib";
|
||||||
import { SyncConnection } from "../type";
|
import { sendWS } from "../sync-handler";
|
||||||
|
import { SyncConnection, SyncType } from "../type";
|
||||||
|
|
||||||
export const comp_load = async function (this: SyncConnection, id: string) {
|
export const comp_load: SAction["comp"]["load"] = async function (
|
||||||
|
this: SyncConnection,
|
||||||
|
id: string
|
||||||
|
) {
|
||||||
let snap = snapshot.get("comp", id);
|
let snap = snapshot.get("comp", id);
|
||||||
let ydoc = docs.comp[id];
|
let ydoc = docs.comp[id];
|
||||||
|
const conf = this.conf;
|
||||||
|
if (!conf) return undefined;
|
||||||
|
|
||||||
if (!snap || !ydoc) {
|
const createUndoManager = async (root: Y.Map<any>) => {
|
||||||
|
const um = new Y.UndoManager(root, {
|
||||||
|
ignoreRemoteMapChanges: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return um;
|
||||||
|
};
|
||||||
|
|
||||||
|
const attachOnUpdate = async (doc: Y.Doc, um: Y.UndoManager) => {
|
||||||
|
snapshot.set("comp", id, "id_doc", um.doc.clientID);
|
||||||
|
|
||||||
|
doc.on("update", async (update: Uint8Array, origin: any) => {
|
||||||
|
const bin = Y.encodeStateAsUpdate(doc);
|
||||||
|
snapshot.set("comp", id, "bin", bin);
|
||||||
|
|
||||||
|
const sv_local = await gzipAsync(update);
|
||||||
|
user.active.findAll({ comp_id: id }).map((e) => {
|
||||||
|
if (origin !== um) {
|
||||||
|
if (e.client_id === origin) return;
|
||||||
|
}
|
||||||
|
const ws = conns.get(e.client_id)?.ws;
|
||||||
|
if (ws)
|
||||||
|
sendWS(ws, {
|
||||||
|
type: SyncType.Event,
|
||||||
|
event: "remote_svlocal",
|
||||||
|
data: { type: "comp", sv_local, id },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultActive = {
|
||||||
|
select: "" as "" | "comp" | "item" | "section" | "text",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!snap && !ydoc) {
|
||||||
const comp = await db.component.findFirst({ where: { id } });
|
const comp = await db.component.findFirst({ where: { id } });
|
||||||
if (comp) {
|
if (comp) {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
let root = doc.getMap("map");
|
let root = doc.getMap("map");
|
||||||
syncronize(root, { id, item: comp.content_tree });
|
syncronize(root, { id, root: comp.content_tree });
|
||||||
|
|
||||||
const um = new Y.UndoManager(root, { ignoreRemoteMapChanges: true });
|
const um = await createUndoManager(root);
|
||||||
docs.comp[id] = {
|
docs.comp[id] = {
|
||||||
doc: doc as any,
|
doc: doc as any,
|
||||||
id,
|
id,
|
||||||
|
|
@ -23,13 +67,24 @@ export const comp_load = async function (this: SyncConnection, id: string) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const bin = Y.encodeStateAsUpdate(doc);
|
const bin = Y.encodeStateAsUpdate(doc);
|
||||||
|
await attachOnUpdate(doc, um);
|
||||||
|
|
||||||
snapshot.update({
|
snapshot.update({
|
||||||
bin,
|
bin,
|
||||||
id,
|
id,
|
||||||
type: "comp",
|
type: "comp",
|
||||||
name: comp.name,
|
name: comp.name,
|
||||||
url: "",
|
|
||||||
ts: Date.now(),
|
ts: Date.now(),
|
||||||
|
id_doc: doc.clientID,
|
||||||
|
});
|
||||||
|
|
||||||
|
user.active.add({
|
||||||
|
...defaultActive,
|
||||||
|
client_id: this.client_id,
|
||||||
|
user_id: this.user_id,
|
||||||
|
site_id: conf.site_id,
|
||||||
|
page_id: conf.page_id,
|
||||||
|
comp_id: comp.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -40,22 +95,43 @@ export const comp_load = async function (this: SyncConnection, id: string) {
|
||||||
}
|
}
|
||||||
} else if (snap && !ydoc) {
|
} else if (snap && !ydoc) {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
|
snapshot.set("comp", id, "id_doc", doc.clientID);
|
||||||
Y.applyUpdate(doc, snap.bin);
|
Y.applyUpdate(doc, snap.bin);
|
||||||
let root = doc.getMap("map");
|
let root = doc.getMap("map");
|
||||||
|
|
||||||
const um = new Y.UndoManager(root, { ignoreRemoteMapChanges: true });
|
const um = await createUndoManager(root);
|
||||||
docs.page[id] = {
|
await attachOnUpdate(doc, um);
|
||||||
|
|
||||||
|
docs.comp[id] = {
|
||||||
doc: doc as any,
|
doc: doc as any,
|
||||||
id,
|
id,
|
||||||
um,
|
um,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
user.active.add({
|
||||||
|
...defaultActive,
|
||||||
|
client_id: this.client_id,
|
||||||
|
user_id: this.user_id,
|
||||||
|
site_id: conf.site_id,
|
||||||
|
page_id: conf.page_id,
|
||||||
|
comp_id: id,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: id,
|
||||||
name: snap.name,
|
name: snap.name,
|
||||||
snapshot: await gzipAsync(snap.bin),
|
snapshot: await gzipAsync(snap.bin),
|
||||||
};
|
};
|
||||||
} else if (snap && ydoc) {
|
} else if (snap && ydoc) {
|
||||||
|
user.active.add({
|
||||||
|
...defaultActive,
|
||||||
|
client_id: this.client_id,
|
||||||
|
user_id: this.user_id,
|
||||||
|
site_id: conf.site_id,
|
||||||
|
page_id: conf.page_id,
|
||||||
|
comp_id: id,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: snap.id,
|
id: snap.id,
|
||||||
name: snap.name,
|
name: snap.name,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { SAction } from "../actions";
|
||||||
|
import { SyncConnection } from "../type";
|
||||||
|
|
||||||
|
export const comp_new: SAction["comp"]["new"] = async function (
|
||||||
|
this: SyncConnection
|
||||||
|
) {};
|
||||||
|
|
@ -2,6 +2,7 @@ export * from "./site_load";
|
||||||
export * from "./site_group";
|
export * from "./site_group";
|
||||||
export * from "./page_load";
|
export * from "./page_load";
|
||||||
export * from "./comp_load";
|
export * from "./comp_load";
|
||||||
|
export * from "./comp_group";
|
||||||
export * from "./yjs_um";
|
export * from "./yjs_um";
|
||||||
export * from "./yjs_sv_local";
|
export * from "./yjs_sv_local";
|
||||||
export * from "./yjs_diff_local";
|
export * from "./yjs_diff_local";
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@ export const page_load: SAction["page"]["load"] = async function (
|
||||||
let snap = snapshot.get("page", id);
|
let snap = snapshot.get("page", id);
|
||||||
let ydoc = docs.page[id];
|
let ydoc = docs.page[id];
|
||||||
|
|
||||||
if (this.conf) this.conf.page_id = id;
|
const conf = this.conf;
|
||||||
|
if (!conf) return undefined;
|
||||||
|
|
||||||
|
conf.page_id = id;
|
||||||
|
|
||||||
const createUndoManager = async (root: Y.Map<any>) => {
|
const createUndoManager = async (root: Y.Map<any>) => {
|
||||||
const um = new Y.UndoManager(root, {
|
const um = new Y.UndoManager(root, {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { SAction } from "../actions";
|
import { SAction } from "../actions";
|
||||||
import { Y, docs } from "../entity/docs";
|
import { Y, docs } from "../entity/docs";
|
||||||
import { snapshot } from "../entity/snapshot";
|
|
||||||
import { gunzipAsync } from "../entity/zlib";
|
import { gunzipAsync } from "../entity/zlib";
|
||||||
import { SyncConnection } from "../type";
|
import { SyncConnection } from "../type";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,47 @@ import { dir } from "dir";
|
||||||
import { RootDatabase, open } from "lmdb";
|
import { RootDatabase, open } from "lmdb";
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
|
|
||||||
const emptySnapshot = {
|
type EmptySnapshot = {
|
||||||
type: "" as "" | "comp" | "page" | "site",
|
type: "";
|
||||||
|
id: string;
|
||||||
|
bin: Uint8Array;
|
||||||
|
id_doc: number;
|
||||||
|
name: string;
|
||||||
|
ts: number;
|
||||||
|
};
|
||||||
|
type CompSnapshot = {
|
||||||
|
type: "comp";
|
||||||
|
id: string;
|
||||||
|
bin: Uint8Array;
|
||||||
|
id_doc: number;
|
||||||
|
name: string;
|
||||||
|
ts: number;
|
||||||
|
};
|
||||||
|
type PageSnapshot = {
|
||||||
|
type: "page";
|
||||||
|
id: string;
|
||||||
|
bin: Uint8Array;
|
||||||
|
id_doc: number;
|
||||||
|
name: string;
|
||||||
|
ts: number;
|
||||||
|
url: string;
|
||||||
|
id_site: string;
|
||||||
|
};
|
||||||
|
type DocSnapshotMap = {
|
||||||
|
page: PageSnapshot;
|
||||||
|
comp: CompSnapshot;
|
||||||
|
"": EmptySnapshot;
|
||||||
|
};
|
||||||
|
export type DocSnapshot = EmptySnapshot | CompSnapshot | PageSnapshot;
|
||||||
|
|
||||||
|
const emptySnapshot: DocSnapshot = {
|
||||||
|
type: "",
|
||||||
id: "",
|
id: "",
|
||||||
bin: new Uint8Array(),
|
bin: new Uint8Array(),
|
||||||
id_doc: 0,
|
id_doc: 0,
|
||||||
name: "",
|
name: "",
|
||||||
ts: Date.now(),
|
ts: Date.now(),
|
||||||
};
|
};
|
||||||
export type DocSnapshot = typeof emptySnapshot & {
|
|
||||||
type: "page";
|
|
||||||
url: string;
|
|
||||||
id_site: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const snapshot = {
|
export const snapshot = {
|
||||||
_db: null as null | RootDatabase<DocSnapshot>,
|
_db: null as null | RootDatabase<DocSnapshot>,
|
||||||
|
|
@ -41,8 +69,8 @@ export const snapshot = {
|
||||||
}
|
}
|
||||||
return res as DocSnapshot;
|
return res as DocSnapshot;
|
||||||
},
|
},
|
||||||
get(type: string, id: string) {
|
get<K extends DocSnapshot["type"]>(type: K, id: string) {
|
||||||
return this.db.get(`${type}-${id}`);
|
return this.db.get(`${type}-${id}`) as DocSnapshotMap[K] | null;
|
||||||
},
|
},
|
||||||
async update(data: DocSnapshot) {
|
async update(data: DocSnapshot) {
|
||||||
const id = `${data.type}-${data.id}`;
|
const id = `${data.type}-${data.id}`;
|
||||||
|
|
@ -50,7 +78,7 @@ export const snapshot = {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
async set<T extends keyof DocSnapshot>(
|
async set<T extends keyof DocSnapshot>(
|
||||||
type: string,
|
type: keyof DocSnapshotMap,
|
||||||
id: string,
|
id: string,
|
||||||
key: T,
|
key: T,
|
||||||
value: DocSnapshot[T]
|
value: DocSnapshot[T]
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export const user = {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
site_id: string;
|
site_id: string;
|
||||||
page_id: string;
|
page_id: string;
|
||||||
|
comp_id?: string;
|
||||||
select: "" | "comp" | "item" | "section" | "text";
|
select: "" | "comp" | "item" | "section" | "text";
|
||||||
},
|
},
|
||||||
"client_id"
|
"client_id"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { edRoute } from "./logic/ed-route";
|
||||||
import { EdMain } from "./panel/main/main";
|
import { EdMain } from "./panel/main/main";
|
||||||
import { EdTree } from "./panel/tree/tree";
|
import { EdTree } from "./panel/tree/tree";
|
||||||
import { edUndoManager } from "./logic/ed-undo";
|
import { edUndoManager } from "./logic/ed-undo";
|
||||||
|
import { EdPopCompGroup } from "./panel/popup/comp-group";
|
||||||
|
|
||||||
export const EdBase = () => {
|
export const EdBase = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
@ -35,6 +36,10 @@ export const EdBase = () => {
|
||||||
<EdTree />
|
<EdTree />
|
||||||
<EdMain />
|
<EdMain />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<>
|
||||||
|
<EdPopCompGroup />
|
||||||
|
</>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { IItem, MItem } from "../../../utils/types/item";
|
||||||
import { DComp, DPage, IRoot } from "../../../utils/types/root";
|
import { DComp, DPage, IRoot } from "../../../utils/types/root";
|
||||||
import { ISection } from "../../../utils/types/section";
|
import { ISection } from "../../../utils/types/section";
|
||||||
import { IText, MText } from "../../../utils/types/text";
|
import { IText, MText } from "../../../utils/types/text";
|
||||||
|
import { SAction } from "../../../../../srv/ws/sync/actions";
|
||||||
|
|
||||||
const EmptySite = {
|
const EmptySite = {
|
||||||
id: "",
|
id: "",
|
||||||
|
|
@ -83,11 +84,12 @@ export const EDGlobal = {
|
||||||
doc: null as null | DComp,
|
doc: null as null | DComp,
|
||||||
item: null as null | IItem,
|
item: null as null | IItem,
|
||||||
list: {} as Record<string, { cur: EComp; doc: DComp }>,
|
list: {} as Record<string, { cur: EComp; doc: DComp }>,
|
||||||
|
group: {} as Record<string, Awaited<ReturnType<SAction["comp"]["group"]>>>,
|
||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
tree: {
|
tree: {
|
||||||
search: "",
|
search: "",
|
||||||
searchMode: {
|
search_mode: {
|
||||||
Name: true,
|
Name: true,
|
||||||
JS: false,
|
JS: false,
|
||||||
HTML: false,
|
HTML: false,
|
||||||
|
|
@ -96,14 +98,12 @@ export const EDGlobal = {
|
||||||
open: {} as Record<string, string[]>,
|
open: {} as Record<string, string[]>,
|
||||||
},
|
},
|
||||||
popup: {
|
popup: {
|
||||||
comp: null as null | true | ((comp_id: string) => void | Promise<void>),
|
comp: null as null | ((comp_id: string) => void | Promise<void>),
|
||||||
compGroup: null as
|
comp_group: null as null | {
|
||||||
| null
|
mouse_event: React.MouseEvent<HTMLElement, MouseEvent>;
|
||||||
| true
|
on_pick?: (group_id: string) => void | Promise<void>;
|
||||||
| {
|
on_close?: () => void | Promise<void>;
|
||||||
event: React.MouseEvent<HTMLElement, MouseEvent>;
|
},
|
||||||
pick: (group_id: string) => void | Promise<void>;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { useGlobal } from "web-utils";
|
||||||
|
import { Menu, MenuItem } from "../../../../utils/ui/context-menu";
|
||||||
|
import { EDGlobal } from "../../logic/ed-global";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { Loading } from "../../../../utils/ui/loading";
|
||||||
|
|
||||||
|
export const EdPopCompGroup = () => {
|
||||||
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
if (!p.comp.group[p.site.id]) {
|
||||||
|
p.comp.group[p.site.id] = await p.sync.comp.group(p.site.id);
|
||||||
|
}
|
||||||
|
console.log(p.comp.group[p.site.id]);
|
||||||
|
p.render();
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!p.ui.popup.comp_group) return null;
|
||||||
|
const pop = p.ui.popup.comp_group;
|
||||||
|
const group = p.comp.group[p.site.id];
|
||||||
|
return (
|
||||||
|
<Menu
|
||||||
|
mouseEvent={pop.mouse_event}
|
||||||
|
onClose={() => {
|
||||||
|
p.ui.popup.comp_group = null;
|
||||||
|
p.render();
|
||||||
|
if (pop.on_close) pop.on_close();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
disabled
|
||||||
|
label={
|
||||||
|
!group ? (
|
||||||
|
<div className="bg-white relative w-[150px] h-[20px]">
|
||||||
|
<div className="absolute inset-0 -mx-[10px] -my-[2px]">
|
||||||
|
<Loading />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-slate-500">Choose Component Group:</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{Object.values(group || {})
|
||||||
|
.filter((g) => g.name !== "__TRASH__")
|
||||||
|
.sort((a, b) => (a.name > b.name ? 1 : -1))
|
||||||
|
.map((g) => (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
p.ui.popup.comp_group?.on_pick?.(g.id);
|
||||||
|
}}
|
||||||
|
label={<div className="pl-2">{g.name}</div>}
|
||||||
|
key={g.id}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
import { IItem } from "../../../../../../../utils/types/item";
|
import { IItem } from "../../../../../../../utils/types/item";
|
||||||
import { PG } from "../../../../../logic/ed-global";
|
import { PG } from "../../../../../logic/ed-global";
|
||||||
|
|
||||||
export const edActionNewComp = (p: PG, item: IItem) => {
|
export const edActionNewComp = (
|
||||||
|
p: PG,
|
||||||
|
item: IItem,
|
||||||
|
e: React.MouseEvent<HTMLElement, MouseEvent>
|
||||||
|
) => {
|
||||||
const mitem = p.page.meta[item.id].mitem;
|
const mitem = p.page.meta[item.id].mitem;
|
||||||
if (mitem) {
|
if (mitem) {
|
||||||
|
p.ui.popup.comp_group = {
|
||||||
|
mouse_event: e,
|
||||||
|
async on_pick(group_id) {
|
||||||
|
await p.sync.comp.new({ group_id, item });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
p.render();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,10 @@ export const EdTreeCtxMenu = ({
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return (
|
return (
|
||||||
<Menu mouseEvent={event} onClose={onClose}>
|
<Menu mouseEvent={event} onClose={onClose}>
|
||||||
<MenuItem label={<div className="text-gray-400">Unavailable</div>} />
|
<MenuItem
|
||||||
|
disabled
|
||||||
|
label={<div className="text-slate-500">Unavailable</div>}
|
||||||
|
/>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +82,7 @@ export const EdTreeCtxMenu = ({
|
||||||
{type === "item" && !comp?.id && (
|
{type === "item" && !comp?.id && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
label="Create Component"
|
label="Create Component"
|
||||||
onClick={() => edActionNewComp(p, item)}
|
onClick={(e) => edActionNewComp(p, item, e)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!item.hidden && (
|
{!item.hidden && (
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ export const indentHook = (
|
||||||
|
|
||||||
let shouldOpen = open[p.page.cur.id] || [];
|
let shouldOpen = open[p.page.cur.id] || [];
|
||||||
|
|
||||||
let meta = p.page.meta[active.item_id];
|
const cur = p.page.meta[active.item_id];
|
||||||
|
let meta = p.page.meta[cur.parent_item.id];
|
||||||
while (meta) {
|
while (meta) {
|
||||||
if (meta.item.id) shouldOpen.push(meta.item.id);
|
if (meta.item.id) shouldOpen.push(meta.item.id);
|
||||||
meta = p.page.meta[meta.parent_item.id];
|
meta = p.page.meta[meta.parent_item.id];
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export const EdTreeSearch = () => {
|
||||||
{(local.focus || local.hover || p.ui.tree.search) && (
|
{(local.focus || local.hover || p.ui.tree.search) && (
|
||||||
<div className="p-1 bg-white text-xs border-t flex space-x-1 justify-between">
|
<div className="p-1 bg-white text-xs border-t flex space-x-1 justify-between">
|
||||||
<div className="flex space-x-1">
|
<div className="flex space-x-1">
|
||||||
{Object.entries(p.ui.tree.searchMode).map(([name, active]) => {
|
{Object.entries(p.ui.tree.search_mode).map(([name, active]) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
|
|
@ -74,7 +74,7 @@ export const EdTreeSearch = () => {
|
||||||
active ? "bg-blue-500 text-white" : "hover:bg-blue-100"
|
active ? "bg-blue-500 text-white" : "hover:bg-blue-100"
|
||||||
)}
|
)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
(p.ui.tree.searchMode as any)[name] = !active;
|
(p.ui.tree.search_mode as any)[name] = !active;
|
||||||
local.render();
|
local.render();
|
||||||
local.sref?.focus();
|
local.sref?.focus();
|
||||||
}}
|
}}
|
||||||
|
|
@ -94,7 +94,7 @@ export const EdTreeSearch = () => {
|
||||||
export const doTreeSearch = (p: PG) => {
|
export const doTreeSearch = (p: PG) => {
|
||||||
let tree: Record<string, { idx: number; node: NodeModel<EdMeta> }> = {};
|
let tree: Record<string, { idx: number; node: NodeModel<EdMeta> }> = {};
|
||||||
|
|
||||||
if (p.ui.tree.searchMode.Name) {
|
if (p.ui.tree.search_mode.Name) {
|
||||||
const [idxs, info] = uf.search(
|
const [idxs, info] = uf.search(
|
||||||
p.page.tree.map((e) => e.text),
|
p.page.tree.map((e) => e.text),
|
||||||
p.ui.tree.search
|
p.ui.tree.search
|
||||||
|
|
@ -162,7 +162,7 @@ export const doTreeSearch = (p: PG) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
const js = item.adv?.js;
|
const js = item.adv?.js;
|
||||||
if (js) {
|
if (js) {
|
||||||
if (p.ui.tree.searchMode.JS) {
|
if (p.ui.tree.search_mode.JS) {
|
||||||
if ((js as string).toLowerCase().includes(search)) {
|
if ((js as string).toLowerCase().includes(search)) {
|
||||||
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
||||||
}
|
}
|
||||||
|
|
@ -170,7 +170,7 @@ export const doTreeSearch = (p: PG) => {
|
||||||
}
|
}
|
||||||
const css = item.adv?.css;
|
const css = item.adv?.css;
|
||||||
if (css) {
|
if (css) {
|
||||||
if (p.ui.tree.searchMode.CSS) {
|
if (p.ui.tree.search_mode.CSS) {
|
||||||
if (css.toString().toLowerCase().includes(search)) {
|
if (css.toString().toLowerCase().includes(search)) {
|
||||||
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +179,7 @@ export const doTreeSearch = (p: PG) => {
|
||||||
|
|
||||||
const html = item.adv?.html;
|
const html = item.adv?.html;
|
||||||
if (html) {
|
if (html) {
|
||||||
if (p.ui.tree.searchMode.HTML) {
|
if (p.ui.tree.search_mode.HTML) {
|
||||||
if (html.toString().toLowerCase().includes(search)) {
|
if (html.toString().toLowerCase().includes(search)) {
|
||||||
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
tree[item.id] = { idx: i++, node: { ...row, parent: "root" } };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export const MenuItem = forwardRef<
|
||||||
interface Props {
|
interface Props {
|
||||||
label?: string;
|
label?: string;
|
||||||
nested?: boolean;
|
nested?: boolean;
|
||||||
mouseEvent: React.MouseEvent<HTMLDivElement, MouseEvent>;
|
mouseEvent: React.MouseEvent<HTMLElement, MouseEvent>;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue