From 58bd98691954d236dd8402ecf07b736313e484b5 Mon Sep 17 00:00:00 2001 From: rizky Date: Mon, 22 Jul 2024 08:06:06 -0700 Subject: [PATCH] fix link nav --- comps/form/field/type/TypeLink.tsx | 1 + preset/menu/Layout.tsx | 92 +++++++++++++++++++++++++++--- preset/menu/Menu.tsx | 32 ++--------- utils/globals.d.ts | 10 +++- 4 files changed, 97 insertions(+), 38 deletions(-) diff --git a/comps/form/field/type/TypeLink.tsx b/comps/form/field/type/TypeLink.tsx index 8904473..f4c1d22 100755 --- a/comps/form/field/type/TypeLink.tsx +++ b/comps/form/field/type/TypeLink.tsx @@ -222,6 +222,7 @@ const navigateLink = async ( alert("No URL defined!"); return false; } + await api._kv("set", vhash, values); const lnk = location.hash.split("#").find((e) => e.startsWith("lnk=")); let prev_link = ""; diff --git a/preset/menu/Layout.tsx b/preset/menu/Layout.tsx index ba3f0e0..2a4e8fd 100755 --- a/preset/menu/Layout.tsx +++ b/preset/menu/Layout.tsx @@ -3,6 +3,8 @@ import { FC, ReactNode, useEffect, useLayoutEffect, useState } from "react"; import { loadSession } from "../login/utils/load"; import { useLocal } from "lib/utils/use-local"; 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 initResponsive = function () { @@ -67,23 +69,87 @@ export const Layout: FC = (props) => { const path = getPathname(); const no_layout = props.exception; - if (!w.user) { - local.loading = true; - loadSession(props.login_url || "/auth/login"); + if (!w.prasi_menu && !isEditor) { + w.prasi_menu = { nav_override: true, nav: w.navigate, pm: null }; + 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 (no_layout.length) { - if (no_layout.includes(path)) { - return <>{props.blank_layout}; - } + if ( + !isEditor && + Array.isArray(no_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 (!w.user && !isEditor) return ( -
+
); @@ -104,3 +170,11 @@ export const Layout: FC = (props) => { ); }; + +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); +} diff --git a/preset/menu/Menu.tsx b/preset/menu/Menu.tsx index 6221039..0844ade 100755 --- a/preset/menu/Menu.tsx +++ b/preset/menu/Menu.tsx @@ -3,6 +3,8 @@ import { useLocal } from "lib/utils/use-local"; import get from "lodash.get"; import { FC, useEffect, useRef } from "react"; 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 "../../.."; const local_default = { @@ -60,6 +62,7 @@ const w = window as unknown as { prasi_menu: { nav_override: boolean; nav: any; + pm: any; }; navigate: any; }; @@ -74,37 +77,10 @@ export const SideBar: FC<{ }> = ({ data: _data, local, depth, pm, mode, expanded, parent }) => { const PassProp = pm.PassProp; + w.prasi_menu.pm = pm; const data: IMenu[] = (typeof _data[0] === "string" ? [_data] : _data) as any; 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) => { const menu = { label: item[0], diff --git a/utils/globals.d.ts b/utils/globals.d.ts index 802b622..02f0d87 100755 --- a/utils/globals.d.ts +++ b/utils/globals.d.ts @@ -6,5 +6,13 @@ declare var params: any; declare var cx: any; declare var preload: (urls: string[] | string) => any; 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;