From 4729203d47c5020bdd9ffd1c8edff5361a66b9bd Mon Sep 17 00:00:00 2001 From: dswbx Date: Mon, 9 Jun 2025 07:21:32 +0200 Subject: [PATCH] fix useSearch and admin path registration --- app/src/data/schema/SchemaManager.ts | 2 +- app/src/modules/server/AdminController.tsx | 11 +++-- app/src/ui/hooks/use-search.ts | 40 ++++++++++--------- app/src/ui/routes/data/data.$entity.index.tsx | 9 ++--- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/app/src/data/schema/SchemaManager.ts b/app/src/data/schema/SchemaManager.ts index 42c071d..b991c67 100644 --- a/app/src/data/schema/SchemaManager.ts +++ b/app/src/data/schema/SchemaManager.ts @@ -333,7 +333,7 @@ export class SchemaManager { if (config.force) { try { - $console.info("[SchemaManager]", sql, parameters); + $console.log("[SchemaManager]", sql); await qb.execute(); } catch (e) { throw new Error(`Failed to execute query: ${sql}: ${(e as any).message}`); diff --git a/app/src/modules/server/AdminController.tsx b/app/src/modules/server/AdminController.tsx index a39826b..af933ee 100644 --- a/app/src/modules/server/AdminController.tsx +++ b/app/src/modules/server/AdminController.tsx @@ -50,7 +50,7 @@ export class AdminController extends Controller { } get basepath() { - return this.options.adminBasepath ?? "/"; + return this.options.basepath ?? "/"; } private withBasePath(route: string = "") { @@ -93,10 +93,13 @@ export class AdminController extends Controller { path, permission(SystemPermissions.accessAdmin, { onDenied: async (c) => { - addFlashMessage(c, "You are not authorized to access the Admin UI", "error"); + if (!path.startsWith("/auth")) { + addFlashMessage(c, "You are not authorized to access the Admin UI", "error"); - $console.log("redirecting"); - return c.redirect(authRoutes.login); + $console.log("redirecting", authRoutes.login); + return c.redirect(authRoutes.login); + } + return; }, }), permission(SystemPermissions.schemaRead, { diff --git a/app/src/ui/hooks/use-search.ts b/app/src/ui/hooks/use-search.ts index 08e118d..a47e310 100644 --- a/app/src/ui/hooks/use-search.ts +++ b/app/src/ui/hooks/use-search.ts @@ -1,4 +1,4 @@ -import { decodeSearch, encodeSearch, parseDecode } from "core/utils"; +import { decodeSearch, encodeSearch, mergeObject, parseDecode } from "core/utils"; import { isEqual, transform } from "lodash-es"; import { useLocation, useSearch as useWouterSearch } from "wouter"; import { type s, parse } from "core/object/schema"; @@ -16,23 +16,16 @@ export function useSearch( clone: true, }) as s.StaticCoerced; - // @todo: add option to set multiple keys at once - function set>( - key: Key, - value: s.StaticCoerced[Key], - ): void { - //console.log("set", key, value); - const update = parse(schema, { ...decodeSearch(searchString), [key]: value }); - const search = transform( - update as any, - (result, value, key) => { - if (defaultValue && isEqual(value, defaultValue[key])) return; - result[key] = value; - }, - {} as s.StaticCoerced, - ); - const encoded = encodeSearch(search, { encode: false }); - navigate(location + (encoded.length > 0 ? "?" + encoded : "")); + // @ts-ignore + const _defaults = mergeObject(schema.template({ withOptional: true }), defaultValue ?? {}); + + function set>>(update: Update): void { + // @ts-ignore + if (schema.validate(update).valid) { + const search = getWithoutDefaults(mergeObject(value, update), _defaults); + const encoded = encodeSearch(search, { encode: false }); + navigate(location + (encoded.length > 0 ? "?" + encoded : "")); + } } return { @@ -40,3 +33,14 @@ export function useSearch( set, }; } + +function getWithoutDefaults(value: object, defaultValue: object) { + return transform( + value as any, + (result, value, key) => { + if (defaultValue && isEqual(value, defaultValue[key])) return; + result[key] = value; + }, + {} as object, + ); +} diff --git a/app/src/ui/routes/data/data.$entity.index.tsx b/app/src/ui/routes/data/data.$entity.index.tsx index e71452d..ee9befc 100644 --- a/app/src/ui/routes/data/data.$entity.index.tsx +++ b/app/src/ui/routes/data/data.$entity.index.tsx @@ -23,7 +23,7 @@ const searchSchema = s.partialObject({ perPage: s.number({ default: 10 }).optional(), }); -const PER_PAGE_OPTIONS = [5, 10, 25]; +const PER_PAGE_OPTIONS = [5, 10, 25, 50, 100]; export function DataEntityList({ params }) { const { $data } = useBkndData(); @@ -61,19 +61,18 @@ export function DataEntityList({ params }) { } function handleClickPage(page: number) { - search.set("page", page); + search.set({ page }); } function handleSortClick(name: string) { const sort = search.value.sort!; const newSort = { by: name, dir: sort.by === name && sort.dir === "asc" ? "desc" : "asc" }; - search.set("sort", newSort as any); + search.set({ sort: newSort as any }); } function handleClickPerPage(perPage: number) { - // @todo: also reset page to 1 - search.set("perPage", perPage); + search.set({ perPage, page: 1 }); } const isUpdating = $q.isLoading || $q.isValidating;