feat(dashboard): Customer groups domain (#6098)

**What**
- Adds list, detail, edit, create, add customers views to the CG domain.

**Note**
- Missing metadata in forms (coming in separate PR for entire admin)
- Missing table filters (separate PR)

CLOSES CORE-1648
This commit is contained in:
Kasper Fabricius Kristensen
2024-01-17 15:25:59 +01:00
committed by GitHub
parent 19bbae61f8
commit 80feb972cb
33 changed files with 1540 additions and 48 deletions

View File

@@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"
import { Link } from "react-router-dom"
type NoResultsProps = {
title: string
title?: string
message?: string
}
@@ -16,7 +16,7 @@ export const NoResults = ({ title, message }: NoResultsProps) => {
<div className="flex flex-col items-center gap-y-2">
<MagnifyingGlass />
<Text size="small" leading="compact" weight="plus">
{title}
{title ?? t("general.noResultsTitle")}
</Text>
<Text size="small" className="text-ui-fg-subtle">
{message ?? t("general.noResultsMessage")}
@@ -51,7 +51,9 @@ export const NoRecords = ({ title, message, action }: NoRecordsProps) => {
</div>
{action && (
<Link to={action.to}>
<Button variant="secondary">{action.label}</Button>
<Button variant="secondary" size="small">
{action.label}
</Button>
</Link>
)}
</div>

View File

@@ -0,0 +1 @@
export * from "./table-row-actions"

View File

@@ -0,0 +1,84 @@
import { EllipsisHorizontal } from "@medusajs/icons"
import { DropdownMenu, IconButton } from "@medusajs/ui"
import { ReactNode } from "react"
import { Link } from "react-router-dom"
type TableRowAction = {
icon: ReactNode
label: string
} & (
| {
to: string
onClick?: never
}
| {
onClick: () => void
to?: never
}
)
type TableRowActionGroup = {
actions: TableRowAction[]
}
type TableRowActionsProps = {
groups: TableRowActionGroup[]
}
export const TableRowActions = ({ groups }: TableRowActionsProps) => {
return (
<DropdownMenu>
<DropdownMenu.Trigger asChild>
<IconButton size="small" variant="transparent">
<EllipsisHorizontal />
</IconButton>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
{groups.map((group, index) => {
if (!group.actions.length) {
return null
}
const isLast = index === groups.length - 1
return (
<div className="flex flex-col gap-y-1">
{group.actions.map((action, index) => {
if (action.onClick) {
return (
<DropdownMenu.Item
key={index}
onClick={(e) => {
e.stopPropagation()
action.onClick()
}}
className="[&_svg]:text-ui-fg-subtle flex items-center gap-x-2"
>
{action.icon}
<span>{action.label}</span>
</DropdownMenu.Item>
)
}
return (
<Link to={action.to} key={index}>
<DropdownMenu.Item
onClick={(e) => {
e.stopPropagation()
}}
className="[&_svg]:text-ui-fg-subtle flex items-center gap-x-2"
>
{action.icon}
<span>{action.label}</span>
</DropdownMenu.Item>
</Link>
)
})}
{!isLast && <DropdownMenu.Separator />}
</div>
)
})}
</DropdownMenu.Content>
</DropdownMenu>
)
}