Skip to content

Commit

Permalink
Fix advanced filter (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
cregourd authored Oct 2, 2024
1 parent 13c2ef1 commit 11dff98
Show file tree
Hide file tree
Showing 22 changed files with 420 additions and 129 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-pandas-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@premieroctet/next-admin": patch
---

Fix in/notin operators in advanced filters
1 change: 0 additions & 1 deletion apps/example/components/PostAddTagDialogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const AddTagDialog = ({ data, onClose }: Props) => {
type: "success",
message: "Tag added successfully",
});

})
.catch((e) => {
console.error(e);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ This command generates the required files to use Next-Admin in your project. It
- `--cwd <path>` : The Next.js project directory. Default: current directory
- `-s, --schema <path>` : The directory path where the Prisma schema is located, relative to the current directory, or cwd if provided
- `-r, --baseRoutePath <path>` : The base route path to access your admin in the browser (e.g: /admin). Default: /admin
- `-a, --baseApiPath <path>` : The base route path for the API routes (e.g: /api/admin). Default: /api/admin
- `-a, --baseApiPath <path>` : The base route path for the API routes (e.g: /api/admin). Default: /api/admin
12 changes: 6 additions & 6 deletions packages/cli/scripts/build.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as esbuild from 'esbuild';
import { buildOptions } from './options';
import * as esbuild from "esbuild";
import { buildOptions } from "./options";

const build = async () => {
await esbuild.build({
...buildOptions
})
}
...buildOptions,
});
};

build()
build();
14 changes: 7 additions & 7 deletions packages/cli/scripts/dev.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as esbuild from 'esbuild';
import { buildOptions } from './options';
import * as esbuild from "esbuild";
import { buildOptions } from "./options";

const dev = async () => {
const ctx = await esbuild.context({
...buildOptions
})
...buildOptions,
});

await ctx.watch()
}
await ctx.watch();
};

dev()
dev();
24 changes: 12 additions & 12 deletions packages/cli/scripts/options.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import type * as esbuild from 'esbuild';
import fs from 'fs'
import type * as esbuild from "esbuild";
import fs from "fs";

const plugin: esbuild.Plugin = {
name: 'cliPlugin',
name: "cliPlugin",
setup(build) {
build.onEnd(() => {
fs.chmodSync('dist/index.js', '755');
fs.chmodSync("dist/index.js", "755");

fs.cpSync("src/templates", "dist/templates", { recursive: true });
})
});
},
}
};

export const buildOptions: esbuild.BuildOptions = {
entryPoints: ['src/index.ts'],
entryPoints: ["src/index.ts"],
bundle: true,
platform: 'node',
platform: "node",
minify: true,
plugins: [plugin],
outfile: 'dist/index.js',
external: ['fs', 'path'],
outfile: "dist/index.js",
external: ["fs", "path"],
banner: {
js: '#!/usr/bin/env node',
js: "#!/usr/bin/env node",
},
}
};
6 changes: 4 additions & 2 deletions packages/cli/src/utils/packageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ export const getPackageManager = (
}
};

export const getDataForPackageManager = (packageManager: PackageManager): PackageManagerData => {
export const getDataForPackageManager = (
packageManager: PackageManager
): PackageManagerData => {
return {
name: packageManager,
installCmd: packageManagerInstallCmd[packageManager],
installDevCmd: packageManagerInstallDevCmd[packageManager],
};
}
};
11 changes: 4 additions & 7 deletions packages/cli/src/utils/path.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import path from 'path';
import path from "path";

export const getRelativePath = (from: string, to: string) => {
return path.join(
path.relative(
path.dirname(from),
path.dirname(to)
),
path.relative(path.dirname(from), path.dirname(to)),
path.basename(to)
)
}
);
};
22 changes: 9 additions & 13 deletions packages/cli/src/utils/templates.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import path from 'path'
import fs from 'fs'
import Mustache from 'mustache'
import path from "path";
import fs from "fs";
import Mustache from "mustache";

