Skip to content

Commit

Permalink
feat: add client actions (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
foyarash authored Sep 13, 2024
1 parent db30b5c commit cdebaac
Show file tree
Hide file tree
Showing 27 changed files with 624 additions and 64 deletions.
5 changes: 5 additions & 0 deletions .changeset/perfect-toys-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@premieroctet/next-admin": minor
---

feat: add client actions (#401)
80 changes: 80 additions & 0 deletions apps/docs/pages/docs/api/components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import OptionsTable from "../../../components/OptionsTable";

# Components

Next-Admin exports a set of UI components which are, for most of those, extending [Radix UI primitives](https://www.radix-ui.com/primitives). These components are available through the `@premieroctet/next-admin/components` import.

## `Button`

The button element accepts all the base `button` tag attributes and extends it with the following:

<OptionsTable
options={[
{
name: "variant",
description:
"The button variant. Possible values are `default`, `destructive`, `destructiveOutline`, `outline`, `secondary`, `ghost`, `link`",
defaultValue: "default",
},
{
name: "size",
description: "The button size. Possible values are `default`, `sm`, `lg`",
},
{
name: "icon",
description: "A boolean indicating the presence of an icon",
},
{
name: "asChild",
description: (
<>
A boolean to render a{" "}
<a href="https://www.radix-ui.com/primitives/docs/utilities/slot">
Radix Slot component
</a>
</>
),
},
{
name: "loading",
description: "A boolean to render a spinner",
},
]}
/>

## `BaseInput`

The input component rendered in the Form component. It accepts all the base `input` tag attributes.

## `Switch`

The [Radix Switch](https://www.radix-ui.com/primitives/docs/components/switch) component.

## `Select`

The [Radix Select](https://www.radix-ui.com/primitives/docs/components/select) component.

## `Checkbox`

An implementation of the [Radix Checkbox](https://www.radix-ui.com/primitives/docs/components/checkbox) component. It accepts all the props of the [Checkbox Root](https://www.radix-ui.com/primitives/docs/components/switch#root) component, and the following:

<OptionsTable
options={[
{
name: "indeterminate",
description: "A boolean to render the checkbox in an indeterminate state",
},
]}
/>

## `Dropdown`

The [Radix Dropdown](https://www.radix-ui.com/primitives/docs/components/dropdown) component.

## `Table`

The [Radix Table](https://www.radix-ui.com/primitives/docs/components/table) component.

## `Tooltip`

The [Radix Tooltip](https://www.radix-ui.com/primitives/docs/components/tooltip) component.
181 changes: 168 additions & 13 deletions apps/docs/pages/docs/api/model-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,8 @@ By default, if no models are defined, they will all be displayed in the admin. I
description: (
<>
{" "}
an array of actions (see <a href="#actions-property">
actions property
</a>)
an array of actions (see{" "}
<a href="#actions-property">actions property</a>)
</>
),
},
Expand Down Expand Up @@ -200,9 +199,8 @@ This property determines how your data is displayed in the [list View](/docs/glo
description: (
<>
{" "}
define a set of Prisma filters that user can choose in list (see <a href="#listfilters-property">
filters
</a>)
define a set of Prisma filters that user can choose in list (see{" "}
<a href="#listfilters-property">filters</a>)
</>
),
},
Expand Down Expand Up @@ -315,6 +313,7 @@ The `exports` property is available in the `list` property. It's an object or an
This property determines how your data is displayed in the [edit view](/docs/glossary#edit-view)

{" "}

<OptionsTable
options={[
{
Expand All @@ -323,10 +322,9 @@ This property determines how your data is displayed in the [edit view](/docs/glo
description: (
<>
{" "}
an array of fields that are displayed in the form. It can also be an object
that will be displayed in the form of a notice (see <a href="#notice">
notice
</a>)
an array of fields that are displayed in the form. It can also be an
object that will be displayed in the form of a notice (see{" "}
<a href="#notice">notice</a>)
</>
),
defaultValue: "all scalar fields are displayed",
Expand Down Expand Up @@ -589,13 +587,39 @@ The `actions` property is an array of objects that allows you to define a set of
type: "String",
description: "mandatory, action's unique identifier",
},
{
name: "type",
type: "String",
description:
"optional action type for client side actions, possible value is 'dialog'. By default action with no type is executed on the server",
},
{
name: "component",
type: "ReactElement",
description: (
<>
a React component that will be displayed in a dialog when the action
is triggered. Its mandatory if the action type is specified
</>
),
},
{
name: "className",
type: "string",
description: (
<>
class name applied to the dialog displayed when the action type is set
to 'dialog'.
</>
),
},
{
name: "action",
type: "Function",
description: (
<>
an async function that will be triggered when selecting the action in
the dropdown. For App Router, it must be defined as a server action
the dropdown. Its mandatory if the action type is not specified
</>
),
},
Expand Down Expand Up @@ -732,9 +756,11 @@ Represents the props that are passed to the custom input component.
description: (
<>
{" "}
a function taking a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event">
a function taking a{" "}
<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event">
ChangeEvent
</a> as a parameter
</a>{" "}
as a parameter
</>
),
},
Expand Down Expand Up @@ -775,3 +801,132 @@ The `HookError` is an error that can be thrown in the `beforeDb` hook of the `ed
},
]}
/>

## ClientActionDialogContentProps

Represents the props that are passed to the custom dialog component.

<OptionsTable
options={[
{
name: "resource",
type: "String",
description: "the current Prisma model name",
},
{
name: "resourceId",
type: "String | Number",
description: "the selected record id",
},
{
name: "data",
type: "Record<string, ListDataFieldValue>",
description: (
<>
A record of row's properties with{" "}
<a href="#listdatafieldvalue">ListDataFieldValue</a> as value
</>
),
},
{
name: "onClose",
type: "Function",
description: "a function to close the dialog",
},
]}
/>

## ListDataFieldValue

Represents a formatted value used by Next-Admin. It will have different shapes depending of the data type.

It will always have the following :

<OptionsTable
options={[
{
name: "__nextadmin_formatted",
type: "ReactNode",
description:
"A React Node used to have a custom rendering of the field, if needed",
},
]}
/>

### Scalar

<OptionsTable
options={[
{
name: "type",
type: "`scalar`",
description: "The type of data. It is always `scalar`",
},
{
name: "value",
type: "String | Number | boolean",
description: "the value coming from the database",
},
]}
/>

### Count

<OptionsTable
options={[
{
name: "type",
type: "`count`",
description: "The type of data. It is always `count`",
},
{
name: "value",
type: "Number",
description: "the value coming from the database",
},
]}
/>

### Link

<OptionsTable
options={[
{
name: "type",
type: "`link`",
description: "The type of data. It is always `link`",
},
{
name: "value",
type: "object",
description: "the link data displayed in the link CTA",
},
{
name: "value.label",
type: "String",
description: "the link CTA label",
},
{
name: "value.url",
type: "String",
description: "the link CTA href",
},
]}
/>

### Date

<OptionsTable
options={[
{
name: "type",
type: "`date`",
description: "The type of data. It is always `date`",
},
{
name: "value",
type: "Date",
description: "the value coming from the database",
},
]}
/>
30 changes: 30 additions & 0 deletions apps/example/components/UserDetailsDialogContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";
import { ClientActionDialogContentProps } from "@premieroctet/next-admin";
import { Button } from "@premieroctet/next-admin/components";

type Props = ClientActionDialogContentProps<"User">;

const UserDetailsDialog = ({ data, onClose }: Props) => {
return (
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<h2 className="text-nextadmin-content-default dark:text-dark-nextadmin-content-default text-2xl font-semibold">
{data?.email.value as string}
</h2>
<p className="text-nextadmin-content-subtle dark:text-dark-nextadmin-content-subtle">
{data?.name.value as string}
</p>
<p className="text-nextadmin-content-subtle dark:text-dark-nextadmin-content-subtle">
{data?.role.value as string}
</p>
</div>
<div className="flex">
<Button variant="default" onClick={onClose}>
Close
</Button>
</div>
</div>
);
};

export default UserDetailsDialog;
3 changes: 3 additions & 0 deletions apps/example/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"title": "Send email",
"success": "Email sent successfully",
"error": "Error while sending email"
},
"details": {
"title": "User details"
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions apps/example/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@
"title": "Envoyer un email",
"success": "Email envoyé avec succès",
"error": "Erreur lors de l'envoi de l'email"
},
"details": {
"title": "Détails de l'utilisateur"
}
},
"label": "Action",
Expand Down
7 changes: 7 additions & 0 deletions apps/example/options.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NextAdminOptions } from "@premieroctet/next-admin";
import DatePicker from "./components/DatePicker";
import PasswordInput from "./components/PasswordInput";
import UserDetailsDialog from "@/components/UserDetailsDialogContent";

export const options: NextAdminOptions = {
title: "⚡️ My Admin",
Expand Down Expand Up @@ -162,6 +163,12 @@ export const options: NextAdminOptions = {
successMessage: "actions.user.email.success",
errorMessage: "actions.user.email.error",
},
{
type: "dialog",
id: "user-details",
title: "actions.user.details.title",
component: <UserDetailsDialog />,
},
],
},
Post: {
Expand Down
Loading

0 comments on commit cdebaac

Please sign in to comment.