wip import component

This commit is contained in:
Rizky 2024-02-14 14:46:34 +07:00
parent 07b12dc636
commit 5e2f3b1897
5 changed files with 239 additions and 95 deletions

View File

@ -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" };
}, },
}; };

View File

@ -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>

View File

@ -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) {

View File

@ -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();