fix link nav

This commit is contained in:
rizky 2024-07-22 08:06:06 -07:00
parent 8f569e3ea0
commit 58bd986919
4 changed files with 97 additions and 38 deletions

View File

@ -222,6 +222,7 @@ const navigateLink = async (
alert("No URL defined!"); alert("No URL defined!");
return false; return false;
} }
await api._kv("set", vhash, values); await api._kv("set", vhash, values);
const lnk = location.hash.split("#").find((e) => e.startsWith("lnk=")); const lnk = location.hash.split("#").find((e) => e.startsWith("lnk="));
let prev_link = ""; let prev_link = "";

View File

@ -3,6 +3,8 @@ import { FC, ReactNode, useEffect, useLayoutEffect, useState } from "react";
import { loadSession } from "../login/utils/load"; import { loadSession } from "../login/utils/load";
import { useLocal } from "lib/utils/use-local"; import { useLocal } from "lib/utils/use-local";
import { FieldLoading } from "lib/exports"; import { FieldLoading } from "lib/exports";
import { LinkParam } from "lib/comps/form/field/type/TypeLink";
import { hashSum } from "lib/utils/hash-sum";
const w = window as any; const w = window as any;
const initResponsive = function () { const initResponsive = function () {
@ -67,23 +69,87 @@ export const Layout: FC<LYTChild> = (props) => {
const path = getPathname(); const path = getPathname();
const no_layout = props.exception; const no_layout = props.exception;
if (!w.user) { if (!w.prasi_menu && !isEditor) {
local.loading = true; w.prasi_menu = { nav_override: true, nav: w.navigate, pm: null };
loadSession(props.login_url || "/auth/login"); w.navigate = (async (_href, params) => {
if (_href.startsWith("/")) {
const url = new URL(location.href);
const newurl = new URL(`${url.protocol}//${url.host}${_href}`);
const pathname = newurl.pathname;
let link_params = "";
if (params) {
const prefix: LinkParam["prefix"] =
params.breads?.map((e) => {
return { label: e.label, url: e.url || getPathname() };
}) || [];
const values: LinkParam = {
url: getPathname({ hash: false }),
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: () => {} };
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;
} }
if (!isEditor && Array.isArray(no_layout)) { if (
if (no_layout.length) { !isEditor &&
if (no_layout.includes(path)) { Array.isArray(no_layout) &&
return <>{props.blank_layout}</>; no_layout.find((rule) => wildcardMatch(path, rule))
} ) {
return <>{props.blank_layout}</>;
} else {
if (!w.user) {
local.loading = true;
loadSession(props.login_url || "/auth/login");
} }
} }
if (path === props.login_url) return props.blank_layout; if (path === props.login_url) return props.blank_layout;
if (!w.user && !isEditor) if (!w.user && !isEditor)
return ( return (
<div className={cx("c-w-full c-h-full c-flex c-items-center c-justify-center c-flex-1")}> <div
className={cx(
"c-w-full c-h-full c-flex c-items-center c-justify-center c-flex-1"
)}
>
<FieldLoading /> <FieldLoading />
</div> </div>
); );
@ -104,3 +170,11 @@ export const Layout: FC<LYTChild> = (props) => {
</props.PassProp> </props.PassProp>
); );
}; };
function wildcardMatch(str: string, rule: string): boolean {
const escapeRegex = (str: string): string =>
str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
return new RegExp(
"^" + rule.split("*").map(escapeRegex).join(".*") + "$"
).test(str);
}

View File

@ -3,6 +3,8 @@ import { useLocal } from "lib/utils/use-local";
import get from "lodash.get"; import get from "lodash.get";
import { FC, useEffect, useRef } from "react"; import { FC, useEffect, useRef } from "react";
import { IMenu, MenuProp } from "./utils/type-menu"; import { IMenu, MenuProp } from "./utils/type-menu";
import { LinkParam } from "lib/comps/form/field/type/TypeLink";
import { hashSum } from "lib/utils/hash-sum";
// import { icon } from "../../.."; // import { icon } from "../../..";
const local_default = { const local_default = {
@ -60,6 +62,7 @@ const w = window as unknown as {
prasi_menu: { prasi_menu: {
nav_override: boolean; nav_override: boolean;
nav: any; nav: any;
pm: any;
}; };
navigate: any; navigate: any;
}; };
@ -74,37 +77,10 @@ export const SideBar: FC<{
}> = ({ data: _data, local, depth, pm, mode, expanded, parent }) => { }> = ({ data: _data, local, depth, pm, mode, expanded, parent }) => {
const PassProp = pm.PassProp; const PassProp = pm.PassProp;
w.prasi_menu.pm = pm;
const data: IMenu[] = (typeof _data[0] === "string" ? [_data] : _data) as any; const data: IMenu[] = (typeof _data[0] === "string" ? [_data] : _data) as any;
useEffect(() => { useEffect(() => {
if (!w.prasi_menu && !isEditor) {
w.prasi_menu = { nav_override: true, nav: w.navigate };
w.navigate = async (_href: any) => {
if (_href.startsWith("/")) {
const url = new URL(location.href);
const newurl = new URL(`${url.protocol}//${url.host}${_href}`);
const pathname = newurl.pathname;
if (preloaded(pathname)) {
w.prasi_menu.nav(_href);
} else if (pm.on_load) {
let done = { exec: () => {} };
pm.on_load((exec) => {
done.exec = exec;
});
await preload(pathname);
setTimeout(() => {
w.prasi_menu.nav(_href);
done.exec();
}, 500);
} else {
await preload(pathname);
w.prasi_menu.nav(_href);
}
}
};
}
data.map((item) => { data.map((item) => {
const menu = { const menu = {
label: item[0], label: item[0],

10
utils/globals.d.ts vendored
View File

@ -6,5 +6,13 @@ declare var params: any;
declare var cx: any; declare var cx: any;
declare var preload: (urls: string[] | string) => any; declare var preload: (urls: string[] | string) => any;
declare var preloaded: (url: string) => boolean; declare var preloaded: (url: string) => boolean;
declare var navigate: (link: string) => void; declare var navigate: (
url: string,
params?: {
where?: any;
create?: any;
update?: any;
breads?: { label: string; url?: string }[];
}
) => void;
declare var siteurl: (path: string) => string; declare var siteurl: (path: string) => string;