export const writeToTemplate = (
templateName: string,
context: Record<string, string | boolean>
) => {
const template = fs.readFileSync(
path.join(
__dirname,
'templates',
`${templateName}.mustache`
),
'utf-8'
)

path.join(__dirname, "templates", `${templateName}.mustache`),
"utf-8"
);

return Mustache.render(template, context, undefined, {
escape: (value) => value
})
escape: (value) => value,
});
};
2 changes: 1 addition & 1 deletion packages/next-admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"@headlessui/react": "^2.1.5",
"@heroicons/react": "^2.0.18",
"@picocss/pico": "^1.5.7",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-select": "^1.2.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-admin/src/components/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Badge = ({ isActive, onClick, ...props }: BadgeProps) => {
<div
{...props}
className={clsx(
"bg-nextadmin-background-default dark:bg-dark-nextadmin-background-emphasis text-nextadmin-content-inverted dark:text-dark-nextadmin-content-subtle ring-nextadmin-border-default dark:ring-dark-nextadmin-border-default bg-nextadmin-dackground-default dark:bg-dark-nextadmin-background-strong peer flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1 text-sm font-medium ring-1",
"bg-nextadmin-background-default dark:bg-dark-nextadmin-background-emphasis text-nextadmin-content-inverted dark:text-dark-nextadmin-content-subtle ring-nextadmin-border-default dark:ring-dark-nextadmin-border-default bg-nextadmin-background-default dark:bg-dark-nextadmin-background-strong peer flex cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1 text-sm font-medium ring-1",
props.className
)}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { AdjustmentsHorizontalIcon } from "@heroicons/react/24/outline";
import { useState } from "react";
import useAdvancedSearch from "../../hooks/useAdvancedSearch";
import { ModelName, Schema } from "../../types";
import Button from "../radix/Button";
import AdvancedSearchModal from "./AdvancedSearchModal";
import { ModelName, Schema } from "../../types";

type Props = {
resource: ModelName;
Expand All @@ -11,9 +12,13 @@ type Props = {

const AdvancedSearchButton = ({ resource, schema }: Props) => {
const [modalOpen, setModalOpen] = useState(false);
const { uiBlocks } = useAdvancedSearch({ resource, schema });

return (
<>
<div className="relative">
{uiBlocks?.length && (
<span className="bg-nextadmin-brand-default absolute right-0 top-0 h-2 w-2 rounded-full" />
)}
<Button
variant="ghost"
className="px-2"
Expand All @@ -27,7 +32,7 @@ const AdvancedSearchButton = ({ resource, schema }: Props) => {
resource={resource}
schema={schema}
/>
</>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, PropsWithChildren, useContext } from "react";
import { UIQueryBlock } from "../../utils/advancedSearch";
import { createContext, useContext } from "react";
import { ModelName, Schema } from "../../types";
import { UIQueryBlock } from "../../utils/advancedSearch";

type AdvancedSearchContextType = {
addUiBlock: (uiBlock: UIQueryBlock) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ const AdvancedSearchDropdown = ({
<Dropdown>
<DropdownTrigger asChild>
{trigger || (
<Button variant="ghost" className="justify-between gap-2 border dark:border-dark-nextadmin-border-strong">
<Button
variant="ghost"
className="dark:border-dark-nextadmin-border-strong justify-between gap-2 border"
>
<div className="flex items-center gap-2">
<PlusIcon className="h-4 w-4" aria-hidden="true" />
{t("search.advanced.add")}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { DropdownItem } from "../radix/Dropdown";
import { ModelName, Schema } from "../../types";
import { MouseEvent, useMemo, useState } from "react";
import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
import { ChevronRightIcon } from "@heroicons/react/24/outline";
import clsx from "clsx";
import { MouseEvent, useMemo, useState } from "react";
import { useConfig } from "../../context/ConfigContext";
import { useI18n } from "../../context/I18nContext";
import { ModelName, Schema } from "../../types";
import {
contentTypeFromSchemaType,
isFieldNullable,
isSchemaPropertyScalarArray,
UIQueryBlock,
} from "../../utils/advancedSearch";
import { useConfig } from "../../context/ConfigContext";
import { useI18n } from "../../context/I18nContext";
import { DropdownItem } from "../radix/Dropdown";

type Props = {
property: string;
Expand Down Expand Up @@ -83,10 +83,13 @@ const AdvancedSearchDropdownItem = ({
type: "filter",
path: [path, property].filter(Boolean).join("."),
value: "",
contentType: contentTypeFromSchemaType(
schemaProperty!.type,
schemaProperty?.format
),
contentType: contentTypeFromSchemaType(schemaProperty as Schema),
enum: (schemaProperty?.enum?.filter(Boolean) ?? []) as string[],
defaultValue: schemaProperty?.default as
| string
| number
| boolean
| null,
canHaveChildren: false,
condition: "equals",
id: crypto.randomUUID(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useEffect } from "react";
import { useI18n } from "../../context/I18nContext";
import { QueryCondition, UIQueryBlock } from "../../utils/advancedSearch";
import { Button } from "../radix/Button";
import {
Dropdown,
DropdownBody,
DropdownContent,
DropdownItem,
DropdownTrigger,
} from "../radix/Dropdown";
import { Button } from "../radix/Button";
import { QueryCondition, UIQueryBlock } from "../../utils/advancedSearch";
import { useI18n } from "../../context/I18nContext";
import { useAdvancedSearchContext } from "./AdvancedSearchContext";

type Props = {
Expand All @@ -18,6 +19,24 @@ const AdvancedSearchFieldCondition = ({ uiBlock }: Props) => {
const { t } = useI18n();
const { updateUiBlock } = useAdvancedSearchContext();

useEffect(() => {
if (uiBlock.type === "filter") {
const condition = uiBlock.condition;
if ((condition === "equals" || condition === "not") && uiBlock.enum) {
updateUiBlock({
...uiBlock,
condition,
value: Boolean(uiBlock.value)
? String(uiBlock.value)
?.split(",")
.map((v) => v.trim())[0]
: (uiBlock.defaultValue ?? null),
});
}
}
// @ts-expect-error
}, [uiBlock.condition]);

Check warning on line 38 in packages/next-admin/src/components/advancedSearch/AdvancedSearchFieldCondition.tsx

View workflow job for this annotation

GitHub Actions / start

React Hook useEffect has missing dependencies: 'uiBlock' and 'updateUiBlock'. Either include them or remove the dependency array

Check warning on line 38 in packages/next-admin/src/components/advancedSearch/AdvancedSearchFieldCondition.tsx

View workflow job for this annotation

GitHub Actions / Release

React Hook useEffect has missing dependencies: 'uiBlock' and 'updateUiBlock'. Either include them or remove the dependency array

if (uiBlock.type !== "filter") {
return null;
}
Expand All @@ -39,13 +58,19 @@ const AdvancedSearchFieldCondition = ({ uiBlock }: Props) => {
];
const numberConditions: QueryCondition[] = ["lt", "lte", "gt", "gte"];

if (uiBlock.contentType !== "boolean") {
if (
uiBlock.contentType !== "boolean" &&
uiBlock.contentType !== "datetime"
) {
commonValidConditions.push(...nonBooleanConditions);
}

if (uiBlock.contentType === "text") {
commonValidConditions.push(...textConditions);
} else if (uiBlock.contentType !== "boolean") {
} else if (
uiBlock.contentType === "number" ||
uiBlock.contentType === "datetime"
) {
commonValidConditions.push(...numberConditions);
}

Expand Down
Loading

0 comments on commit 11dff98

Please sign in to comment.