Skip to content

Commit

Permalink
Merge pull request #371 from premieroctet/revert-370-revert-369-featu…
Browse files Browse the repository at this point in the history
…re/loader-select

Revert "Revert "Add loader to select""
  • Loading branch information
cregourd authored Jul 1, 2024
2 parents bc1a9bb + 6da22fc commit ab3628b
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 139 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-waves-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@premieroctet/next-admin": patch
---

Add loader on select
3 changes: 3 additions & 0 deletions .github/workflows/reset-database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ jobs:
- name: Install dependencies
run: yarn install
- name: Reset database
env:
POSTGRES_URL_NON_POOLING: ${{ env.POSTGRES_URL_NON_POOLING }}
POSTGRES_URL: ${{ env.POSTGRES_URL }}
run: yarn reset-database
2 changes: 1 addition & 1 deletion apps/example/app/[locale]/admin/[[...nextadmin]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const viewport: Viewport = {
};

export const metadata: Metadata = {
icons: "/favicon.ico",
icons: "/assets/logo.svg",
};

export default async function AdminPage({
Expand Down
4 changes: 4 additions & 0 deletions apps/example/options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ export const options: NextAdminOptions = {
label: "Documentation",
url: "https://next-admin.js.org",
},
{
label: "Page Router",
url: "/pagerouter/admin",
},
],
defaultColorScheme: "dark",
};
9 changes: 7 additions & 2 deletions apps/example/pageRouterOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import DatePicker from "./components/DatePicker";

export const options: NextAdminOptions = {
basePath: "/pagerouter/admin",
title: "⚡️ My Admin",
title: "⚡️ My Admin Page Router",
model: {
User: {
toString: (user) => `${user.name} (${user.email})`,
Expand All @@ -22,7 +22,6 @@ export const options: NextAdminOptions = {
},
},
},

],
fields: {
role: {
Expand Down Expand Up @@ -157,6 +156,12 @@ export const options: NextAdminOptions = {
icon: "AdjustmentsHorizontalIcon",
},
},
externalLinks: [
{
label: "App Router",
url: "/ ",
},
],
sidebar: {
groups: [
{
Expand Down
92 changes: 92 additions & 0 deletions apps/example/public/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/next-admin/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ const Form = ({
onSubmit={(e) => console.log("onSubmit", e)}
onError={(e) => console.log("onError", e)}
ref={formRef}
className="relative"
/>
)}
</FormContext.Consumer>
Expand Down
7 changes: 4 additions & 3 deletions packages/next-admin/src/components/LoaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ const LoadingRow = forwardRef<
return (
<div
className={clsx(
"flex items-center justify-start px-3 py-2 text-sm text-gray-400",
"flex items-center justify-start px-3 py-2",
"dark:bg-dark-nextadmin-background-subtle ",
props.className
)}
{...props}
ref={ref}
>
<Loader className="h-5 w-5 animate-spin stroke-gray-400" />
<span className="ml-3">{t("selector.loading")}</span>
<Loader className="h-5 w-5 animate-spin stroke-nextadmin-content-default dark:stroke-dark-nextadmin-content-default dark:stroke-gray-400" />
<span className="ml-3 dark:text-dark-nextadmin-content-default text-sm text-gray-400">{t("selector.loading")}</span>
</div>
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { RJSFSchema } from "@rjsf/utils";
import clsx from "clsx";
import { PropsWithChildren, useRef } from "react";
import { twMerge } from "tailwind-merge";
import DoubleArrow from "../../../assets/icons/DoubleArrow";
import { useForm } from "../../../context/FormContext";
import { useI18n } from "../../../context/I18nContext";
import useCloseOnOutsideClick from "../../../hooks/useCloseOnOutsideClick";
import { Enumeration, Field, ModelName } from "../../../types";
import Button from "../../radix/Button";
import { Selector } from "../Selector";
Expand All @@ -26,9 +23,7 @@ type Props = {
const MultiSelectWidget = (props: Props) => {
const formContext = useForm();
const { formData, onChange, options, name, schema } = props;
const containerRef = useRef<HTMLDivElement>(null);
const { t } = useI18n();
useCloseOnOutsideClick(containerRef, () => formContext.setOpen(false, name));
const fieldOptions =
formContext.options?.model?.[formContext.resource!]?.edit?.fields?.[
name as Field<ModelName>
Expand All @@ -53,65 +48,61 @@ const MultiSelectWidget = (props: Props) => {
// @ts-expect-error
const fieldSortable = displayMode === "list" && !!fieldOptions?.orderField;

const Select = ({
children,
className,
}: PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => (
<div className={twMerge("relative", className)} ref={containerRef}>
<select
name={name}
className={clsx(
"absolute inset-0 h-full w-full opacity-0",
props.disabled ? "cursor-not-allowed" : "cursor-pointer"
)}
disabled={props.disabled}
required={props.required}
onMouseDown={(e) => {
e.preventDefault();
if (!props.disabled) {
formContext.toggleOpen(name);
}
}}
>
{!(props.required && selectedValues.length === 0) && (
<option value={JSON.stringify(selectedValues)} />
)}
</select>
{children}
</div>
const select = (
<select
name={name}
className={clsx(
"absolute inset-0 h-full w-full opacity-0",
props.disabled ? "cursor-not-allowed" : "cursor-pointer"
)}
disabled={props.disabled}
required={props.required}
onMouseDown={(e) => {
e.preventDefault();
if (!props.disabled) {
formContext.toggleOpen(name);
}
}}
onClick={(e) => {
e.stopPropagation();
}}
>
{!(props.required && selectedValues.length === 0) && (
<option value={JSON.stringify(selectedValues)} />
)}
</select>
);

return (
<div className="relative">
{displayMode === "select" && (
<Select>
<div
className={clsx(
"dark:bg-dark-nextadmin-background-subtle dark:ring-dark-nextadmin-border-strong text-nextadmin-content-inverted dark:text-dark-nextadmin-content-inverted dark:border-dark-nextadmin-border-default ring-nextadmin-border-default flex min-h-[38px] w-[100%] w-full appearance-none flex-wrap gap-x-1 gap-y-1 rounded-md border-0 border-gray-300 px-2 py-1.5 pr-10 text-sm placeholder-gray-500 shadow-sm ring-1 ring-inset transition-all duration-300 placeholder:text-gray-400 sm:leading-6",
{
"opacity-50": props.disabled,
}
)}
aria-disabled={props.disabled}
>
{formData?.map(
(value: any, index: number) =>
value && (
<MultiSelectItem
key={index}
label={value.label}
onRemoveClick={() => onRemoveClick(value.value)}
deletable={!props.disabled}
/>
)
)}
{!props.disabled && (
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-3">
<DoubleArrow />
</div>
)}
</div>
</Select>
<div
className={clsx(
"dark:bg-dark-nextadmin-background-subtle dark:ring-dark-nextadmin-border-strong text-nextadmin-content-inverted dark:text-dark-nextadmin-content-inverted dark:border-dark-nextadmin-border-default ring-nextadmin-border-default flex min-h-[38px] w-[100%] w-full appearance-none flex-wrap gap-x-1 gap-y-1 rounded-md border-0 border-gray-300 px-2 py-1.5 pr-10 text-sm placeholder-gray-500 shadow-sm ring-1 ring-inset transition-all duration-300 placeholder:text-gray-400 sm:leading-6",
{
"cursor-not-allowed opacity-50": props.disabled,
}
)}
aria-disabled={props.disabled}
>
{select}
{formData?.map(
(value: any, index: number) =>
value && (
<MultiSelectItem
key={index}
label={value.label}
onRemoveClick={() => onRemoveClick(value.value)}
deletable={!props.disabled}
/>
)
)}
{!props.disabled && (
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-3">
<DoubleArrow />
</div>
)}
</div>
)}
{displayMode === "list" && (
<div className="space-y-2">
Expand All @@ -123,15 +114,16 @@ const MultiSelectWidget = (props: Props) => {
sortable={fieldSortable}
onUpdateFormData={onChange}
/>
<Select className="max-w-fit">
<Button
aria-disabled={props.disabled}
type="button"
disabled={props.disabled}
>
{t("form.widgets.multiselect.select")}
</Button>
</Select>

<Button
aria-disabled={props.disabled}
type="button"
disabled={props.disabled}
className="relative"
>
{select}
{t("form.widgets.multiselect.select")}
</Button>
</div>
)}
{displayMode === "table" && (
Expand All @@ -142,15 +134,16 @@ const MultiSelectWidget = (props: Props) => {
onRemoveClick={onRemoveClick}
deletable={!props.disabled}
/>
<Select className="max-w-fit">
<Button
aria-disabled={props.disabled}
type="button"
disabled={props.disabled}
>
{t("form.widgets.multiselect.select")}
</Button>
</Select>

<Button
aria-disabled={props.disabled}
type="button"
disabled={props.disabled}
className="relative"
>
{select}
{t("form.widgets.multiselect.select")}
</Button>
</div>
)}

Expand Down
Loading

0 comments on commit ab3628b

Please sign in to comment.