betterstart-cli 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/adapters/next/plugins/blog/schemas/menus.json +51 -11
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar.tsx +7 -1
- package/dist/assets/adapters/next/templates/init/components/layouts/sidebar-branding.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-grid.tsx +107 -0
- package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-table.tsx +58 -45
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/lifecycle-hooks-tab.tsx +3 -3
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/snippets-tab.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/entity-filters-bar.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/media/edit-media-dialog-content.tsx +2 -2
- package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/sort-indicator.tsx +7 -3
- package/dist/assets/adapters/next/templates/init/data/navigation.ts +2 -0
- package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-table-button.ts +85 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-logs.ts +41 -16
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/index.ts +2 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/types.ts +5 -0
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/runner.ts +2 -1
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/types.ts +2 -1
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-detail-drawer.tsx +51 -43
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-detail-row.tsx +2 -4
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page-content.tsx +465 -179
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page-skeleton.tsx +3 -15
- package/dist/assets/adapters/next/templates/init/pages/dashboard-page.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/forgot-password-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/login-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/reset-password-page-skeleton.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/pages/users/users-page-content.tsx +83 -2
- package/dist/assets/adapters/next/templates/init/pages/users/users-table.tsx +126 -78
- package/dist/assets/adapters/next/templates/init/utils/editor/tiptap.ts +7 -8
- package/dist/assets/adapters/next/templates/init/utils/form/list-field.ts +17 -0
- package/dist/assets/adapters/next/templates/init/utils/user/user.ts +70 -0
- package/dist/assets/shared-assets/react-admin/custom/content-editor/math-bubble-menu.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/selection-bubble-menu.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +0 -2
- package/dist/assets/shared-assets/react-admin/custom/content-editor/table-button.tsx +17 -65
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-control-popover.tsx +3 -8
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-popover.tsx +1 -2
- package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/dynamic-list-field.tsx +20 -8
- package/dist/assets/shared-assets/react-admin/custom/gallery-field.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/media-gallery-field.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +211 -0
- package/dist/assets/shared-assets/react-admin/custom/placeholder-card.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/placeholder.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/sortable-gallery-item.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/schema.json +136 -0
- package/dist/assets/shared-assets/react-admin/ui/accordion.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/alert.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/card.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/chart.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/checkbox.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/combobox.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/command.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/context-menu.tsx +6 -6
- package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/dropdown-menu.tsx +6 -6
- package/dist/assets/shared-assets/react-admin/ui/empty.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/field.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/form.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/hover-card.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/input-group.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/item.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/menubar.tsx +7 -7
- package/dist/assets/shared-assets/react-admin/ui/navigation-menu.tsx +4 -4
- package/dist/assets/shared-assets/react-admin/ui/popover.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/resizable.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/select.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/sidebar.tsx +3 -3
- package/dist/assets/shared-assets/react-admin/ui/skeleton.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/tabs.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/ui/textarea.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/tooltip.tsx +1 -1
- package/dist/cli.js +2688 -1644
- package/dist/cli.js.map +1 -1
- package/package.json +10 -2
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-filters.tsx +0 -152
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "Manage Menus",
|
|
5
5
|
"icon": "Menu",
|
|
6
6
|
"navGroup": {
|
|
7
|
-
"label": "
|
|
7
|
+
"label": "General",
|
|
8
8
|
"position": 0
|
|
9
9
|
},
|
|
10
10
|
"navPosition": 1,
|
|
@@ -30,16 +30,23 @@
|
|
|
30
30
|
"hint": "Items in the navigation menu",
|
|
31
31
|
"fields": [
|
|
32
32
|
{
|
|
33
|
-
"name": "
|
|
34
|
-
"type": "
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
"name": "parentFields",
|
|
34
|
+
"type": "group",
|
|
35
|
+
"columns": 2,
|
|
36
|
+
"fields": [
|
|
37
|
+
{
|
|
38
|
+
"name": "label",
|
|
39
|
+
"type": "string",
|
|
40
|
+
"label": "Label",
|
|
41
|
+
"required": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "href",
|
|
45
|
+
"type": "string",
|
|
46
|
+
"label": "Href",
|
|
47
|
+
"required": true
|
|
48
|
+
}
|
|
49
|
+
]
|
|
43
50
|
},
|
|
44
51
|
{
|
|
45
52
|
"name": "openInNewTab",
|
|
@@ -47,6 +54,39 @@
|
|
|
47
54
|
"label": "Open in New Tab",
|
|
48
55
|
"hint": "Open this link in a new browser tab",
|
|
49
56
|
"default": false
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "subItems",
|
|
60
|
+
"type": "list",
|
|
61
|
+
"label": "Sub Menu Items",
|
|
62
|
+
"fields": [
|
|
63
|
+
{
|
|
64
|
+
"name": "subItemFields",
|
|
65
|
+
"type": "group",
|
|
66
|
+
"columns": 2,
|
|
67
|
+
"fields": [
|
|
68
|
+
{
|
|
69
|
+
"name": "subItemLabel",
|
|
70
|
+
"type": "string",
|
|
71
|
+
"label": "Label",
|
|
72
|
+
"required": true
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "subItemHref",
|
|
76
|
+
"type": "string",
|
|
77
|
+
"label": "Href",
|
|
78
|
+
"required": true
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "subItemOpenInNewTab",
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"label": "Open in New Tab",
|
|
86
|
+
"hint": "Open this link in a new browser tab",
|
|
87
|
+
"default": false
|
|
88
|
+
}
|
|
89
|
+
]
|
|
50
90
|
}
|
|
51
91
|
]
|
|
52
92
|
}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '@admin/components/ui/sidebar'
|
|
12
12
|
import { adminNavigation } from '@admin/data/navigation'
|
|
13
13
|
import { groupAdminNavigationItems } from '@admin/utils/navigation/sidebar'
|
|
14
|
-
import { Settings, Users } from 'lucide-react'
|
|
14
|
+
import { History, Settings, Users } from 'lucide-react'
|
|
15
15
|
import type { ComponentProps } from 'react'
|
|
16
16
|
import { Fragment, Suspense } from 'react'
|
|
17
17
|
import { SidebarBrandingRsc } from './admin-sidebar-branding-rsc'
|
|
@@ -64,6 +64,12 @@ export function AdminSidebar(props: ComponentProps<typeof Sidebar>) {
|
|
|
64
64
|
<span>Settings</span>
|
|
65
65
|
</SidebarNavLink>
|
|
66
66
|
</SidebarMenuItem>
|
|
67
|
+
<SidebarMenuItem>
|
|
68
|
+
<SidebarNavLink href="/admin/system/audit-log">
|
|
69
|
+
<History strokeWidth={2} />
|
|
70
|
+
<span>Audit Log</span>
|
|
71
|
+
</SidebarNavLink>
|
|
72
|
+
</SidebarMenuItem>
|
|
67
73
|
</SidebarMenu>
|
|
68
74
|
</SidebarGroup>
|
|
69
75
|
</SidebarContent>
|
|
@@ -20,7 +20,7 @@ export function SidebarBranding({ initialData }: SidebarBrandingProps) {
|
|
|
20
20
|
return <BrandingSkeleton />
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const dashboardName = settings?.
|
|
23
|
+
const dashboardName = settings?.title ?? admin.name
|
|
24
24
|
const dashboardLogo = settings?.dashboardLogo || DEFAULT_LOGO_URL
|
|
25
25
|
|
|
26
26
|
return (
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { cn } from '@admin/utils/shared/cn'
|
|
4
|
+
import type * as React from 'react'
|
|
5
|
+
|
|
6
|
+
type DataGridProps = React.ComponentProps<'div'> & {
|
|
7
|
+
containerClassName?: string
|
|
8
|
+
gridTemplateColumns: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const dataGridTableRole = { role: 'table' } as const
|
|
12
|
+
const dataGridRowGroupRole = { role: 'rowgroup' } as const
|
|
13
|
+
const dataGridRowRole = { role: 'row' } as const
|
|
14
|
+
const dataGridColumnHeaderRole = { role: 'columnheader' } as const
|
|
15
|
+
const dataGridCellRole = { role: 'cell' } as const
|
|
16
|
+
|
|
17
|
+
function DataGrid({
|
|
18
|
+
className,
|
|
19
|
+
containerClassName,
|
|
20
|
+
gridTemplateColumns,
|
|
21
|
+
style,
|
|
22
|
+
...props
|
|
23
|
+
}: DataGridProps) {
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
data-slot="data-grid-container"
|
|
27
|
+
className={cn('relative min-w-0 overflow-auto', containerClassName)}
|
|
28
|
+
>
|
|
29
|
+
<div
|
|
30
|
+
{...dataGridTableRole}
|
|
31
|
+
data-slot="data-grid"
|
|
32
|
+
className={cn('grid min-w-full text-sm', className)}
|
|
33
|
+
style={{ ...style, gridTemplateColumns }}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function DataGridHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
{...dataGridRowGroupRole}
|
|
44
|
+
data-slot="data-grid-header"
|
|
45
|
+
className={cn('contents', className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function DataGridBody({ className, ...props }: React.ComponentProps<'div'>) {
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
{...dataGridRowGroupRole}
|
|
55
|
+
data-slot="data-grid-body"
|
|
56
|
+
className={cn('contents', className)}
|
|
57
|
+
{...props}
|
|
58
|
+
/>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function DataGridRow({ className, style, ...props }: React.ComponentProps<'div'>) {
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
{...dataGridRowRole}
|
|
66
|
+
data-slot="data-grid-row"
|
|
67
|
+
className={cn(
|
|
68
|
+
'grid border-b transition-colors has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted',
|
|
69
|
+
className
|
|
70
|
+
)}
|
|
71
|
+
style={{ ...style, gridColumn: '1 / -1', gridTemplateColumns: 'subgrid' }}
|
|
72
|
+
tabIndex={-1}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function DataGridHead({ className, ...props }: React.ComponentProps<'div'>) {
|
|
79
|
+
return (
|
|
80
|
+
<div
|
|
81
|
+
{...dataGridColumnHeaderRole}
|
|
82
|
+
data-slot="data-grid-head"
|
|
83
|
+
className={cn(
|
|
84
|
+
'grid h-10 items-center px-3 text-left font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0',
|
|
85
|
+
className
|
|
86
|
+
)}
|
|
87
|
+
tabIndex={-1}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function DataGridCell({ className, ...props }: React.ComponentProps<'div'>) {
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
{...dataGridCellRole}
|
|
97
|
+
data-slot="data-grid-cell"
|
|
98
|
+
className={cn(
|
|
99
|
+
'grid min-h-10 items-center px-3 py-1.5 whitespace-nowrap [&:has([role=checkbox])]:pr-0',
|
|
100
|
+
className
|
|
101
|
+
)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { DataGrid, DataGridHeader, DataGridBody, DataGridHead, DataGridRow, DataGridCell }
|
package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-table.tsx
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from '@admin/components/
|
|
4
|
+
DataGrid,
|
|
5
|
+
DataGridBody,
|
|
6
|
+
DataGridCell,
|
|
7
|
+
DataGridHead,
|
|
8
|
+
DataGridHeader,
|
|
9
|
+
DataGridRow
|
|
10
|
+
} from '@admin/components/shared/data-table/data-grid'
|
|
11
11
|
import { useTableUtils } from '@admin/hooks/use-table-utils'
|
|
12
12
|
import { cn } from '@admin/utils/shared/cn'
|
|
13
13
|
import {
|
|
@@ -108,19 +108,18 @@ export function DataTable<TData extends RowData, TValue>({
|
|
|
108
108
|
}
|
|
109
109
|
})
|
|
110
110
|
registerTable(table)
|
|
111
|
+
const gridTemplateColumns = table
|
|
112
|
+
.getVisibleLeafColumns()
|
|
113
|
+
.map((column) => `${column.getSize()}px`)
|
|
114
|
+
.join(' ')
|
|
111
115
|
|
|
112
116
|
return (
|
|
113
117
|
<div className="space-y-6 pb-24">
|
|
114
|
-
<div ref={tableContainerRef} className="overflow-hidden material-sm border-border">
|
|
115
|
-
<
|
|
116
|
-
<
|
|
117
|
-
{table.getVisibleLeafColumns().map((column) => (
|
|
118
|
-
<col key={column.id} style={{ width: column.getSize() }} />
|
|
119
|
-
))}
|
|
120
|
-
</colgroup>
|
|
121
|
-
<TableHeader>
|
|
118
|
+
<div ref={tableContainerRef} className="min-w-0 overflow-hidden material-sm border-border">
|
|
119
|
+
<DataGrid gridTemplateColumns={gridTemplateColumns} style={{ width: table.getTotalSize() }}>
|
|
120
|
+
<DataGridHeader>
|
|
122
121
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
123
|
-
<
|
|
122
|
+
<DataGridRow key={headerGroup.id}>
|
|
124
123
|
{headerGroup.headers.map((header, headerIndex) => {
|
|
125
124
|
const meta = header.column.columnDef.meta as Record<string, unknown> | undefined
|
|
126
125
|
const resizeLabel =
|
|
@@ -131,12 +130,15 @@ export function DataTable<TData extends RowData, TValue>({
|
|
|
131
130
|
const canResizeColumn =
|
|
132
131
|
header.column.getCanResize() && nextHeader?.column.getCanResize() === true
|
|
133
132
|
return (
|
|
134
|
-
<
|
|
133
|
+
<DataGridHead
|
|
135
134
|
key={header.id}
|
|
136
|
-
className={cn(
|
|
137
|
-
'
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
className={cn(
|
|
136
|
+
'group/resize-header relative overflow-hidden text-foreground',
|
|
137
|
+
{
|
|
138
|
+
'text-center': meta?.align === 'center',
|
|
139
|
+
'text-right': meta?.align === 'right'
|
|
140
|
+
}
|
|
141
|
+
)}
|
|
140
142
|
data-column-id={header.column.id}
|
|
141
143
|
onMouseEnter={() => setHoveredColumnId(header.column.id)}
|
|
142
144
|
onMouseLeave={() =>
|
|
@@ -144,7 +146,6 @@ export function DataTable<TData extends RowData, TValue>({
|
|
|
144
146
|
current === header.column.id ? null : current
|
|
145
147
|
)
|
|
146
148
|
}
|
|
147
|
-
style={{ width: header.getSize() }}
|
|
148
149
|
>
|
|
149
150
|
{header.isPlaceholder
|
|
150
151
|
? null
|
|
@@ -166,32 +167,42 @@ export function DataTable<TData extends RowData, TValue>({
|
|
|
166
167
|
<GripVertical aria-hidden="true" className="size-3.5 text-foreground" />
|
|
167
168
|
</button>
|
|
168
169
|
) : null}
|
|
169
|
-
</
|
|
170
|
+
</DataGridHead>
|
|
170
171
|
)
|
|
171
172
|
})}
|
|
172
|
-
</
|
|
173
|
+
</DataGridRow>
|
|
173
174
|
))}
|
|
174
|
-
</
|
|
175
|
-
<
|
|
175
|
+
</DataGridHeader>
|
|
176
|
+
<DataGridBody>
|
|
176
177
|
{isPending ? (
|
|
177
|
-
<
|
|
178
|
-
<
|
|
178
|
+
<DataGridRow>
|
|
179
|
+
<DataGridCell
|
|
180
|
+
className="flex h-24 items-center justify-center text-center"
|
|
181
|
+
style={{ gridColumn: '1 / -1' }}
|
|
182
|
+
>
|
|
179
183
|
<div className="text-muted-foreground">{loadingMessage}</div>
|
|
180
|
-
</
|
|
181
|
-
</
|
|
184
|
+
</DataGridCell>
|
|
185
|
+
</DataGridRow>
|
|
182
186
|
) : error ? (
|
|
183
|
-
<
|
|
184
|
-
<
|
|
187
|
+
<DataGridRow>
|
|
188
|
+
<DataGridCell
|
|
189
|
+
className="flex h-24 items-center justify-center text-center"
|
|
190
|
+
style={{ gridColumn: '1 / -1' }}
|
|
191
|
+
>
|
|
185
192
|
<div className="text-destructive">Error: {error.message}</div>
|
|
186
|
-
</
|
|
187
|
-
</
|
|
193
|
+
</DataGridCell>
|
|
194
|
+
</DataGridRow>
|
|
188
195
|
) : table.getRowModel().rows?.length ? (
|
|
189
196
|
table.getRowModel().rows.map((row) => (
|
|
190
|
-
<
|
|
197
|
+
<DataGridRow
|
|
198
|
+
key={row.id}
|
|
199
|
+
className="hover:bg-muted/50"
|
|
200
|
+
data-state={row.getIsSelected() ? 'selected' : undefined}
|
|
201
|
+
>
|
|
191
202
|
{row.getVisibleCells().map((cell) => {
|
|
192
203
|
const meta = cell.column.columnDef.meta as Record<string, unknown> | undefined
|
|
193
204
|
return (
|
|
194
|
-
<
|
|
205
|
+
<DataGridCell
|
|
195
206
|
key={cell.id}
|
|
196
207
|
className={cn({
|
|
197
208
|
'text-center': meta?.align === 'center',
|
|
@@ -204,23 +215,25 @@ export function DataTable<TData extends RowData, TValue>({
|
|
|
204
215
|
current === cell.column.id ? null : current
|
|
205
216
|
)
|
|
206
217
|
}
|
|
207
|
-
style={{ width: cell.column.getSize() }}
|
|
208
218
|
>
|
|
209
219
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
210
|
-
</
|
|
220
|
+
</DataGridCell>
|
|
211
221
|
)
|
|
212
222
|
})}
|
|
213
|
-
</
|
|
223
|
+
</DataGridRow>
|
|
214
224
|
))
|
|
215
225
|
) : (
|
|
216
|
-
<
|
|
217
|
-
<
|
|
226
|
+
<DataGridRow>
|
|
227
|
+
<DataGridCell
|
|
228
|
+
className="flex h-24 items-center justify-center text-center"
|
|
229
|
+
style={{ gridColumn: '1 / -1' }}
|
|
230
|
+
>
|
|
218
231
|
{emptyMessage}
|
|
219
|
-
</
|
|
220
|
-
</
|
|
232
|
+
</DataGridCell>
|
|
233
|
+
</DataGridRow>
|
|
221
234
|
)}
|
|
222
|
-
</
|
|
223
|
-
</
|
|
235
|
+
</DataGridBody>
|
|
236
|
+
</DataGrid>
|
|
224
237
|
</div>
|
|
225
238
|
|
|
226
239
|
<DataTablePagination
|
package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/lifecycle-hooks-tab.tsx
CHANGED
|
@@ -53,14 +53,14 @@ export function LifecycleHooksTab({ lifecycleHooks }: LifecycleHooksTabProps) {
|
|
|
53
53
|
|
|
54
54
|
if (!firstHook) {
|
|
55
55
|
return (
|
|
56
|
-
<div className="flex min-h-80 items-center justify-center rounded-
|
|
57
|
-
Lifecycle hook examples are generated for entity
|
|
56
|
+
<div className="flex min-h-80 items-center justify-center rounded-lg border border-dashed border-border px-6 text-center text-sm text-muted-foreground">
|
|
57
|
+
Lifecycle hook examples are generated for entity and form schemas.
|
|
58
58
|
</div>
|
|
59
59
|
)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
return (
|
|
63
|
-
<Accordion type="single" defaultValue={firstHook.id} className="min-h-0 shrink-0 rounded-
|
|
63
|
+
<Accordion type="single" defaultValue={firstHook.id} className="min-h-0 shrink-0 rounded-lg">
|
|
64
64
|
{lifecycleHooks.map((hook) => {
|
|
65
65
|
const HookIcon = LIFECYCLE_HOOK_ICONS[hook.icon]
|
|
66
66
|
const phaseLabel = LIFECYCLE_HOOK_PHASE_LABELS[hook.phase]
|
package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/snippets-tab.tsx
CHANGED
|
@@ -56,7 +56,7 @@ export function SnippetsTab({ snippets }: SnippetsTabProps) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
|
-
<Accordion type="single" defaultValue={firstSnippet.id} className="min-h-0 shrink-0 rounded-
|
|
59
|
+
<Accordion type="single" defaultValue={firstSnippet.id} className="min-h-0 shrink-0 rounded-lg">
|
|
60
60
|
{snippets.map((snippet) => {
|
|
61
61
|
const SnippetIcon = SNIPPET_ICONS[snippet.icon]
|
|
62
62
|
const snippetKindLabel = SNIPPET_KIND_LABELS[snippet.kind]
|
|
@@ -93,7 +93,7 @@ export function EditMediaDialogContent({
|
|
|
93
93
|
<DrawerContent className="h-full w-full overflow-hidden">
|
|
94
94
|
<div
|
|
95
95
|
ref={handleDrawerContainerRef}
|
|
96
|
-
className="pointer-events-none absolute inset-3 z-20 overflow-hidden rounded-
|
|
96
|
+
className="pointer-events-none absolute inset-3 z-20 overflow-hidden rounded-lg"
|
|
97
97
|
/>
|
|
98
98
|
<div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden">
|
|
99
99
|
<DrawerHeader>
|
|
@@ -107,7 +107,7 @@ export function EditMediaDialogContent({
|
|
|
107
107
|
>
|
|
108
108
|
<Card>
|
|
109
109
|
<CardContent className="p-0">
|
|
110
|
-
<div className="relative aspect-video overflow-hidden rounded-
|
|
110
|
+
<div className="relative aspect-video overflow-hidden rounded-lg bg-background">
|
|
111
111
|
<MediaPreview media={media} showMetadata />
|
|
112
112
|
</div>
|
|
113
113
|
</CardContent>
|
package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx
CHANGED
|
@@ -90,7 +90,7 @@ export function MediaUrlImporter({ onImportFromUrl, accept, className }: MediaUr
|
|
|
90
90
|
return (
|
|
91
91
|
<div
|
|
92
92
|
className={cn(
|
|
93
|
-
'flex items-center justify-center transition-colors rounded-
|
|
93
|
+
'flex items-center justify-center transition-colors rounded-lg border bg-input border-border overflow-hidden h-full flex-col p-5 gap-5',
|
|
94
94
|
className
|
|
95
95
|
)}
|
|
96
96
|
>
|
|
@@ -16,9 +16,13 @@ export function SortIndicator({ direction }: { direction: false | 'asc' | 'desc'
|
|
|
16
16
|
|
|
17
17
|
return (
|
|
18
18
|
<Icon
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
className={cn(
|
|
21
|
+
'size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-visible:opacity-100 group-hover/resize-header:opacity-100',
|
|
22
|
+
{
|
|
23
|
+
'text-foreground': direction !== false
|
|
24
|
+
}
|
|
25
|
+
)}
|
|
22
26
|
/>
|
|
23
27
|
)
|
|
24
28
|
}
|
|
@@ -10,12 +10,14 @@ const coreNav: AdminNavigationItem[] = [
|
|
|
10
10
|
label: 'Overview',
|
|
11
11
|
href: '/admin',
|
|
12
12
|
icon: House,
|
|
13
|
+
group: 'General',
|
|
13
14
|
position: 0
|
|
14
15
|
},
|
|
15
16
|
{
|
|
16
17
|
label: 'Media',
|
|
17
18
|
href: '/admin/media',
|
|
18
19
|
icon: ImagePlay,
|
|
20
|
+
group: 'General',
|
|
19
21
|
position: 1
|
|
20
22
|
}
|
|
21
23
|
]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { normalizeCount } from '@admin/utils/editor/table-input'
|
|
4
|
+
import { insertContentEditorTable } from '@admin/utils/editor/tiptap'
|
|
5
|
+
import type { Editor } from '@tiptap/core'
|
|
6
|
+
import * as React from 'react'
|
|
7
|
+
|
|
8
|
+
const DEFAULT_TABLE_ROWS = 3
|
|
9
|
+
const DEFAULT_TABLE_COLS = 3
|
|
10
|
+
const MIN_TABLE_ROWS = 2
|
|
11
|
+
const MIN_TABLE_COLS = 1
|
|
12
|
+
|
|
13
|
+
interface UseTableButtonOptions {
|
|
14
|
+
disabled?: boolean
|
|
15
|
+
editor?: Editor | null
|
|
16
|
+
onInsertTable?: (size: { cols: number; rows: number }) => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useTableButton({ disabled, editor, onInsertTable }: UseTableButtonOptions) {
|
|
20
|
+
const [isOpen, setIsOpen] = React.useState(false)
|
|
21
|
+
const [rows, setRows] = React.useState(String(DEFAULT_TABLE_ROWS))
|
|
22
|
+
const [cols, setCols] = React.useState(String(DEFAULT_TABLE_COLS))
|
|
23
|
+
const rowsId = React.useId()
|
|
24
|
+
const colsId = React.useId()
|
|
25
|
+
const canInsert = Boolean(onInsertTable || editor?.isEditable)
|
|
26
|
+
const isDisabled = disabled || !canInsert
|
|
27
|
+
|
|
28
|
+
const closePopover = React.useCallback(() => {
|
|
29
|
+
setIsOpen(false)
|
|
30
|
+
window.setTimeout(() => setIsOpen(false), 0)
|
|
31
|
+
}, [])
|
|
32
|
+
|
|
33
|
+
const insertTable = React.useCallback(() => {
|
|
34
|
+
if (isDisabled) return
|
|
35
|
+
|
|
36
|
+
const rowCount = normalizeCount(rows, DEFAULT_TABLE_ROWS, MIN_TABLE_ROWS)
|
|
37
|
+
const colCount = normalizeCount(cols, DEFAULT_TABLE_COLS, MIN_TABLE_COLS)
|
|
38
|
+
|
|
39
|
+
if (onInsertTable) {
|
|
40
|
+
onInsertTable({ cols: colCount, rows: rowCount })
|
|
41
|
+
closePopover()
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!editor) return
|
|
46
|
+
|
|
47
|
+
insertContentEditorTable(editor, rowCount, colCount)
|
|
48
|
+
closePopover()
|
|
49
|
+
}, [closePopover, cols, editor, isDisabled, onInsertTable, rows])
|
|
50
|
+
|
|
51
|
+
const handleKeyDown = React.useCallback(
|
|
52
|
+
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
53
|
+
if (event.key !== 'Enter') return
|
|
54
|
+
|
|
55
|
+
event.preventDefault()
|
|
56
|
+
event.stopPropagation()
|
|
57
|
+
insertTable()
|
|
58
|
+
},
|
|
59
|
+
[insertTable]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const handleRowsChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
|
63
|
+
setRows(event.target.value)
|
|
64
|
+
}, [])
|
|
65
|
+
|
|
66
|
+
const handleColsChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
|
67
|
+
setCols(event.target.value)
|
|
68
|
+
}, [])
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
cols,
|
|
72
|
+
colsId,
|
|
73
|
+
handleColsChange,
|
|
74
|
+
handleKeyDown,
|
|
75
|
+
handleRowsChange,
|
|
76
|
+
insertTable,
|
|
77
|
+
isDisabled,
|
|
78
|
+
isOpen,
|
|
79
|
+
minCols: MIN_TABLE_COLS,
|
|
80
|
+
minRows: MIN_TABLE_ROWS,
|
|
81
|
+
rows,
|
|
82
|
+
rowsId,
|
|
83
|
+
setIsOpen
|
|
84
|
+
}
|
|
85
|
+
}
|