Skip to content

Commit

Permalink
feat: display actions in table rows (#388)
Browse files Browse the repository at this point in the history
* feat: display actions in table rows

* add changeset
  • Loading branch information
foyarash authored Sep 5, 2024
1 parent 2bf5933 commit 2fa281d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-brooms-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@premieroctet/next-admin": patch
---

feat: display actions in table rows (#387)
34 changes: 34 additions & 0 deletions packages/next-admin/src/components/ActionDropdownItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import clsx from "clsx";
import { useAction } from "../hooks/useAction";
import { ModelAction, ModelName } from "../types";
import { DropdownItem } from "./radix/Dropdown";
import { useI18n } from "../context/I18nContext";

type Props = {
action: ModelAction | Omit<ModelAction, "action">;
resource: ModelName;
resourceIds: string[] | number[];
};

const ActionDropdownItem = ({ action, resource, resourceIds }: Props) => {
const { t } = useI18n();
const { runAction } = useAction(resource, resourceIds);

return (
<DropdownItem
key={action.title}
className={clsx("cursor-pointer rounded-md px-2 py-1", {
"text-red-700 dark:text-red-400": action.style === "destructive",
"hover:bg-red-50": action.style === "destructive",
})}
onClick={(evt) => {
evt.stopPropagation();
runAction(action);
}}
>
{t(action.title)}
</DropdownItem>
);
};

export default ActionDropdownItem;
26 changes: 7 additions & 19 deletions packages/next-admin/src/components/ActionsDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ import {
ChevronDownIcon,
EllipsisVerticalIcon,
} from "@heroicons/react/24/outline";
import clsx from "clsx";
import { useState } from "react";
import { useI18n } from "../context/I18nContext";
import { useAction } from "../hooks/useAction";
import { ModelAction, ModelName } from "../types";
import ActionDropdownItem from "./ActionDropdownItem";
import {
Dropdown,
DropdownBody,
DropdownContent,
DropdownItem,
DropdownTrigger,
} from "./radix/Dropdown";

Expand All @@ -29,14 +27,9 @@ const ActionsDropdown = ({
resource,
selectedCount,
}: Props) => {
const { runAction } = useAction(resource, selectedIds);
const { t } = useI18n();
const [isOpen, setIsOpen] = useState(false);

const onActionClick = (action: ModelAction | Omit<ModelAction, "action">) => {
runAction(action);
};

return (
<Dropdown onOpenChange={setIsOpen}>
<DropdownTrigger
Expand Down Expand Up @@ -77,17 +70,12 @@ const ActionsDropdown = ({
>
{actions?.map((action) => {
return (
<DropdownItem
key={action.title}
className={clsx("cursor-pointer rounded-md px-2 py-1", {
"text-red-700 dark:text-red-400":
action.style === "destructive",
"hover:bg-red-50": action.style === "destructive",
})}
onClick={() => onActionClick(action)}
>
{t(action.title)}
</DropdownItem>
<ActionDropdownItem
key={action.id}
action={action}
resourceIds={selectedIds}
resource={resource}
/>
);
})}
</TransitionChild>
Expand Down
16 changes: 14 additions & 2 deletions packages/next-admin/src/components/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
SelectTrigger,
SelectValue,
} from "./radix/Select";
import ActionDropdownItem from "./ActionDropdownItem";

export type ListProps = {
resource: ModelName;
Expand Down Expand Up @@ -154,13 +155,24 @@ function List({
<DropdownBody>
<DropdownContent
side="left"
align="start"
sideOffset={5}
className="z-50 px-1 py-2"
className="z-50 space-y-1.5 px-2 py-2"
>
{actions?.map((action) => {
return (
<ActionDropdownItem
key={action.id}
action={action}
resourceIds={[row.original[idProperty].value as string]}
resource={resource}
/>
);
})}
<DropdownItem asChild>
<Button
variant="destructiveOutline"
className="h-6 px-1"
className="h-6 w-full"
onClick={(evt) => {
evt.stopPropagation();
deleteItems([row.original[idProperty].value as string]);
Expand Down
4 changes: 2 additions & 2 deletions packages/next-admin/src/components/ListHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default function ListHeader({
: [];

return [...(actionsProp || []), ...defaultActions];
}, [actionsProp, onDelete, t]);
}, [actionsProp, onDelete, t, canDelete]);

const resourcePluralName = t(`model.${resource}.plural`, {}, title);

Expand Down Expand Up @@ -115,7 +115,7 @@ export default function ListHeader({
onInput={onSearchChange}
defaultValue={search}
type="search"
className="text-nextadmin-content-subtle dark:text-dark-nextadmin-content-subtle rounded-md bg-[transparent] py-1.5 text-sm focus:outline-none focus:ring-0 focus:ring-offset-0 min-w-0 w-full"
className="text-nextadmin-content-subtle dark:text-dark-nextadmin-content-subtle w-full min-w-0 rounded-md bg-[transparent] py-1.5 text-sm focus:outline-none focus:ring-0 focus:ring-offset-0"
placeholder={`${t(
"list.header.search.placeholder"
)} ${resourcePluralName.toLowerCase()}`}
Expand Down
2 changes: 0 additions & 2 deletions packages/next-admin/src/hooks/useAction.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useRouterInternal } from "./useRouterInternal";
import { ModelAction, ModelName } from "../types";
import { useI18n } from "../context/I18nContext";
import { useConfig } from "../context/ConfigContext";
Expand All @@ -9,7 +8,6 @@ export const SPECIFIC_IDS_TO_RUN_ACTION = {
};

export const useAction = (resource: ModelName, ids: string[] | number[]) => {
const { router } = useRouterInternal();
const { t } = useI18n();
const { apiBasePath } = useConfig();
const { showMessage } = useMessage();
Expand Down

0 comments on commit 2fa281d

Please sign in to comment.