This commit is contained in:
Rizky 2023-11-18 12:34:04 +07:00
parent 82516adf10
commit 7a1cb39b32
7 changed files with 274 additions and 13 deletions

View File

@ -26,7 +26,6 @@ export const Code = {
};
export const startCodeWatcher = async (code: DBCode) => {
console.log(code)
if (code.id && Code.watchers[code.id]) {
return;
}
@ -79,7 +78,7 @@ export const startCodeWatcher = async (code: DBCode) => {
clearTimeout(Code.timeout[code.id]);
Code.timeout[code.id] = setTimeout(() => {
codeBuild(code);
}, 1000);
}, 100);
}
if (path) {

View File

@ -117,6 +117,7 @@ export const EDGlobal = {
name: "site",
log: "",
loading: false,
error: false,
show_log: false,
list: {} as Record<string, string>,
},

View File

@ -63,13 +63,20 @@ export const edInitSync = (p: PG) => {
page_id: params.page_id,
events: {
code(arg) {
p.ui.popup.code.error = false;
if (arg.event === "code-loading") {
p.ui.popup.code.log = "";
p.ui.popup.code.loading = true;
p.render();
} else if (arg.event === "code-done") {
if (typeof arg.content === "string")
if (typeof arg.content === "string") {
if (arg.content !== "OK") {
p.ui.popup.code.error = true;
}
p.ui.popup.code.log += arg.content;
}
p.ui.popup.code.loading = false;
p.render();
} else {

View File

@ -1,5 +1,207 @@
import { FC } from "react";
import { FC, ReactNode } from "react";
import { useGlobal, useLocal } from "web-utils";
import { EDGlobal } from "../../../logic/ed-global";
import { Popover } from "../../../../../utils/ui/popover";
import { fuzzy } from "../../../../../utils/ui/fuzzy";
export const CodeAssign: FC<{ id_code: string }> = () => {
return <div>mantap</div>;
const assign = {
loading: true,
list: [] as Awaited<ReturnType<typeof getAssign>>,
render: () => {},
};
export const CodeAssign: FC<{ id_code: string; onClose: () => void }> = ({
onClose,
id_code,
}) => {
const local = useLocal({}, async () => {
assign.list = await getAssign(id_code);
assign.loading = false;
assign.render();
});
assign.render = local.render;
return (
<div className={"flex items-stretch"}>
<AssignList id_code={id_code} mode="page" />
<div className="border-r"></div>
<AssignList id_code={id_code} mode="comp" />
</div>
);
};
const AssignList: FC<{ id_code: string; mode: "page" | "comp" }> = ({
id_code,
mode,
}) => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal(
{
search: "",
list: [] as { id: string; name: string; url?: string }[],
popover: false,
loading: true,
},
async () => {
if (mode === "page") {
const list = await db.page.findMany({
where: {
id_site: p.site.id,
is_deleted: false,
},
select: {
name: true,
id: true,
url: true,
},
});
local.list = list.map((e) => ({
id: e.id,
name: e.name,
url: e.url,
}));
} else {
const list = await db.component_site.findMany({
where: {
id_site: p.site.id,
},
select: {
component_group: { select: { id: true, name: true } },
},
});
local.list = list.map((e) => ({
id: e.component_group.id,
name: e.component_group.name,
}));
}
local.loading = false;
local.render();
}
);
const filtered = fuzzy(
local.list,
mode === "page" ? { pk: "id", search: ["name", "url"] } : "name",
local.search
);
return (
<div className="flex flex-col min-w-[300px] min-h-[100px] items-stretch">
<Popover
open={local.popover}
onOpenChange={(open) => {
local.popover = open;
local.render();
}}
arrow={false}
backdrop={false}
popoverClassName={cx(
"p-0 shadow-lg border border-blue-500 bg-white",
css`
top: -7px !important;
`
)}
content={
<div className="flex flex-col min-w-[300px] min-h-[50px] max-h-[300px] overflow-auto items-stretch">
{local.loading && (
<div className="flex flex-1 items-center justify-center">
Loading...
</div>
)}
{!local.loading &&
filtered.map((e) => {
let label: any = e.name;
if (mode === "page") {
label = (
<div className="flex flex-1 justify-between">
<div>{e.name}</div>
<div className="text-slate-500 text-sm pl-10">
{e.url}
</div>
</div>
);
}
return (
<div
className={
"border-b p-1 flex flex-col items-stretch hover:bg-blue-100 cursor-pointer"
}
key={e.id}
>
{label}
</div>
);
})}
</div>
}
>
<div className="border-b flex">
<input
type="text"
value={local.search}
onChange={(e) => {
local.search = e.currentTarget.value;
local.render();
}}
spellCheck={false}
placeholder={`Search ${
mode === "page" ? "Page" : "Component Group"
}...`}
className="flex flex-1 outline-none p-1 text-sm focus:border-blue-500 border border-transparent"
/>
</div>
</Popover>
<div className=""></div>
</div>
);
};
const getAssign = async (id_code: string) => {
return await db.code_assign.findMany({
where: {
id_code: { equals: id_code },
},
});
};
const selectStyle = css`
flex: 1;
.sel__control {
border: 0px;
border-radius: 0px;
outline: none;
min-height: 29px;
border-left: 1px solid #ececeb;
border-right: 1px solid #ececeb;
}
.sel__control--is-focused {
box-shadow: none !important;
border-bottom: 1px solid blue;
}
.sel__menu {
border-radius: 0px;
background: white;
border: 1px solid #ececeb;
}
.sel__value-container {
padding-left: 5px;
}
.sel__option {
padding: 2px 5px;
border-bottom: 1px solid #ececeb;
}
.sel__option--is-selected,
.sel__option--is-focused {
background: #e0e9fa;
}
.sel__indicator {
width: 15px;
opacity: 0.7;
}
.sel__placeholder {
color: #ccc;
}
`;

View File

@ -18,7 +18,7 @@ import { CodeNameItem, CodeNameList, codeName } from "./name-list";
export const EdPopCode = () => {
const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ namePicker: false });
const local = useLocal({ namePicker: false, codeAssign: false });
useEffect(() => {
(async () => {
@ -77,7 +77,6 @@ export const EdPopCode = () => {
name: p.ui.popup.code.name,
});
console.log(id_code);
if (id_code) {
p.ui.popup.code.id = id_code;
p.render();
@ -116,7 +115,7 @@ export const EdPopCode = () => {
onClick={async () => {
if (
prompt(
"Are you sure want to delete this code?\n type 'yes' to confirm:"
"Are you sure want to delete this code?\ntype 'yes' to confirm:"
) === "yes"
) {
await db.code.delete({
@ -140,7 +139,23 @@ export const EdPopCode = () => {
></div>
</Tooltip>
<Popover
content={<CodeAssign id_code={p.ui.popup.code.name} />}
open={local.codeAssign}
onOpenChange={(open) => {
local.codeAssign = open;
local.render();
}}
backdrop={false}
placement="bottom"
popoverClassName="p-0 shadow-lg bg-white"
content={
<CodeAssign
onClose={() => {
local.codeAssign = false;
local.render();
}}
id_code={p.ui.popup.code.id}
/>
}
className="flex items-center border-l relative border-l hover:bg-blue-50 cursor-pointer px-2 transition-all"
>
<div
@ -155,7 +170,10 @@ export const EdPopCode = () => {
content="STDOUT Log"
delay={0}
placement="bottom"
className="flex items-stretch relative border-l"
className={cx(
"flex items-stretch relative border-l",
p.ui.popup.code.error && "bg-red-500 text-white"
)}
onClick={() => {
p.ui.popup.code.show_log = !p.ui.popup.code.show_log;
p.render();
@ -199,11 +217,12 @@ export const EdPopCode = () => {
)}
</div>
{local.namePicker && (
{(local.namePicker || local.codeAssign) && (
<div
className="absolute inset-0"
className="fixed inset-0 z-50"
onClick={() => {
local.namePicker = false;
local.codeAssign = false;
local.render();
}}
></div>

View File

@ -93,6 +93,7 @@ export const CodeNameList: FC<{
spellCheck={false}
onBlur={async (e) => {
local.newopen = false;
local.render();
const nc = await db.code.create({
data: {

View File

@ -2,6 +2,38 @@ import uFuzzy from "@leeoniya/ufuzzy";
const uf = new uFuzzy({});
export const fuzzy = <T extends object>(
array: T[],
field: keyof T | { pk: keyof T; search: (keyof T)[] },
search: string
) => {
if (typeof field === "string") {
return fuzzySingle(array, field, search);
}
const result: Record<any, { row: any; idx: number }> = {};
if (typeof field === "object") {
for (const f of field.search) {
const res = fuzzySingle(array, f, search);
let idx = 0;
for (const row of res) {
idx++;
const id = row[field.pk] as any;
if (!result[id]) {
result[id] = { idx, row };
} else {
result[id].row[f] = row[f];
}
}
}
}
const final: any = {};
for (const i of Object.values(result)) {
final[i.idx] = i.row;
}
return Object.values(final) as T[];
};
const fuzzySingle = <T extends object>(
array: T[],
field: keyof T,
search: string