diff --git a/comps/custom/Detail.tsx b/comps/custom/Detail.tsx
index cc41759..8e550de 100755
--- a/comps/custom/Detail.tsx
+++ b/comps/custom/Detail.tsx
@@ -114,6 +114,8 @@ export const Detail: FC<{
if (typeof values !== "object" || values === null) return null;
const entries = Object.entries(values);
+
+ console.log(entries)
return (
{
const local = useLocal({ error: false });
return (
@@ -311,7 +311,7 @@ export const ImgThumb = ({
"img-thumb",
className,
css`
- width: ${w}px;
+ width: ${w}px;
height: ${h}px;
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%),
linear-gradient(135deg, #ccc 25%, transparent 25%),
@@ -329,7 +329,9 @@ export const ImgThumb = ({
local.render();
}}
src={siteurl(
- `/_img/${url.substring("_file/".length)}?w=${w}&h=${h}&fit=${fit || 'cover'}`
+ `/_img/${url.substring("_file/".length)}?w=${w}&h=${h}&fit=${
+ fit || "cover"
+ }`
)}
/>
)}
diff --git a/comps/form/field/type/KeyValue.tsx b/comps/form/field/type/KeyValue.tsx
index 34125f1..e5da000 100755
--- a/comps/form/field/type/KeyValue.tsx
+++ b/comps/form/field/type/KeyValue.tsx
@@ -1,3 +1,4 @@
+import { kvToJSON } from "lib/utils/kv-to-json";
import { useLocal } from "lib/utils/use-local";
import { useEffect, useRef } from "react";
@@ -7,7 +8,7 @@ export const KeyValue = ({
index,
}: {
value: any;
- onChange: (val: any) => void;
+ onChange?: (val: any) => void;
index?: "preserve" | "auto-sort";
}) => {
const local = useLocal({
@@ -48,18 +49,9 @@ export const KeyValue = ({
if (typeof value !== "object") return null;
- const reverseEntries = (input: [string, unknown][]) => {
- return input
- .filter(([k, v]) => {
- return true; // some irrelevant conditions here
- })
- .reduce((accum: any, [k, v]) => {
- accum[k] = v;
- return accum;
- }, {});
- };
+ console.log(value);
return (
-
+
{
e.stopPropagation();
@@ -67,6 +59,10 @@ export const KeyValue = ({
}}
className={cx(
"c-flex-1",
+ !onChange &&
+ css`
+ border: 1px solid #ececeb;
+ `,
css`
input {
width: 100%;
@@ -88,54 +84,60 @@ export const KeyValue = ({
key={idx}
item={item}
idx={idx}
- update={(idx, k, v) => {
- local.entries[idx] = [k, v];
+ update={
+ onChange
+ ? (idx, k, v) => {
+ local.entries[idx] = [k, v];
- if (k === "" && v === "") {
- local.entries.splice(idx, 1);
- }
+ if (k === "" && v === "") {
+ local.entries.splice(idx, 1);
+ }
- local.render();
- }}
+ local.render();
+ }
+ : undefined
+ }
onBlur={() => {
if (index === "preserve") {
- onChange([...local.entries]);
+ onChange?.([...local.entries]);
} else {
- onChange(reverseEntries(local.entries));
+ onChange?.(kvToJSON(local.entries));
}
}}
/>
))}
- {
- local.new.key = k;
- local.new.value = v;
- local.render();
- }}
- onBlur={(field, val) => {
- if (field === "key" && val) {
- const idx = local.entries.length;
- local.entries[idx] = [local.new.key, local.new.value];
- local.new.key = "";
- local.new.value = "";
+ {onChange && (
+ {
+ local.new.key = k;
+ local.new.value = v;
local.render();
- if (index === "preserve") {
- onChange([...local.entries]);
- } else {
- onChange(reverseEntries(local.entries));
+ }}
+ onBlur={(field, val) => {
+ if (field === "key" && val) {
+ const idx = local.entries.length;
+ local.entries[idx] = [local.new.key, local.new.value];
+ local.new.key = "";
+ local.new.value = "";
+ local.render();
+ if (index === "preserve") {
+ onChange?.([...local.entries]);
+ } else {
+ onChange?.(kvToJSON(local.entries));
+ }
+ setTimeout(() => {
+ (
+ ref?.current?.querySelector(
+ `.kv-row-${idx} .kv-value input`
+ ) as HTMLInputElement
+ )?.focus();
+ }, 10);
}
- setTimeout(() => {
- (
- ref?.current?.querySelector(
- `.kv-row-${idx} .kv-value input`
- ) as HTMLInputElement
- )?.focus();
- }, 10);
- }
- }}
- />
+ }}
+ />
+ )}
@@ -150,7 +152,7 @@ const KVRow = ({
}: {
item: [string, unknown];
idx: number;
- update: (idx: number, key: string, value: string) => void;
+ update?: (idx: number, key: string, value: string) => void;
onBlur?: (field: "key" | "value", val: string) => void;
}) => {
const [k, v] = item as any;
@@ -172,22 +174,26 @@ const KVRow = ({
`
)}
>
-
{
- update(idx, e.currentTarget.value, v || "");
- }}
- onBlur={
- onBlur
- ? (e) => {
- onBlur("key", e.currentTarget.value);
- }
- : undefined
- }
- ref={keyref}
- >
+ {update ? (
+
{
+ update(idx, e.currentTarget.value, v || "");
+ }}
+ onBlur={
+ onBlur
+ ? (e) => {
+ onBlur("key", e.currentTarget.value);
+ }
+ : undefined
+ }
+ ref={keyref}
+ >
+ ) : (
+ k
+ )}
- {
- update(idx, k, e.currentTarget.value || "");
- }}
- onKeyUp={(e) => {
- if (e.key === "Backspace" && !e.currentTarget.value) {
- keyref.current?.focus();
+ {update ? (
+ {
+ update(idx, k, e.currentTarget.value || "");
+ }}
+ onKeyUp={(e) => {
+ if (e.key === "Backspace" && !e.currentTarget.value) {
+ keyref.current?.focus();
+ }
+ }}
+ onBlur={
+ onBlur
+ ? (e) => {
+ onBlur("value", e.currentTarget.value);
+ }
+ : undefined
}
- }}
- onBlur={
- onBlur
- ? (e) => {
- onBlur("value", e.currentTarget.value);
- }
- : undefined
- }
- ref={valref}
- >
+ ref={valref}
+ >
+ ) : (
+ v
+ )}
|
);
diff --git a/comps/form/field/type/TypeMoney.tsx b/comps/form/field/type/TypeMoney.tsx
index ba9b1eb..597e69e 100755
--- a/comps/form/field/type/TypeMoney.tsx
+++ b/comps/form/field/type/TypeMoney.tsx
@@ -129,7 +129,7 @@ const formatCurrency = (value: any) => {
return (isNegative ? "-" : "") + rupiah;
}
};
-export const formatMoney = (res: number) => {
+export const formatMoney = (res: any) => {
const formattedAmount = new Intl.NumberFormat("id-ID", {
minimumFractionDigits: 0,
}).format(res);
diff --git a/comps/list/TLSlider.tsx b/comps/list/TLSlider.tsx
index 2eeed3f..a122bad 100755
--- a/comps/list/TLSlider.tsx
+++ b/comps/list/TLSlider.tsx
@@ -81,7 +81,7 @@ export const TLSlider: FC<{
})}
) : (
-
+
No Data
diff --git a/comps/list/TableList.tsx b/comps/list/TableList.tsx
index 5d912bc..bffe9fc 100755
--- a/comps/list/TableList.tsx
+++ b/comps/list/TableList.tsx
@@ -39,6 +39,7 @@ import { sortTree } from "./utils/sort-tree";
import { TLList } from "./TLList";
import { OnRowClick } from "./utils/type";
import { TLSlider } from "./TLSlider";
+import { getPathname } from "lib/exports";
let EMPTY_SET = new Set() as ReadonlySet
;
@@ -253,6 +254,7 @@ export const TableList: FC = ({
skip: local.paging.skip,
},
};
+
if (id_parent) {
load_args.paging = {};
}
@@ -261,7 +263,8 @@ export const TableList: FC = ({
if (
id_parent ||
!local.paging ||
- (local.paging && !local.paging.take)
+ (local.paging && !local.paging.take) ||
+ local.paging.skip === 0
) {
local.data = data;
} else {
diff --git a/exports.tsx b/exports.tsx
index e84d3f0..5237448 100755
--- a/exports.tsx
+++ b/exports.tsx
@@ -95,18 +95,23 @@ export const ScrollArea = lazify(
async () => (await import("@/comps/ui/scroll-area")).ScrollArea
);
+export const KeyValue = lazify(
+ async () => (await import("@/comps/form/field/type/KeyValue")).KeyValue
+);
+
export { fetchLinkParams } from "@/comps/form/field/type/TypeLink";
-export { FieldLoading } from "@/comps/ui/field-loading";
+export { FieldLoading, Spinner } from "@/comps/ui/field-loading";
export { lang } from "lib/lang";
export { prasi_gen } from "./gen/prasi_gen";
export { guessLabel } from "./utils/guess-label";
-
import __get from "lodash.get";
import { sum } from "./utils/sum";
+export { kvToJSON } from "./utils/kv-to-json";
+export { overrideNav } from "./utils/override-nav";
export const _sum = sum;
export const _get = __get;
-
+
/** Generator */
export { generateFilter as genereteFilter } from "@/comps/filter/gen/gen-filter";
export { generateRelation } from "@/comps/form/gen/gen-rel";
@@ -126,14 +131,14 @@ export {
fieldType,
FieldTypeCustom,
FMLocal,
- formType
+ formType,
} from "@/comps/form/typings";
export { TableListType } from "@/comps/list/utils/typings";
export { generateTableList as generateTableList } from "@/comps/md/gen/gen-table-list";
export { generateSelect } from "@/comps/md/gen/md-select";
export { MasterDetailType } from "@/comps/md/utils/typings";
export { Button, FloatButton } from "@/comps/ui/button";
-export { baseurl } from "@/utils/baseurl";
+export { baseurl, imgThumb } from "@/utils/baseurl";
export { FormatValue } from "@/utils/format-value";
export { GetValue } from "@/utils/get-value";
export { password } from "@/utils/password";
@@ -146,7 +151,7 @@ export { logout } from "@/preset/login/utils/logout";
export {
registerSession,
RG,
- UserSession
+ UserSession,
} from "@/preset/login/utils/register";
export { Card } from "@/comps/custom/Card";
diff --git a/preset/menu/Layout.tsx b/preset/menu/Layout.tsx
index bab8bf1..60f691e 100755
--- a/preset/menu/Layout.tsx
+++ b/preset/menu/Layout.tsx
@@ -5,6 +5,7 @@ import { getPathname } from "lib/utils/pathname";
import { useLocal } from "lib/utils/use-local";
import { FC, ReactNode, useLayoutEffect } from "react";
import { loadSession } from "../login/utils/load";
+import { overrideNav } from "lib/utils/override-nav";
const w = window as any;
const initResponsive = function () {
@@ -69,75 +70,7 @@ export const Layout: FC = (props) => {
const path = getPathname();
const no_layout = props.exception;
- if (!w.prasi_menu && !isEditor) {
- w.prasi_menu = { nav_override: true, nav: w.navigate, pm: null };
- w.navigate = (async (_href, params) => {
- if (!_href) {
- console.error("Failed to navigate, empty url");
- return;
- }
- if (_href.startsWith("/")) {
- const url = new URL(location.href);
- const newurl = new URL(`${url.protocol}//${url.host}${_href}`);
- const pathname = newurl.pathname;
-
- _href = baseurl(_href);
- if (params) {
- const prefix: LinkParam["prefix"] =
- params.breads?.map((e) => {
- return {
- label: e.label,
- url: e.url || getPathname({ hash: true }),
- };
- }) || [];
-
- const values: LinkParam = {
- name: params.name,
- url: getPathname({ hash: true }),
- prefix,
- hash: "",
- create: params.create,
- update: params.update,
- where: params.where,
- };
-
- const vhash = hashSum(values);
- values.hash = vhash;
-
- await api._kv("set", vhash, values);
-
- const lnk = location.hash
- .split("#")
- .find((e) => e.startsWith("lnk="));
- let prev_link = "";
- if (lnk) {
- prev_link = lnk.split("=").pop() || "";
- if (prev_link) prev_link = prev_link + "+";
- }
- _href = `${_href}#lnk=${prev_link + vhash}`;
- }
-
- if (preloaded(pathname)) {
- w.prasi_menu.nav(_href);
- } else if (w.prasi_menu.pm?.on_load) {
- let done = { exec: () => {} };
- local.loading = true;
- local.render();
- w.prasi_menu.pm?.on_load((exec: any) => {
- done.exec = exec;
- });
- await preload(pathname);
- setTimeout(() => {
- w.prasi_menu.nav(_href);
- done.exec();
- }, 500);
- } else {
- await preload(pathname);
- w.prasi_menu.nav(_href);
- }
- }
- }) as typeof navigate;
- }
+ overrideNav({ local });
if (
!isEditor &&
diff --git a/utils/baseurl.ts b/utils/baseurl.ts
index 039133c..178a835 100755
--- a/utils/baseurl.ts
+++ b/utils/baseurl.ts
@@ -6,3 +6,21 @@ export const baseurl = (url: string) => {
}
return url;
};
+
+export const imgThumb = ({
+ url,
+ w,
+ h,
+ fit,
+}: {
+ url: string;
+ w: number;
+ h: number;
+ fit?: "cover" | "contain" | "inside" | "fill" | "outside";
+}) => {
+ return siteurl(
+ `/_img/${url.substring("_file/".length)}?w=${w}&h=${h}&fit=${
+ fit || "cover"
+ }`
+ );
+};
diff --git a/utils/init.ts b/utils/init.ts
index de1db81..c62d4a6 100755
--- a/utils/init.ts
+++ b/utils/init.ts
@@ -1,3 +1,4 @@
+
const w = window as any;
if (typeof isEditor === "undefined") {
if (
@@ -5,7 +6,7 @@ if (typeof isEditor === "undefined") {
location.pathname.startsWith("/ed")
) {
w.isEditor = true;
- } else {
+ } else {
w.isEditor = false;
}
}
diff --git a/utils/kv-to-json.ts b/utils/kv-to-json.ts
new file mode 100755
index 0000000..a51aced
--- /dev/null
+++ b/utils/kv-to-json.ts
@@ -0,0 +1,10 @@
+export const kvToJSON = (input: [string, unknown][]) => {
+ return input
+ .filter(([k, v]) => {
+ return true; // some irrelevant conditions here
+ })
+ .reduce((accum: any, [k, v]) => {
+ accum[k] = v;
+ return accum;
+ }, {}) as Record;
+};
diff --git a/utils/override-nav.ts b/utils/override-nav.ts
new file mode 100755
index 0000000..b384b2a
--- /dev/null
+++ b/utils/override-nav.ts
@@ -0,0 +1,79 @@
+import { LinkParam } from "lib/comps/form/field/type/TypeLink";
+import { hashSum } from "lib/utils/hash-sum";
+import { getPathname } from "lib/utils/pathname";
+
+const w = window as any;
+
+export const overrideNav = (arg?: { local?: any }) => {
+ if (!w.prasi_menu && !isEditor) {
+ w.prasi_menu = { nav_override: true, nav: w.navigate, pm: null };
+ w.navigate = (async (_href, params) => {
+ if (!_href) {
+ console.error("Failed to navigate, empty url");
+ return;
+ }
+ if (_href.startsWith("/")) {
+ const url = new URL(location.href);
+ const newurl = new URL(`${url.protocol}//${url.host}${_href}`);
+ const pathname = newurl.pathname;
+
+ _href = baseurl(_href);
+ if (params) {
+ const prefix: LinkParam["prefix"] =
+ params.breads?.map((e) => {
+ return {
+ label: e.label,
+ url: e.url || getPathname({ hash: true }),
+ };
+ }) || [];
+
+ const values: LinkParam = {
+ name: params.name,
+ url: getPathname({ hash: true }),
+ prefix,
+ hash: "",
+ create: params.create,
+ update: params.update,
+ where: params.where,
+ };
+
+ const vhash = hashSum(values);
+ values.hash = vhash;
+
+ await api._kv("set", vhash, values);
+
+ const lnk = location.hash
+ .split("#")
+ .find((e) => e.startsWith("lnk="));
+ let prev_link = "";
+ if (lnk) {
+ prev_link = lnk.split("=").pop() || "";
+ if (prev_link) prev_link = prev_link + "+";
+ }
+ _href = `${_href}#lnk=${prev_link + vhash}`;
+ }
+
+ if (preloaded(pathname)) {
+ w.prasi_menu.nav(_href);
+ } else if (w.prasi_menu.pm?.on_load) {
+ let done = { exec: () => {} };
+ if (arg?.local) {
+ arg.local.loading = true;
+ arg.local.render();
+ }
+ w.prasi_menu.pm?.on_load((exec: any) => {
+ done.exec = exec;
+ });
+ await preload(pathname);
+ setTimeout(() => {
+ w.prasi_menu.nav(_href);
+ done.exec();
+ }, 500);
+ } else {
+ await preload(pathname);
+ w.prasi_menu.nav(_href);
+ }
+ }
+ }) as typeof navigate;
+ }
+};