wip import component
This commit is contained in:
parent
07b12dc636
commit
5e2f3b1897
|
|
@ -2,8 +2,77 @@ import { apiContext } from "service-srv";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/comp-import",
|
url: "/comp-import",
|
||||||
async api(arg: { site_id: string; comp_ids: string[] }) {
|
async api(arg: { site_id: string; comps: string[] }) {
|
||||||
const { req, res } = apiContext(this);
|
const { req, res } = apiContext(this);
|
||||||
return "This is comp-import.ts";
|
|
||||||
|
if (arg.comps.length === 0) {
|
||||||
|
return {
|
||||||
|
status: "failed",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const comps = await _db.component.findMany({
|
||||||
|
where: {
|
||||||
|
id: { in: arg.comps },
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
content_tree: true,
|
||||||
|
component_group: {
|
||||||
|
select: { name: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const comp_groups = {} as Record<string, string>;
|
||||||
|
for (const comp of comps) {
|
||||||
|
if (comp.component_group?.name)
|
||||||
|
comp_groups[comp.component_group?.name] = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
await _db.component_site.findMany({
|
||||||
|
where: { id_site: arg.site_id },
|
||||||
|
select: {
|
||||||
|
component_group: { select: { id: true, name: true } },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)?.forEach((v) => {
|
||||||
|
if (v.component_group) {
|
||||||
|
if (comp_groups[v.component_group.name] === "-") {
|
||||||
|
comp_groups[v.component_group.name] = v.component_group.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [k, v] of Object.entries(comp_groups)) {
|
||||||
|
if (v === "-") {
|
||||||
|
const new_cg = await _db.component_group.create({
|
||||||
|
data: {
|
||||||
|
name: v,
|
||||||
|
component_site: { create: { id_site: arg.site_id } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (new_cg) {
|
||||||
|
comp_groups[k] = new_cg.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const comp of comps) {
|
||||||
|
if (comp.component_group && comp_groups[comp.component_group.name]) {
|
||||||
|
await _db.component.create({
|
||||||
|
data: {
|
||||||
|
name: comp.name,
|
||||||
|
content_tree: comp.content_tree as any,
|
||||||
|
component_group: {
|
||||||
|
connect: { id: comp_groups[comp.component_group.name] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status: "ok" };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,63 @@
|
||||||
|
import { validate } from "uuid";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
|
import { Loading } from "../../../../../utils/ui/loading";
|
||||||
import { Modal } from "../../../../../utils/ui/modal";
|
import { Modal } from "../../../../../utils/ui/modal";
|
||||||
import { EDGlobal } from "../../../logic/ed-global";
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
import { validate } from "uuid";
|
import { reloadCompPicker } from "./comp-reload";
|
||||||
|
|
||||||
export const EdCompImport = () => {
|
export const EdCompImport = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
const local = useLocal({
|
const local = useLocal(
|
||||||
site_id: "",
|
{
|
||||||
groups: [] as {
|
site_id: "",
|
||||||
name: string;
|
groups: [] as {
|
||||||
id: string;
|
name: string;
|
||||||
comps: { id: string; name: string }[];
|
id: string;
|
||||||
}[],
|
comps: { id: string; name: string }[];
|
||||||
checked: [] as string[],
|
}[],
|
||||||
checked_groups: [] as string[],
|
checked: [] as string[],
|
||||||
status: "init" as "init" | "loading" | "done",
|
checked_groups: [] as string[],
|
||||||
});
|
sites_org: [] as { org: string; sites: { id: string; name: string }[] }[],
|
||||||
|
status: "init" as "init" | "loading" | "done" | "importing",
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
const res = await _db.site.findMany({
|
||||||
|
where: {
|
||||||
|
org: {
|
||||||
|
org_user: { some: { id_user: p.user.id } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
org: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
local.sites_org = [];
|
||||||
|
const org = {} as Record<string, { id: string; name: string }[]>;
|
||||||
|
for (const i of res) {
|
||||||
|
if (i.org) {
|
||||||
|
if (!org[i.org.name]) {
|
||||||
|
org[i.org.name] = [];
|
||||||
|
}
|
||||||
|
if (org[i.org.name]) {
|
||||||
|
org[i.org.name].push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
local.sites_org.push({ org: "-", sites: [{ id: "-", name: "-" }] });
|
||||||
|
for (const [k, v] of Object.entries(org)) {
|
||||||
|
local.sites_org.push({ org: k, sites: v });
|
||||||
|
}
|
||||||
|
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const load = async () => {
|
const load = async () => {
|
||||||
if (!validate(local.site_id)) {
|
if (!validate(local.site_id)) {
|
||||||
|
|
@ -59,6 +101,8 @@ export const EdCompImport = () => {
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local.status = "done";
|
||||||
local.render();
|
local.render();
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
|
@ -81,102 +125,131 @@ export const EdCompImport = () => {
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div>Import from Site ID:</div>
|
<div>Import from Site ID:</div>
|
||||||
<div className="space-x-1 flex">
|
<div className="space-x-1 flex">
|
||||||
<div
|
|
||||||
className="bg-white text-sm border px-2 my-1 flex items-center hover:border-blue-500 hover:bg-blue-50 cursor-pointer"
|
|
||||||
onClick={() => {
|
|
||||||
load();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Load Site
|
|
||||||
</div>
|
|
||||||
{local.checked.length > 0 && (
|
{local.checked.length > 0 && (
|
||||||
<div
|
<div
|
||||||
className="bg-white text-sm border px-2 my-1 flex items-center hover:border-blue-500 hover:bg-blue-50 cursor-pointer"
|
className="bg-white text-sm border px-2 my-1 flex items-center hover:border-blue-500 hover:bg-blue-50 cursor-pointer"
|
||||||
onClick={() => {}}
|
onClick={async () => {
|
||||||
|
if (
|
||||||
|
confirm(`Import ${local.checked.length} component(s) ?`)
|
||||||
|
) {
|
||||||
|
local.status = "importing";
|
||||||
|
local.render();
|
||||||
|
await _api.comp_import({
|
||||||
|
site_id: p.site.id,
|
||||||
|
comps: local.checked,
|
||||||
|
});
|
||||||
|
alert("Import done!");
|
||||||
|
|
||||||
|
local.status = "done";
|
||||||
|
local.render();
|
||||||
|
|
||||||
|
reloadCompPicker(p);
|
||||||
|
}
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Import
|
Import
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<select
|
||||||
type="text"
|
|
||||||
className="border p-1 bg-white"
|
|
||||||
spellCheck={false}
|
|
||||||
value={local.site_id}
|
value={local.site_id}
|
||||||
|
className="border p-1 bg-white border"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
local.site_id = e.currentTarget.value;
|
local.site_id = e.currentTarget.value;
|
||||||
local.render();
|
local.render();
|
||||||
|
load();
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
>
|
||||||
if (e.key === "Enter") {
|
{local.sites_org.map((e) => {
|
||||||
load();
|
return (
|
||||||
}
|
<optgroup key={e.org} label={e.org}>
|
||||||
}}
|
{e.sites.map((i) => {
|
||||||
/>
|
return (
|
||||||
|
<option value={i.id} key={i.id}>
|
||||||
|
{i.name}
|
||||||
|
</option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</optgroup>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
<div className="relative flex overflow-auto flex-1">
|
<div className="relative flex overflow-auto flex-1">
|
||||||
<div className="inset-0 absolute p-2 flex flex-col">
|
{local.status !== "done" && (
|
||||||
{local.groups.map((e) => {
|
<>
|
||||||
return (
|
{local.status === "init" ? (
|
||||||
<div className="flex flex-col" key={e.id}>
|
<div className="flex-1 items-center justify-center flex">
|
||||||
<label className="flex space-x-1">
|
Please choose a site
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={local.checked_groups.includes(e.id)}
|
|
||||||
onChange={() => {
|
|
||||||
let is_checked = false;
|
|
||||||
if (local.checked_groups.includes(e.id)) {
|
|
||||||
local.checked_groups = local.checked_groups.filter(
|
|
||||||
(i) => e.id !== i
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
is_checked = true;
|
|
||||||
local.checked_groups.push(e.id);
|
|
||||||
}
|
|
||||||
for (const item of e.comps) {
|
|
||||||
if (is_checked) {
|
|
||||||
if (!local.checked.includes(item.id)) {
|
|
||||||
local.checked.push(item.id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
local.checked = local.checked.filter(
|
|
||||||
(e) => e !== item.id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
></input>
|
|
||||||
<div>{e.name}</div>
|
|
||||||
</label>
|
|
||||||
<div className="pl-3 flex flex-col">
|
|
||||||
{e.comps.map((f) => {
|
|
||||||
return (
|
|
||||||
<label key={f.id} className="flex space-x-1">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
checked={local.checked.includes(f.id)}
|
|
||||||
onChange={() => {
|
|
||||||
if (local.checked.includes(f.id)) {
|
|
||||||
local.checked = local.checked.filter(
|
|
||||||
(i) => f.id !== i
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
local.checked.push(f.id);
|
|
||||||
}
|
|
||||||
local.render();
|
|
||||||
}}
|
|
||||||
></input>
|
|
||||||
<div>{f.name}</div>
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
) : (
|
||||||
})}
|
<Loading note={local.status} backdrop={false} />
|
||||||
</div>
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{local.status === "done" && (
|
||||||
|
<div className="inset-0 absolute p-2 flex flex-col">
|
||||||
|
{local.groups.map((e) => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col" key={e.id}>
|
||||||
|
<label className="flex space-x-1">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={local.checked_groups.includes(e.id)}
|
||||||
|
onChange={() => {
|
||||||
|
let is_checked = false;
|
||||||
|
if (local.checked_groups.includes(e.id)) {
|
||||||
|
local.checked_groups =
|
||||||
|
local.checked_groups.filter((i) => e.id !== i);
|
||||||
|
} else {
|
||||||
|
is_checked = true;
|
||||||
|
local.checked_groups.push(e.id);
|
||||||
|
}
|
||||||
|
for (const item of e.comps) {
|
||||||
|
if (is_checked) {
|
||||||
|
if (!local.checked.includes(item.id)) {
|
||||||
|
local.checked.push(item.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
local.checked = local.checked.filter(
|
||||||
|
(e) => e !== item.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
></input>
|
||||||
|
<div>{e.name}</div>
|
||||||
|
</label>
|
||||||
|
<div className="pl-3 flex flex-col">
|
||||||
|
{e.comps.map((f) => {
|
||||||
|
return (
|
||||||
|
<label key={f.id} className="flex space-x-1">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={local.checked.includes(f.id)}
|
||||||
|
onChange={() => {
|
||||||
|
if (local.checked.includes(f.id)) {
|
||||||
|
local.checked = local.checked.filter(
|
||||||
|
(i) => f.id !== i
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
local.checked.push(f.id);
|
||||||
|
}
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
></input>
|
||||||
|
<div>{f.name}</div>
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ export const reloadCompPicker = async (p: PG) => {
|
||||||
where: { id_component_group: { in: comp_ids } },
|
where: { id_component_group: { in: comp_ids } },
|
||||||
select: { id: true, id_component_group: true, name: true },
|
select: { id: true, id_component_group: true, name: true },
|
||||||
});
|
});
|
||||||
|
console.log(comps);
|
||||||
|
|
||||||
for (const comp of Object.values(comps)) {
|
for (const comp of Object.values(comps)) {
|
||||||
if (comp.id_component_group) {
|
if (comp.id_component_group) {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export const EdPopSite = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const reload = async () => {
|
const reload = async () => {
|
||||||
|
if (!p.sync) return;
|
||||||
local.status = "loading";
|
local.status = "loading";
|
||||||
local.render();
|
local.render();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue