Skip to content

Commit

Permalink
fix: correctly display path in advanced search (#442)
Browse files Browse the repository at this point in the history
* fix: correctly display path in advanced search

* fix display path

* decrease dialog radius

* use translated names in dropdown trigger
  • Loading branch information
foyarash authored Sep 30, 2024
1 parent 84ae5d6 commit 003805d
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/breezy-cups-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@premieroctet/next-admin": patch
---

fix: correctly display path in advanced search
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
UIQueryBlock,
} from "../../utils/advancedSearch";
import { useConfig } from "../../context/ConfigContext";
import { useI18n } from "../../context/I18nContext";

type Props = {
property: string;
Expand All @@ -29,6 +30,7 @@ const AdvancedSearchDropdownItem = ({
displayPath,
}: Props) => {
const { options } = useConfig();
const { t } = useI18n();
const schemaDef = schema.definitions[resource];
const schemaProperty =
schemaDef.properties[property as keyof typeof schemaDef.properties];
Expand Down Expand Up @@ -66,8 +68,11 @@ const AdvancedSearchDropdownItem = ({
}, [hasChildren, schemaProperty, schema]);

const aliases = options?.model?.[resource]?.aliases;
const displayedProperty =
aliases?.[property as keyof typeof aliases] ?? property;
const displayedProperty = t(
`model.${resource}.fields.${property}`,
{},
aliases?.[property as keyof typeof aliases] ?? property
);

const onClick = (evt: MouseEvent<HTMLDivElement>) => {
if (hasChildren) {
Expand Down
4 changes: 2 additions & 2 deletions packages/next-admin/src/components/radix/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const DialogOverlay = forwardRef<
<Dialog.Overlay
className={twMerge(
clsx(
"bg-zinc-950/25 dark:bg-zinc-950/50 fixed inset-0 z-[51]",
"fixed inset-0 z-[51] bg-zinc-950/25 dark:bg-zinc-950/50",
className
)
)}
Expand All @@ -33,7 +33,7 @@ export const DialogContent = forwardRef<
<Dialog.Content
className={twMerge(
clsx(
"text-nextadmin-content-emphasis dark:text-dark-nextadmin-content-emphasis border-nextadmin-border-strong dark:border-dark-nextadmin-border-strong bg-nextadmin-background-default dark:bg-dark-nextadmin-background-default fixed top-[50%] z-[52] w-full translate-y-[-50%] border p-6 md:left-[50%] md:w-[50vw] md:translate-x-[-50%] bg-white shadow-lg rounded-2xl",
"text-nextadmin-content-emphasis dark:text-dark-nextadmin-content-emphasis border-nextadmin-border-strong dark:border-dark-nextadmin-border-strong bg-nextadmin-background-default dark:bg-dark-nextadmin-background-default fixed top-[50%] z-[52] w-full translate-y-[-50%] rounded-lg border bg-white p-6 shadow-lg md:left-[50%] md:w-[50vw] md:translate-x-[-50%]",
className
)
)}
Expand Down
14 changes: 8 additions & 6 deletions packages/next-admin/src/context/I18nContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ type Props = {
translations: Translations;
};

export type TranslationFn = (
key: string,
options?: { [key: string]: any },
fallback?: string
) => string;

const I18nContext = createContext<{
t: (
key: string,
options?: { [key: string]: any },
fallback?: string
) => string;
t: TranslationFn;
}>({
t: () => "",
});
Expand All @@ -20,7 +22,7 @@ export const I18nProvider = ({
translations,
children,
}: PropsWithChildren<Props>) => {
const t = (
const t: TranslationFn = (
key: string,
options?: { [key: string]: any },
fallback?: string
Expand Down
11 changes: 10 additions & 1 deletion packages/next-admin/src/hooks/useAdvancedSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
} from "../utils/advancedSearch";
import { useRouterInternal } from "./useRouterInternal";
import { ModelName, Schema } from "../types";
import { useConfig } from "../context/ConfigContext";
import { useI18n } from "../context/I18nContext";

type UseAdvancedSearchParams<M extends ModelName> = {
resource: M;
Expand All @@ -17,6 +19,8 @@ const useAdvancedSearch = <M extends ModelName>({
schema,
}: UseAdvancedSearchParams<M>) => {
const { router, query } = useRouterInternal();
const { options } = useConfig();
const { t } = useI18n();
const [uiBlocks, setUiBlocks] = useState(() => {
if (query.q) {
const blocks = validateQuery(query.q);
Expand All @@ -25,7 +29,12 @@ const useAdvancedSearch = <M extends ModelName>({
return null;
}

return buildUIBlocks(blocks, { resource, schema });
return buildUIBlocks(blocks, {
resource,
schema,
options: options?.model,
t,
});
}
});

Expand Down
13 changes: 13 additions & 0 deletions packages/next-admin/src/utils/advancedSearch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[0]",
nullable: true,
displayPath: "test",
},
{
type: "filter",
Expand All @@ -164,6 +165,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[1]",
nullable: true,
displayPath: "test",
},
{
type: "filter",
Expand All @@ -175,6 +177,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[2]",
nullable: true,
displayPath: "test",
},
{
type: "filter",
Expand All @@ -186,6 +189,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[3]",
nullable: false,
displayPath: "test2",
},
{
type: "filter",
Expand All @@ -197,6 +201,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[4]",
nullable: false,
displayPath: "test5 → test6",
},
{
type: "filter",
Expand All @@ -208,6 +213,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[5]",
nullable: false,
displayPath: "test5 → some",
},
{
type: "and",
Expand All @@ -224,6 +230,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[6].children[0]",
nullable: false,
displayPath: "test3 → test",
},
{
type: "filter",
Expand All @@ -235,6 +242,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[6].children[1]",
nullable: false,
displayPath: "test3 → test2",
},
{
type: "or",
Expand All @@ -251,6 +259,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[6].children[2].children[0]",
nullable: false,
displayPath: "test5 → test6",
},
],
},
Expand All @@ -266,6 +275,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[7]",
nullable: false,
displayPath: "testBool",
},
{
type: "filter",
Expand All @@ -277,6 +287,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[8]",
nullable: true,
displayPath: "testNull",
},
{
type: "filter",
Expand All @@ -288,6 +299,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[9]",
nullable: false,
displayPath: "testArray",
},
];

Expand Down Expand Up @@ -322,6 +334,7 @@ describe("advancedSearch", () => {
canHaveChildren: false,
internalPath: "[0]",
nullable: false,
displayPath: "test2",
},
];

Expand Down
42 changes: 33 additions & 9 deletions packages/next-admin/src/utils/advancedSearch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import z from "zod";
import set from "lodash.set";
import get from "lodash.get";
import { ModelName, Schema, SchemaModel } from "../types";
import { ModelName, ModelOptions, Schema, SchemaModel } from "../types";
import { TranslationFn } from "../context/I18nContext";

export type QueryCondition =
| "equals"
Expand Down Expand Up @@ -234,8 +235,19 @@ const getQueryBlockValue = (

export const buildUIBlocks = <M extends ModelName>(
blocks: QueryBlock | null,
{ resource, schema }: { resource: M; schema: Schema },
fields: string[] = []
{
resource,
schema,
options,
t,
}: {
resource: M;
schema: Schema;
options?: ModelOptions<ModelName>;
t?: TranslationFn;
},
fields: string[] = [],
displayFields: string[] = []
): UIQueryBlock[] => {
if (blocks) {
const entries = Object.entries(blocks);
Expand All @@ -247,7 +259,12 @@ export const buildUIBlocks = <M extends ModelName>(
type: key === "AND" ? "and" : "or",
id: crypto.randomUUID(),
children: value.flatMap((block: QueryBlock) => {
return buildUIBlocks(block, { resource, schema }, fields);
return buildUIBlocks(
block,
{ resource, schema, options },
fields,
displayFields
);
}),
};
} else {
Expand All @@ -257,10 +274,14 @@ export const buildUIBlocks = <M extends ModelName>(
key as keyof typeof resourceInSchema.properties
];
const conditions = Object.entries(value as Filter);
const displayKeyFallback = options?.[resource]?.aliases?.[key] ?? key;
const displayKey =
t?.(`model.${resource}.fields.${key}`, {}, displayKeyFallback) ??
displayKeyFallback;

if (schemaProperty) {
// @ts-expect-error
return conditions.flatMap(([conditionKey, conditionValue]) => {
return conditions.flatMap(([conditionKey]) => {
const queryCondition = getQueryCondition(conditionKey);

if (queryCondition) {
Expand All @@ -286,6 +307,7 @@ export const buildUIBlocks = <M extends ModelName>(
contentType: contentType,
canHaveChildren: false,
nullable: isFieldNullable(schemaProperty.type),
displayPath: [...displayFields, displayKey].join(" → "),
};
} else {
let isArrayConditionKey = conditionKey === "some";
Expand Down Expand Up @@ -321,8 +343,9 @@ export const buildUIBlocks = <M extends ModelName>(
.flatMap((block) => {
return buildUIBlocks(
block,
{ resource: childResourceName, schema },
[...fields, key]
{ resource: childResourceName, schema, options },
[...fields, key],
[...displayFields, displayKey]
);
})
.filter(Boolean) as UIQueryBlock[],
Expand All @@ -331,8 +354,9 @@ export const buildUIBlocks = <M extends ModelName>(

return buildUIBlocks(
{ [childKey]: childValue } as Filter,
{ resource: childResourceName, schema },
[...fields, key]
{ resource: childResourceName, schema, options },
[...fields, key],
[...displayFields, displayKey]
);
})
.flat();
Expand Down

0 comments on commit 003805d

Please sign in to comment.