This commit is contained in:
rizky 2024-08-12 13:50:44 -07:00
parent ad86c97c9a
commit c3fdb700b2
10 changed files with 126 additions and 127 deletions

View File

@ -14,6 +14,8 @@ export const FilterContent: FC<{
_item: PrasiItem;
}> = ({ mode, filter, PassProp, child, _item, onSubmit }) => {
const internal = useLocal({});
return (
<div
className={cx(
@ -101,13 +103,7 @@ export const FilterContent: FC<{
data={filter.data}
on_submit={async (form) => {
if (typeof onSubmit === "function" && mode === "raw") {
const data = await onSubmit(form.fm);
if(typeof form.fm?.data === "object"){
form.fm.data = {
...form.fm.data,
_where: data
}
}
await onSubmit(form.fm);
}
const f = getFilter(filter.name);

View File

@ -15,7 +15,10 @@ export const FilterField: FC<{
type: FilterFieldType;
modifiers?: any[];
}> = ({ filter, name, label, type, modifiers }) => {
const internal = useLocal({ render_timeout: null as any });
const internal = useLocal({
render_timeout: null as any,
search_timeout: null as any,
});
if (!name) return <>No Name</>;
if (!filter.form) return <div>Loading...</div>;
@ -80,20 +83,22 @@ export const FilterField: FC<{
<path d="m21 21-4.3-4.3" />
</svg>
</div>
<FieldTypeInput
{...field}
prop={{
type: "input",
sub_type: "search",
placeholder: field.field.label,
onBlur(e) {
<input
type="search"
placeholder={field.field.label}
onBlur={() => {
clearTimeout(internal.search_timeout);
filter.form?.submit();
},
onChange(val) {
if (!val) {
}}
spellCheck={false}
className="c-flex-1 c-transition-all c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"
onChange={(e) => {
field.fm.data[name] = e.currentTarget.value;
clearTimeout(internal.search_timeout);
internal.search_timeout = setTimeout(() => {
filter.form?.submit();
}
},
}, 1500);
}}
/>
</div>

View File

@ -1,12 +1,12 @@
import { useLocal } from "@/utils/use-local";
import { FC, ReactNode } from "react";
import { createPortal } from "react-dom";
import { FMLocal, GenField } from "../form/typings";
import { FilterContent } from "./FilterContent";
import { getFilter } from "./utils/get-filter";
import { default_filter_local } from "./utils/types";
import { FieldLoading } from "lib/exports";
type FilterMode = "regular" | "inline" | "popup";
type FilterMode = "raw" | "inline";
type FilterProps = {
gen_fields: GenField[];
@ -17,6 +17,7 @@ type FilterProps = {
children?: ReactNode;
onClose?: () => void;
onSubmit?: (fm: FMLocal | null) => Promise<any>;
onLoad?: () => Promise<any>;
PassProp: any;
child: any;
_item: PrasiItem;
@ -33,6 +34,7 @@ export const MasterFilter: FC<FilterProps> = ({
onClose,
_item,
onSubmit,
onLoad,
}): ReactNode => {
const filter = useLocal({ ...default_filter_local });
filter.name = name;
@ -41,55 +43,27 @@ export const MasterFilter: FC<FilterProps> = ({
if (!isEditor) {
const wf = getFilter(name);
if (wf) {
if (wf.filter.ref[_item.id]) {
filter.data = wf.filter.ref[_item.id].data;
} else {
if (mode === "raw" && onLoad) {
if (filter.raw_status === "init") {
filter.raw_status = "loading";
filter.data = onLoad();
filter.raw_status = "ready";
filter.render();
}
if (filter.raw_status !== "ready") {
return <FieldLoading />;
}
}
}
wf.filter.ref[_item.id] = filter;
wf.list.render();
}
}
if (mode === "popup") {
let popup = document.querySelector(".main-content-preview > .portal");
if (!popup) {
popup = document.createElement("div");
popup.classList.add("portal");
const main = document.querySelector(".main-content-preview");
if (main) {
main.appendChild(popup);
}
}
return (
<>
{createPortal(
<div
onClick={onClose}
className={cx(
css`
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: white;
z-index: 100;
`,
"c-flex c-flex-col"
)}
>
<FilterContent
onSubmit={onSubmit}
PassProp={PassProp}
child={child}
mode={mode}
_item={_item}
filter={filter}
/>
</div>,
popup
)}
</>
);
}
return (
<>
<FilterContent

View File

@ -19,6 +19,7 @@ export const default_filter_local = {
types: {} as Record<string, FilterFieldType>,
name: "",
mode: "",
raw_status: "init" as "init" | "loading" | "ready",
};
export const modifiers = {
@ -69,7 +70,7 @@ export const filter_window = window as unknown as {
Record<
string,
{
filter: {ref: Record<string, FilterLocal>, render: () => void;};
filter: { ref: Record<string, FilterLocal>; render: () => void };
list: {
ref: Record<string, { reload: () => void }>;
reload: () => void;
@ -82,4 +83,3 @@ export const filter_window = window as unknown as {
render: () => void;
};
};

View File

@ -0,0 +1,26 @@
export const KeyValue = () => {
return (
<div className="c-flex c-relative c-flex-1">
<table className="c-flex-1">
<tbody>
<tr>
<td>
<input type="text"></input>
</td>
<td>
<input type="text"></input>
</td>
</tr>
<tr>
<td>
<input type="text"></input>
</td>
<td>
<input type="text"></input>
</td>
</tr>
</tbody>
</table>
</div>
);
};

View File

@ -8,6 +8,7 @@ import { FMLocal, FieldLocal, FieldProp } from "../../typings";
import { FieldMoney } from "./TypeMoney";
import { FieldRichText } from "./TypeRichText";
import { FieldUpload } from "./TypeUpload";
import { KeyValue } from "./KeyValue";
export type PropTypeInput = {
type: "input";
@ -27,7 +28,8 @@ export type PropTypeInput = {
| "search"
| "password"
| "import"
| "monthly";
| "monthly"
| "key-value";
placeholder?: string;
onFocus?: (e: FocusEvent<HTMLDivElement>) => void;
onBlur?: (e: FocusEvent<HTMLDivElement>) => void;
@ -212,6 +214,8 @@ export const FieldTypeInput: FC<{
/>
);
}
case "key-value":
return <KeyValue />;
case "monthly": {
return (
<Datepicker

View File

@ -59,28 +59,6 @@ async (arg: {
let where =
(await call_prasi_events("field", "relation_load", [fm, arg.field]) || {}) as Prisma.${table}WhereInput;
if (typeof opt__load_trigger === "object" && typeof opt__load_trigger?.on_change === "function") {
const trigger = await opt__load_trigger.on_change({ md: typeof md !== 'undefined' ? md : undefined, fm, where });
if (trigger.hidden) {
done([]);
arg.field.hidden = true;
arg.field.render();
return;
} else {
if (arg.field.hidden) {
arg.field.hidden = false;
arg.field.render();
}
}
if (trigger.result) {
done(trigger.result);
return;
} else if (trigger.where) {
where = trigger.where;
}
}
let items = await db.${table}.findMany({
select: {
...ext_select,

View File

@ -39,7 +39,10 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
</div>
<div
className={cx(
"c-flex c-items-center c-justify-between c-space-x-2 c-p-3",
"c-flex c-items-center c-space-x-2 c-p-3",
md.props.mode === "full"
? "c-justify-between"
: "c-justify-center",
css`
border-radius: 10px;
margin: 0px -10px -10px -10px;
@ -52,6 +55,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
`
)}
>
{md.props.mode === "full" && (
<Button
variant={"link"}
size={"xs"}
@ -74,6 +78,7 @@ export const formInit = (fm: FMLocal, props: FMProps) => {
<ChevronLeft size={18} />{" "}
<div className="c-px-1">Back To List</div>
</Button>
)}
<Button
variant={"outline"}

View File

@ -708,6 +708,12 @@ export const TableList: FC<TableListProp> = ({
if (columns.length > 1) columns = columns.slice(0, 0 + 1);
}
if (!isEditor) {
let should_toast = true;
if (md && md.props.mode !== "full") {
should_toast = false;
}
if (should_toast) {
if (local.status === "loading") {
toast.dismiss();
toast.loading(
@ -719,6 +725,8 @@ export const TableList: FC<TableListProp> = ({
} else {
toast.dismiss();
}
}
}
if (local.status === "resizing" && !isEditor) {
local.status = "ready";

View File

@ -85,11 +85,14 @@ export const Layout: FC<LYTChild> = (props) => {
if (params) {
const prefix: LinkParam["prefix"] =
params.breads?.map((e) => {
return { label: e.label, url: e.url || getPathname() };
return {
label: e.label,
url: e.url || getPathname({ hash: true }),
};
}) || [];
const values: LinkParam = {
url: getPathname({ hash: false }),
url: getPathname({ hash: true }),
prefix,
hash: "",
create: params.create,