betterstart-cli 0.0.12 → 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/plugin.ts +1 -1
- package/dist/assets/adapters/next/plugins/blog/schemas/menus.json +155 -0
- package/dist/assets/adapters/next/plugins/blog/schemas/posts.json +2 -7
- package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar.tsx +9 -3
- 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 +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/dev-mode-integrate.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/entity-versions/entity-versions-drawer.tsx +1 -1
- package/dist/assets/adapters/next/templates/init/components/shared/page-header.tsx +20 -17
- package/dist/assets/adapters/next/templates/init/components/shared/sort-indicator.tsx +7 -3
- package/dist/assets/adapters/next/templates/init/data/navigation.ts +4 -1
- package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-slash-menu.ts +28 -2
- package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor.ts +22 -1
- package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-table-button.ts +85 -0
- package/dist/assets/adapters/next/templates/init/hooks/use-audit-log.ts +23 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/cleanup-audit-logs.ts +63 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/get-audit-logs.ts +122 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/index.ts +19 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/record-audit-event.ts +37 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/register.ts +13 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/request-metadata.ts +37 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/audit/types.ts +77 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/forms/upsert-form-settings.ts +3 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/create-media.ts +19 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media-bulk.ts +23 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/delete-media.ts +21 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/media/update-media.ts +23 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/profile/update-email.ts +17 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-files.ts +3 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/upload/upload-media-from-url.ts +3 -0
- package/dist/assets/adapters/next/templates/init/lib/actions/users/create-user.ts +19 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/users/delete-user.ts +23 -1
- package/dist/assets/adapters/next/templates/init/lib/actions/users/update-user-role.ts +23 -1
- package/dist/assets/adapters/next/templates/init/lib/db/core/schema.ts +49 -0
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/index.ts +6 -1
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/register.ts +3 -0
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/registry.ts +36 -1
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/runner.ts +117 -12
- package/dist/assets/adapters/next/templates/init/lib/lifecycle-hooks/types.ts +35 -1
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-detail-drawer.tsx +104 -0
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-detail-row.tsx +15 -0
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page-content.tsx +565 -0
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page-skeleton.tsx +7 -0
- package/dist/assets/adapters/next/templates/init/pages/audit-log/audit-log-page.tsx +14 -0
- 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/audit/audit.ts +54 -0
- package/dist/assets/adapters/next/templates/init/utils/editor/tiptap.ts +7 -32
- 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/horizontal-rule-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/index.tsx +6 -0
- package/dist/assets/shared-assets/react-admin/custom/content-editor/main-toolbar-content.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/math-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/math-editor-controls.tsx +27 -40
- package/dist/assets/shared-assets/react-admin/custom/content-editor/math-popover-button.tsx +0 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/mobile-toolbar-content.tsx +4 -4
- package/dist/assets/shared-assets/react-admin/custom/content-editor/mode-toggle-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/selection-bubble-menu.tsx +45 -8
- package/dist/assets/shared-assets/react-admin/custom/content-editor/slash-command-menu.tsx +153 -27
- package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode-dropdown-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +9 -11
- package/dist/assets/shared-assets/react-admin/custom/content-editor/table-bubble-menu.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/table-button.tsx +24 -67
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/blockquote-button/blockquote-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/code-block-button/code-block-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/color-highlight-popover-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/color-highlight-popover-content.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx +11 -2
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-popover/source-color-highlight-popover.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu-item.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx +9 -4
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-control-popover.tsx +5 -12
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-main.tsx +19 -45
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-popover.tsx +2 -3
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/list-dropdown-menu/list-dropdown-menu-item.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx +9 -4
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/mark-button/mark-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/undo-redo-button/undo-redo-button.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/date-range-picker.tsx +2 -2
- package/dist/assets/shared-assets/react-admin/custom/dynamic-list-field.tsx +20 -8
- package/dist/assets/shared-assets/react-admin/custom/media-gallery-field.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/custom/nested-object-list-field.tsx +211 -0
- package/dist/assets/shared-assets/react-admin/schema.json +136 -23
- package/dist/assets/shared-assets/react-admin/ui/button.tsx +18 -18
- package/dist/assets/shared-assets/react-admin/ui/card.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 +27 -3
- package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +9 -5
- package/dist/assets/shared-assets/react-admin/ui/dropdown-menu.tsx +27 -12
- package/dist/assets/shared-assets/react-admin/ui/form.tsx +1 -1
- package/dist/assets/shared-assets/react-admin/ui/sidebar.tsx +4 -4
- package/dist/cli.js +5396 -2385
- package/dist/cli.js.map +1 -1
- package/package.json +10 -2
|
@@ -4,16 +4,9 @@ import { Button } from '@admin/components/ui/button'
|
|
|
4
4
|
import { Input } from '@admin/components/ui/input'
|
|
5
5
|
import { Label } from '@admin/components/ui/label'
|
|
6
6
|
import { Popover, PopoverContent, PopoverTrigger } from '@admin/components/ui/popover'
|
|
7
|
-
import {
|
|
8
|
-
import { insertContentEditorTable } from '@admin/utils/editor/tiptap'
|
|
7
|
+
import { useTableButton } from '@admin/hooks/content-editor/use-table-button'
|
|
9
8
|
import type { Editor } from '@tiptap/core'
|
|
10
9
|
import { TableIcon } from 'lucide-react'
|
|
11
|
-
import * as React from 'react'
|
|
12
|
-
|
|
13
|
-
const DEFAULT_TABLE_ROWS = 3
|
|
14
|
-
const DEFAULT_TABLE_COLS = 3
|
|
15
|
-
const MIN_TABLE_ROWS = 2
|
|
16
|
-
const MIN_TABLE_COLS = 1
|
|
17
10
|
|
|
18
11
|
interface TableButtonProps {
|
|
19
12
|
disabled?: boolean
|
|
@@ -22,92 +15,56 @@ interface TableButtonProps {
|
|
|
22
15
|
}
|
|
23
16
|
|
|
24
17
|
export function TableButton({ disabled, editor, onInsertTable }: TableButtonProps) {
|
|
25
|
-
const
|
|
26
|
-
const [rows, setRows] = React.useState(String(DEFAULT_TABLE_ROWS))
|
|
27
|
-
const [cols, setCols] = React.useState(String(DEFAULT_TABLE_COLS))
|
|
28
|
-
const rowsId = React.useId()
|
|
29
|
-
const colsId = React.useId()
|
|
30
|
-
const canInsert = Boolean(onInsertTable || editor?.isEditable)
|
|
31
|
-
|
|
32
|
-
const closePopover = React.useCallback(() => {
|
|
33
|
-
setIsOpen(false)
|
|
34
|
-
window.setTimeout(() => setIsOpen(false), 0)
|
|
35
|
-
}, [])
|
|
36
|
-
|
|
37
|
-
const insertTable = React.useCallback(() => {
|
|
38
|
-
if (disabled || !canInsert) return
|
|
39
|
-
|
|
40
|
-
const rowCount = normalizeCount(rows, DEFAULT_TABLE_ROWS, MIN_TABLE_ROWS)
|
|
41
|
-
const colCount = normalizeCount(cols, DEFAULT_TABLE_COLS, MIN_TABLE_COLS)
|
|
42
|
-
|
|
43
|
-
if (onInsertTable) {
|
|
44
|
-
onInsertTable({ cols: colCount, rows: rowCount })
|
|
45
|
-
closePopover()
|
|
46
|
-
return
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (!editor) return
|
|
50
|
-
|
|
51
|
-
insertContentEditorTable(editor, rowCount, colCount)
|
|
52
|
-
closePopover()
|
|
53
|
-
}, [canInsert, closePopover, cols, disabled, editor, onInsertTable, rows])
|
|
54
|
-
|
|
55
|
-
const handleKeyDown = React.useCallback(
|
|
56
|
-
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
57
|
-
if (event.key !== 'Enter') return
|
|
58
|
-
|
|
59
|
-
event.preventDefault()
|
|
60
|
-
event.stopPropagation()
|
|
61
|
-
insertTable()
|
|
62
|
-
},
|
|
63
|
-
[insertTable]
|
|
64
|
-
)
|
|
18
|
+
const tableButton = useTableButton({ disabled, editor, onInsertTable })
|
|
65
19
|
|
|
66
20
|
return (
|
|
67
|
-
<Popover open={isOpen} onOpenChange={setIsOpen}>
|
|
21
|
+
<Popover open={tableButton.isOpen} onOpenChange={tableButton.setIsOpen}>
|
|
68
22
|
<PopoverTrigger asChild>
|
|
69
23
|
<Button
|
|
70
24
|
type="button"
|
|
71
25
|
variant="ghost"
|
|
72
26
|
size="sm"
|
|
73
|
-
disabled={
|
|
27
|
+
disabled={tableButton.isDisabled}
|
|
74
28
|
aria-label="Insert table"
|
|
75
29
|
title="Table"
|
|
76
|
-
onPointerDown={(event) => event.preventDefault()}
|
|
77
|
-
onClick={() => setIsOpen((current) => !current)}
|
|
78
30
|
>
|
|
79
|
-
<TableIcon
|
|
31
|
+
<TableIcon />
|
|
80
32
|
<span className="tiptap-button-text">Table</span>
|
|
81
33
|
</Button>
|
|
82
34
|
</PopoverTrigger>
|
|
83
|
-
<PopoverContent align="start" className="w-
|
|
84
|
-
<div className="flex flex-col gap-3" onKeyDownCapture={handleKeyDown}>
|
|
35
|
+
<PopoverContent align="start" className="w-72 p-4">
|
|
36
|
+
<div className="flex flex-col gap-3" onKeyDownCapture={tableButton.handleKeyDown}>
|
|
85
37
|
<div className="grid grid-cols-2 gap-2">
|
|
86
38
|
<div className="flex flex-col gap-1.5">
|
|
87
|
-
<Label htmlFor={rowsId}>Rows</Label>
|
|
39
|
+
<Label htmlFor={tableButton.rowsId}>Rows</Label>
|
|
88
40
|
<Input
|
|
89
|
-
id={rowsId}
|
|
41
|
+
id={tableButton.rowsId}
|
|
90
42
|
inputMode="numeric"
|
|
91
|
-
min={
|
|
92
|
-
onChange={
|
|
43
|
+
min={tableButton.minRows}
|
|
44
|
+
onChange={tableButton.handleRowsChange}
|
|
93
45
|
type="number"
|
|
94
|
-
value={rows}
|
|
46
|
+
value={tableButton.rows}
|
|
95
47
|
/>
|
|
96
48
|
</div>
|
|
97
49
|
<div className="flex flex-col gap-1.5">
|
|
98
|
-
<Label htmlFor={colsId}>Cols</Label>
|
|
50
|
+
<Label htmlFor={tableButton.colsId}>Cols</Label>
|
|
99
51
|
<Input
|
|
100
|
-
id={colsId}
|
|
52
|
+
id={tableButton.colsId}
|
|
101
53
|
inputMode="numeric"
|
|
102
|
-
min={
|
|
103
|
-
onChange={
|
|
54
|
+
min={tableButton.minCols}
|
|
55
|
+
onChange={tableButton.handleColsChange}
|
|
104
56
|
type="number"
|
|
105
|
-
value={cols}
|
|
57
|
+
value={tableButton.cols}
|
|
106
58
|
/>
|
|
107
59
|
</div>
|
|
108
60
|
</div>
|
|
109
|
-
<Button
|
|
110
|
-
|
|
61
|
+
<Button
|
|
62
|
+
type="button"
|
|
63
|
+
variant="default"
|
|
64
|
+
disabled={tableButton.isDisabled}
|
|
65
|
+
onClick={tableButton.insertTable}
|
|
66
|
+
>
|
|
67
|
+
Insert
|
|
111
68
|
</Button>
|
|
112
69
|
</div>
|
|
113
70
|
</PopoverContent>
|
|
@@ -102,7 +102,7 @@ export function BlockquoteButton({
|
|
|
102
102
|
>
|
|
103
103
|
{children ?? (
|
|
104
104
|
<>
|
|
105
|
-
<Icon
|
|
105
|
+
<Icon />
|
|
106
106
|
{text && <span className="tiptap-button-text">{text}</span>}
|
|
107
107
|
{shouldShowControlShortcut(shortcut) && (
|
|
108
108
|
<BlockquoteShortcutBadge shortcutKeys={shortcutKeys} />
|
|
@@ -100,7 +100,7 @@ export function CodeBlockButton({
|
|
|
100
100
|
>
|
|
101
101
|
{children ?? (
|
|
102
102
|
<>
|
|
103
|
-
<Icon
|
|
103
|
+
<Icon />
|
|
104
104
|
{text && <span className="tiptap-button-text">{text}</span>}
|
|
105
105
|
{shouldShowControlShortcut(shortcut) && (
|
|
106
106
|
<CodeBlockShortcutBadge shortcutKeys={shortcutKeys} />
|
|
@@ -33,6 +33,7 @@ export interface ColorHighlightPopoverProps
|
|
|
33
33
|
* If not provided, defaults to a predefined set of colors.
|
|
34
34
|
*/
|
|
35
35
|
colors?: HighlightColor[]
|
|
36
|
+
onOpenChange?: (isOpen: boolean) => void
|
|
36
37
|
tooltip?: ControlTooltip
|
|
37
38
|
useColorValue?: boolean
|
|
38
39
|
}
|
|
@@ -43,6 +44,7 @@ export function ColorHighlightPopover({
|
|
|
43
44
|
colors = DEFAULT_HIGHLIGHT_COLORS,
|
|
44
45
|
useColorValue = false,
|
|
45
46
|
onApplied,
|
|
47
|
+
onOpenChange,
|
|
46
48
|
tooltip,
|
|
47
49
|
disabled,
|
|
48
50
|
ref,
|
|
@@ -60,11 +62,18 @@ export function ColorHighlightPopover({
|
|
|
60
62
|
const isActive = highlightState.isActive
|
|
61
63
|
const label = highlightState.label
|
|
62
64
|
const Icon = highlightState.Icon
|
|
65
|
+
const handleOpenChange = React.useCallback(
|
|
66
|
+
(open: boolean) => {
|
|
67
|
+
setIsOpen(open)
|
|
68
|
+
onOpenChange?.(open)
|
|
69
|
+
},
|
|
70
|
+
[onOpenChange]
|
|
71
|
+
)
|
|
63
72
|
|
|
64
73
|
if (!isVisible) return null
|
|
65
74
|
|
|
66
75
|
return (
|
|
67
|
-
<Popover open={isOpen} onOpenChange={
|
|
76
|
+
<Popover open={isOpen} onOpenChange={handleOpenChange}>
|
|
68
77
|
<PopoverTrigger asChild>
|
|
69
78
|
<ColorHighlightPopoverButton
|
|
70
79
|
disabled={disabled || !canColorHighlight}
|
|
@@ -77,7 +86,7 @@ export function ColorHighlightPopover({
|
|
|
77
86
|
{...props}
|
|
78
87
|
ref={ref}
|
|
79
88
|
>
|
|
80
|
-
<Icon
|
|
89
|
+
<Icon />
|
|
81
90
|
</ColorHighlightPopoverButton>
|
|
82
91
|
</PopoverTrigger>
|
|
83
92
|
<PopoverContent
|
|
@@ -74,7 +74,7 @@ export function HeadingDropdownMenu({
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
return (
|
|
77
|
-
<DropdownMenu open={isOpen} onOpenChange={handleOpenChange}>
|
|
77
|
+
<DropdownMenu modal={false} open={isOpen} onOpenChange={handleOpenChange}>
|
|
78
78
|
<DropdownMenuTrigger asChild>
|
|
79
79
|
<Button
|
|
80
80
|
type="button"
|
|
@@ -91,21 +91,26 @@ export function HeadingDropdownMenu({
|
|
|
91
91
|
className="w-auto px-2"
|
|
92
92
|
{...buttonProps}
|
|
93
93
|
ref={ref}
|
|
94
|
-
onPointerDown={(
|
|
94
|
+
onPointerDown={(event) => event.preventDefault()}
|
|
95
95
|
onClick={() => handleOpenChange(!isOpen)}
|
|
96
96
|
>
|
|
97
97
|
{children ? (
|
|
98
98
|
children
|
|
99
99
|
) : (
|
|
100
100
|
<>
|
|
101
|
-
<Icon
|
|
101
|
+
<Icon />
|
|
102
102
|
<ChevronDownIcon className="tiptap-button-dropdown-small" />
|
|
103
103
|
</>
|
|
104
104
|
)}
|
|
105
105
|
</Button>
|
|
106
106
|
</DropdownMenuTrigger>
|
|
107
107
|
|
|
108
|
-
<DropdownMenuContent
|
|
108
|
+
<DropdownMenuContent
|
|
109
|
+
align="start"
|
|
110
|
+
className="w-auto min-w-40"
|
|
111
|
+
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
112
|
+
portalled={false}
|
|
113
|
+
>
|
|
109
114
|
<DropdownMenuGroup>
|
|
110
115
|
{levels.map((level) => (
|
|
111
116
|
<HeadingDropdownMenuItem key={`heading-${level}`} editor={editor} level={level} />
|
|
@@ -9,6 +9,7 @@ import { LinkMain, type LinkMainProps } from './link-main'
|
|
|
9
9
|
|
|
10
10
|
export interface LinkControlPopoverProps extends Omit<LinkButtonProps, 'type'>, LinkMainProps {
|
|
11
11
|
canSet?: boolean
|
|
12
|
+
isActive?: boolean
|
|
12
13
|
label?: string
|
|
13
14
|
onOpenChange?: (isOpen: boolean) => void
|
|
14
15
|
open?: boolean
|
|
@@ -17,12 +18,11 @@ export interface LinkControlPopoverProps extends Omit<LinkButtonProps, 'type'>,
|
|
|
17
18
|
export function LinkControlPopover({
|
|
18
19
|
canSet = true,
|
|
19
20
|
children,
|
|
20
|
-
isActive,
|
|
21
|
+
isActive = false,
|
|
21
22
|
label = 'Link',
|
|
22
23
|
onClick,
|
|
23
24
|
onOpenChange,
|
|
24
25
|
open,
|
|
25
|
-
openLink,
|
|
26
26
|
ref,
|
|
27
27
|
removeLink,
|
|
28
28
|
setLink,
|
|
@@ -71,19 +71,12 @@ export function LinkControlPopover({
|
|
|
71
71
|
onClick={handleClick}
|
|
72
72
|
ref={ref}
|
|
73
73
|
>
|
|
74
|
-
{children ?? <LinkIcon
|
|
74
|
+
{children ?? <LinkIcon />}
|
|
75
75
|
</LinkButton>
|
|
76
76
|
</PopoverTrigger>
|
|
77
77
|
|
|
78
|
-
<PopoverContent className="w-auto max-w-[calc(100vw-2rem)]
|
|
79
|
-
<LinkMain
|
|
80
|
-
url={url}
|
|
81
|
-
setUrl={setUrl}
|
|
82
|
-
setLink={handleSetLink}
|
|
83
|
-
removeLink={removeLink}
|
|
84
|
-
openLink={openLink}
|
|
85
|
-
isActive={isActive}
|
|
86
|
-
/>
|
|
78
|
+
<PopoverContent className="w-auto max-w-[calc(100vw-2rem)]">
|
|
79
|
+
<LinkMain url={url} setUrl={setUrl} setLink={handleSetLink} removeLink={removeLink} />
|
|
87
80
|
</PopoverContent>
|
|
88
81
|
</Popover>
|
|
89
82
|
)
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Button } from '@admin/components/ui/button'
|
|
4
4
|
import { InputGroup, InputGroupInput } from '@admin/components/ui/input-group'
|
|
5
|
-
import {
|
|
6
|
-
import { CornerDownLeftIcon, ExternalLinkIcon, TrashIcon } from 'lucide-react'
|
|
5
|
+
import { TrashIcon } from 'lucide-react'
|
|
7
6
|
import type * as React from 'react'
|
|
8
7
|
|
|
9
8
|
export interface LinkMainProps {
|
|
@@ -23,17 +22,9 @@ export interface LinkMainProps {
|
|
|
23
22
|
* Function to remove the link from the editor.
|
|
24
23
|
*/
|
|
25
24
|
removeLink: () => void
|
|
26
|
-
/**
|
|
27
|
-
* Function to open the link.
|
|
28
|
-
*/
|
|
29
|
-
openLink: () => void
|
|
30
|
-
/**
|
|
31
|
-
* Whether the link is currently active in the editor.
|
|
32
|
-
*/
|
|
33
|
-
isActive: boolean
|
|
34
25
|
}
|
|
35
26
|
|
|
36
|
-
export function LinkMain({ url, setUrl, setLink, removeLink
|
|
27
|
+
export function LinkMain({ url, setUrl, setLink, removeLink }: LinkMainProps) {
|
|
37
28
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
38
29
|
if (event.key === 'Enter') {
|
|
39
30
|
event.preventDefault()
|
|
@@ -42,7 +33,7 @@ export function LinkMain({ url, setUrl, setLink, removeLink, openLink, isActive
|
|
|
42
33
|
}
|
|
43
34
|
|
|
44
35
|
return (
|
|
45
|
-
<div className="flex min-w-max items-center gap-
|
|
36
|
+
<div className="flex flex-col min-w-max items-center gap-2">
|
|
46
37
|
<InputGroup className="h-9 min-w-64">
|
|
47
38
|
<InputGroupInput
|
|
48
39
|
type="url"
|
|
@@ -57,40 +48,23 @@ export function LinkMain({ url, setUrl, setLink, removeLink, openLink, isActive
|
|
|
57
48
|
/>
|
|
58
49
|
</InputGroup>
|
|
59
50
|
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
size="icon-sm"
|
|
67
|
-
>
|
|
68
|
-
<CornerDownLeftIcon className="tiptap-button-icon" />
|
|
69
|
-
</Button>
|
|
70
|
-
|
|
71
|
-
<Separator orientation="vertical" decorative className="h-6 my-auto self-center" />
|
|
72
|
-
|
|
73
|
-
<Button
|
|
74
|
-
type="button"
|
|
75
|
-
onClick={openLink}
|
|
76
|
-
title="Open in new window"
|
|
77
|
-
disabled={!url && !isActive}
|
|
78
|
-
variant="ghost"
|
|
79
|
-
size="icon-sm"
|
|
80
|
-
>
|
|
81
|
-
<ExternalLinkIcon className="tiptap-button-icon" />
|
|
82
|
-
</Button>
|
|
51
|
+
<div className="flex items-center gap-1 w-full">
|
|
52
|
+
{url && (
|
|
53
|
+
<Button type="button" onClick={removeLink} title="Remove link" variant="destructive">
|
|
54
|
+
<TrashIcon />
|
|
55
|
+
</Button>
|
|
56
|
+
)}
|
|
83
57
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
</
|
|
58
|
+
<Button
|
|
59
|
+
type="button"
|
|
60
|
+
onClick={setLink}
|
|
61
|
+
title="Apply link"
|
|
62
|
+
variant="default"
|
|
63
|
+
className="flex-1"
|
|
64
|
+
>
|
|
65
|
+
Insert
|
|
66
|
+
</Button>
|
|
67
|
+
</div>
|
|
94
68
|
</div>
|
|
95
69
|
)
|
|
96
70
|
}
|
|
@@ -57,7 +57,7 @@ export function LinkPopover({
|
|
|
57
57
|
}: LinkPopoverProps) {
|
|
58
58
|
const { editor } = useTiptapEditor(providedEditor)
|
|
59
59
|
|
|
60
|
-
const { isVisible, canSet, isActive, url, setUrl, setLink, removeLink,
|
|
60
|
+
const { isVisible, canSet, isActive, url, setUrl, setLink, removeLink, label, Icon } =
|
|
61
61
|
useLinkPopover({
|
|
62
62
|
editor,
|
|
63
63
|
hideWhenUnavailable: shouldHideUnavailableControl(availability),
|
|
@@ -105,7 +105,6 @@ export function LinkPopover({
|
|
|
105
105
|
onClick={onClick}
|
|
106
106
|
onOpenChange={handleOnOpenChange}
|
|
107
107
|
open={isOpen}
|
|
108
|
-
openLink={openLink}
|
|
109
108
|
removeLink={removeLink}
|
|
110
109
|
setLink={setLink}
|
|
111
110
|
setUrl={setUrl}
|
|
@@ -113,7 +112,7 @@ export function LinkPopover({
|
|
|
113
112
|
{...buttonProps}
|
|
114
113
|
ref={ref}
|
|
115
114
|
>
|
|
116
|
-
{children ?? <Icon
|
|
115
|
+
{children ?? <Icon />}
|
|
117
116
|
</LinkControlPopover>
|
|
118
117
|
)
|
|
119
118
|
}
|
|
@@ -73,7 +73,7 @@ export function ListDropdownMenu({
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
return (
|
|
76
|
-
<DropdownMenu open={isOpen} onOpenChange={handleOnOpenChange}>
|
|
76
|
+
<DropdownMenu modal={false} open={isOpen} onOpenChange={handleOnOpenChange}>
|
|
77
77
|
<DropdownMenuTrigger asChild>
|
|
78
78
|
<Button
|
|
79
79
|
type="button"
|
|
@@ -88,15 +88,20 @@ export function ListDropdownMenu({
|
|
|
88
88
|
size="icon-sm"
|
|
89
89
|
className="w-auto px-2"
|
|
90
90
|
{...props}
|
|
91
|
-
onPointerDown={(
|
|
91
|
+
onPointerDown={(event) => event.preventDefault()}
|
|
92
92
|
onClick={() => handleOnOpenChange(!isOpen)}
|
|
93
93
|
>
|
|
94
|
-
<Icon
|
|
94
|
+
<Icon />
|
|
95
95
|
<ChevronDownIcon className="tiptap-button-dropdown-small" />
|
|
96
96
|
</Button>
|
|
97
97
|
</DropdownMenuTrigger>
|
|
98
98
|
|
|
99
|
-
<DropdownMenuContent
|
|
99
|
+
<DropdownMenuContent
|
|
100
|
+
align="start"
|
|
101
|
+
className="w-auto min-w-40"
|
|
102
|
+
onCloseAutoFocus={(event) => event.preventDefault()}
|
|
103
|
+
portalled={false}
|
|
104
|
+
>
|
|
100
105
|
<DropdownMenuGroup>
|
|
101
106
|
{filteredLists.map((option) => (
|
|
102
107
|
<ListDropdownMenuItem
|
|
@@ -105,7 +105,7 @@ export function MarkButton({
|
|
|
105
105
|
>
|
|
106
106
|
{children ?? (
|
|
107
107
|
<>
|
|
108
|
-
<Icon
|
|
108
|
+
<Icon />
|
|
109
109
|
{text && <span className="tiptap-button-text">{text}</span>}
|
|
110
110
|
{shouldShowControlShortcut(shortcut) && (
|
|
111
111
|
<MarkShortcutBadge type={type} shortcutKeys={shortcutKeys} />
|
|
@@ -103,7 +103,7 @@ export function UndoRedoButton({
|
|
|
103
103
|
>
|
|
104
104
|
{children ?? (
|
|
105
105
|
<>
|
|
106
|
-
<Icon
|
|
106
|
+
<Icon />
|
|
107
107
|
{text && <span className="tiptap-button-text">{text}</span>}
|
|
108
108
|
{shouldShowControlShortcut(shortcut) && (
|
|
109
109
|
<HistoryShortcutBadge action={action} shortcutKeys={shortcutKeys} />
|
|
@@ -134,9 +134,9 @@ export function DateRangePicker({
|
|
|
134
134
|
>
|
|
135
135
|
<PopoverTrigger asChild>
|
|
136
136
|
<Button variant="outline" className={cn('w-[206px]', className)} disabled={disabled}>
|
|
137
|
-
<CalendarIcon
|
|
137
|
+
<CalendarIcon />
|
|
138
138
|
<span className="min-w-0 flex-1 truncate text-left tabular-nums">{triggerLabel}</span>
|
|
139
|
-
<ChevronDown
|
|
139
|
+
<ChevronDown />
|
|
140
140
|
</Button>
|
|
141
141
|
</PopoverTrigger>
|
|
142
142
|
<PopoverContent className="w-[282px] gap-0 overflow-hidden rounded-lg p-0" align="start">
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { Button } from '@admin/components/ui/button'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
FormControl,
|
|
6
|
+
FormDescription,
|
|
7
|
+
FormField,
|
|
8
|
+
FormItem,
|
|
9
|
+
FormLabel,
|
|
10
|
+
FormMessage
|
|
11
|
+
} from '@admin/components/ui/form'
|
|
5
12
|
import { Input } from '@admin/components/ui/input'
|
|
6
|
-
import { Label } from '@admin/components/ui/label'
|
|
7
13
|
import { cn } from '@admin/utils/shared/cn'
|
|
8
14
|
import { Plus, Trash2 } from 'lucide-react'
|
|
9
15
|
import { useFieldArray, useFormContext } from 'react-hook-form'
|
|
@@ -46,12 +52,18 @@ export function DynamicListField({
|
|
|
46
52
|
return (
|
|
47
53
|
<div className={cn('space-y-4', className)}>
|
|
48
54
|
<div className="flex items-start justify-between gap-3">
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
<FormField
|
|
56
|
+
control={control}
|
|
57
|
+
name={name}
|
|
58
|
+
render={() => (
|
|
59
|
+
<FormItem className="flex flex-col gap-1">
|
|
60
|
+
<FormLabel className={cn({ 'sr-only': hideLabel })}>{label}</FormLabel>
|
|
61
|
+
{description ? (
|
|
62
|
+
<FormDescription className="text-muted-foreground">{description}</FormDescription>
|
|
63
|
+
) : null}
|
|
64
|
+
</FormItem>
|
|
65
|
+
)}
|
|
66
|
+
/>
|
|
55
67
|
<Button
|
|
56
68
|
type="button"
|
|
57
69
|
variant="outline"
|
|
@@ -81,7 +81,7 @@ export function MediaGalleryField({
|
|
|
81
81
|
<>
|
|
82
82
|
<div
|
|
83
83
|
aria-hidden="true"
|
|
84
|
-
className="pointer-events-none absolute inset-0 bg-black/10 opacity-0 backdrop-blur-xs transition-opacity duration-300 ease-out group-hover:opacity-100"
|
|
84
|
+
className="pointer-events-none absolute inset-0 bg-black/10 opacity-0 backdrop-blur-xs transition-opacity duration-300 ease-out group-hover:opacity-100 rounded-lg"
|
|
85
85
|
/>
|
|
86
86
|
<div className="absolute inset-0 flex items-center justify-center gap-1 opacity-0 transition-opacity duration-200 ease-out group-hover:opacity-100">
|
|
87
87
|
<Button
|