InsertButton.tsx157 lines · main
1// @ts-nocheck
2import { PermissionAction } from '@supabase/shared-types/out/constants'
3import { useParams } from 'common'
4import { ArrowUp, ChevronDown, FileText } from 'lucide-react'
5import {
6 Button,
7 cn,
8 DropdownMenu,
9 DropdownMenuContent,
10 DropdownMenuItem,
11 DropdownMenuTrigger,
12} from 'ui'
13
14import { ShortcutBadge } from '@/components/ui/ShortcutBadge'
15import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
16import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
17import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
18import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
19import { useShortcut } from '@/state/shortcuts/useShortcut'
20import { useTableEditorStateSnapshot } from '@/state/table-editor'
21import { useTableEditorTableStateSnapshot } from '@/state/table-editor-table'
22
23export const InsertButton = () => {
24 const { ref: projectRef } = useParams()
25 const { data: org } = useSelectedOrganizationQuery()
26
27 const snap = useTableEditorTableStateSnapshot()
28 const tableEditorSnap = useTableEditorStateSnapshot()
29 const { can: canCreateColumns } = useAsyncCheckPermissions(
30 PermissionAction.TENANT_SQL_ADMIN_WRITE,
31 'columns'
32 )
33 const { mutate: sendEvent } = useSendEventMutation()
34
35 const onAddRow =
36 snap.editable && (snap.table.columns ?? []).length > 0 ? tableEditorSnap.onAddRow : undefined
37 const onAddColumn = snap.editable ? tableEditorSnap.onAddColumn : undefined
38 const onImportData = snap.editable ? tableEditorSnap.onImportData : undefined
39
40 const canAddNew = onAddRow !== undefined || onAddColumn !== undefined
41
42 useShortcut(SHORTCUT_IDS.TABLE_EDITOR_INSERT_ROW, () => onAddRow?.(), {
43 registerInCommandMenu: true,
44 enabled: onAddRow !== undefined && canAddNew && canCreateColumns,
45 })
46 useShortcut(SHORTCUT_IDS.TABLE_EDITOR_INSERT_COLUMN, () => onAddColumn?.(), {
47 registerInCommandMenu: true,
48 enabled: onAddColumn !== undefined && canAddNew && canCreateColumns,
49 })
50 useShortcut(SHORTCUT_IDS.TABLE_EDITOR_IMPORT_CSV, () => onImportData?.(), {
51 registerInCommandMenu: true,
52 enabled: onImportData !== undefined && canAddNew && canCreateColumns,
53 })
54
55 if (!canAddNew || !canCreateColumns) return null
56
57 return (
58 <DropdownMenu>
59 <DropdownMenuTrigger asChild>
60 <Button
61 data-testid="table-editor-insert-new-row"
62 type="primary"
63 size="tiny"
64 icon={<ChevronDown strokeWidth={1.5} />}
65 >
66 Insert
67 </Button>
68 </DropdownMenuTrigger>
69 <DropdownMenuContent side="bottom" align="end">
70 {[
71 ...(onAddRow !== undefined
72 ? [
73 <DropdownMenuItem
74 key="add-row"
75 className="flex items-center group gap-x-3"
76 onClick={onAddRow}
77 >
78 <div className="shrink-0 w-4">
79 <div className="border border-foreground-lighter w-[15px] h-[4px]" />
80 <div className="border border-foreground-lighter w-[15px] h-[4px] my-[2px]" />
81 <div
82 className={cn([
83 'border border-foreground-light w-[15px] h-[4px] translate-x-0.5',
84 'transition duration-200 group-data-highlighted:border-brand group-data-highlighted:translate-x-0',
85 ])}
86 />
87 </div>
88 <p className="flex-1 min-w-0 pr-4">Insert row</p>
89 <ShortcutBadge
90 shortcutId={SHORTCUT_IDS.TABLE_EDITOR_INSERT_ROW}
91 className="shrink-0"
92 />
93 </DropdownMenuItem>,
94 ]
95 : []),
96 ...(onAddColumn !== undefined
97 ? [
98 <DropdownMenuItem key="add-column" className="group gap-x-3" onClick={onAddColumn}>
99 <div className="flex shrink-0 w-4">
100 <div className="border border-foreground-lighter w-[4px] h-[15px]" />
101 <div className="border border-foreground-lighter w-[4px] h-[15px] mx-[2px]" />
102 <div
103 className={cn([
104 'border border-foreground-light w-[4px] h-[15px] -translate-y-0.5',
105 'transition duration-200 group-data-highlighted:border-brand group-data-highlighted:translate-y-0',
106 ])}
107 />
108 </div>
109 <p className="flex-1 min-w-0 pr-4">Insert column</p>
110 <ShortcutBadge
111 shortcutId={SHORTCUT_IDS.TABLE_EDITOR_INSERT_COLUMN}
112 className="shrink-0"
113 />
114 </DropdownMenuItem>,
115 ]
116 : []),
117 ...(onImportData !== undefined
118 ? [
119 <DropdownMenuItem
120 key="import-data"
121 className="group gap-x-3"
122 onClick={() => {
123 onImportData()
124 sendEvent({
125 action: 'import_data_button_clicked',
126 properties: { tableType: 'Existing Table' },
127 groups: {
128 project: projectRef ?? 'Unknown',
129 organization: org?.slug ?? 'Unknown',
130 },
131 })
132 }}
133 >
134 <div className="relative shrink-0 w-4">
135 <FileText size={18} strokeWidth={1.5} className="translate-x-[-2px]" />
136 <ArrowUp
137 className={cn(
138 'transition duration-200 absolute bottom-0 right-0 translate-y-1 opacity-0 bg-brand-400 rounded-full',
139 'group-data-highlighted:translate-y-0 group-data-highlighted:text-brand group-data-highlighted:opacity-100'
140 )}
141 strokeWidth={3}
142 size={12}
143 />
144 </div>
145 <p className="flex-1 min-w-0 pr-4">Import data from CSV</p>
146 <ShortcutBadge
147 shortcutId={SHORTCUT_IDS.TABLE_EDITOR_IMPORT_CSV}
148 className="shrink-0"
149 />
150 </DropdownMenuItem>,
151 ]
152 : []),
153 ]}
154 </DropdownMenuContent>
155 </DropdownMenu>
156 )
157}