@adecore/database 0.17.0-beta.2 → 0.18.0

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.
Files changed (135) hide show
  1. package/README.md +1 -1
  2. package/dist/DatabaseProvider.d.ts +4 -3
  3. package/dist/DatabaseProvider.js +15 -3
  4. package/dist/KeyIcon.d.ts +4 -0
  5. package/dist/KeyIcon.js +14 -0
  6. package/dist/actions.d.ts +12 -0
  7. package/dist/client-context.d.ts +3 -1
  8. package/dist/client-context.js +2 -0
  9. package/dist/code-text.d.ts +1 -0
  10. package/dist/code-text.js +2 -0
  11. package/dist/column-keys.d.ts +5 -0
  12. package/dist/column-keys.js +2 -0
  13. package/dist/connections/ConnectionManager.d.ts +3 -2
  14. package/dist/connections/ConnectionManager.js +27 -16
  15. package/dist/connections/connection-config.js +2 -0
  16. package/dist/console/QueryConsole.d.ts +8 -3
  17. package/dist/console/QueryConsole.js +110 -50
  18. package/dist/console/SqlEditor.d.ts +2 -12
  19. package/dist/console/SqlEditor.js +29 -18
  20. package/dist/console/StatementResultView.d.ts +5 -1
  21. package/dist/console/StatementResultView.js +18 -5
  22. package/dist/console/TransactionControls.js +3 -6
  23. package/dist/console/editor-slot.d.ts +18 -0
  24. package/dist/console/editor-slot.js +1 -0
  25. package/dist/console/result-keys.d.ts +15 -0
  26. package/dist/console/result-keys.js +79 -0
  27. package/dist/designer/ColumnsEditor.js +2 -2
  28. package/dist/designer/DesignerView.d.ts +3 -2
  29. package/dist/designer/DesignerView.js +5 -4
  30. package/dist/designer/SqlPreview.js +2 -1
  31. package/dist/designer/TableDesigner.d.ts +3 -2
  32. package/dist/designer/TableDesigner.js +2 -2
  33. package/dist/explorer/DatabaseExplorer.d.ts +4 -1
  34. package/dist/explorer/DatabaseExplorer.js +79 -23
  35. package/dist/explorer/RowMenu.js +2 -2
  36. package/dist/explorer/expansion.js +2 -2
  37. package/dist/explorer/folders.d.ts +16 -0
  38. package/dist/explorer/folders.js +1 -0
  39. package/dist/explorer/tree.d.ts +55 -4
  40. package/dist/explorer/tree.js +137 -23
  41. package/dist/grid/CellEditor.js +3 -1
  42. package/dist/grid/DataGrid.d.ts +2 -2
  43. package/dist/grid/DataGrid.js +61 -59
  44. package/dist/grid/EnumPicker.js +2 -1
  45. package/dist/grid/GridHeaderCell.d.ts +1 -2
  46. package/dist/grid/GridHeaderCell.js +12 -5
  47. package/dist/grid/GridRowView.d.ts +49 -0
  48. package/dist/grid/GridRowView.js +51 -0
  49. package/dist/grid/RecordView.d.ts +4 -2
  50. package/dist/grid/RecordView.js +71 -22
  51. package/dist/grid/ValueDock.d.ts +3 -1
  52. package/dist/grid/ValueDock.js +9 -3
  53. package/dist/grid/cell-id.d.ts +1 -0
  54. package/dist/grid/cell-id.js +2 -0
  55. package/dist/grid/layout.d.ts +3 -2
  56. package/dist/grid/layout.js +15 -6
  57. package/dist/grid/types.d.ts +8 -1
  58. package/dist/grid/types.js +4 -3
  59. package/dist/index.d.ts +5 -1
  60. package/dist/index.js +2 -0
  61. package/dist/locales/en.json +32 -15
  62. package/dist/locales/nl.json +32 -15
  63. package/dist/protocol/index.d.ts +1 -1
  64. package/dist/protocol/messages.d.ts +1 -1
  65. package/dist/protocol/messages.js +1 -1
  66. package/dist/protocol/schema.d.ts +17 -0
  67. package/dist/structure/StructureView.d.ts +5 -3
  68. package/dist/structure/StructureView.js +8 -6
  69. package/dist/table/CommandField.js +2 -2
  70. package/dist/table/TableStatusBar.js +2 -2
  71. package/dist/table/TableToolbar.d.ts +3 -4
  72. package/dist/table/TableToolbar.js +4 -3
  73. package/dist/table/TableView.d.ts +4 -2
  74. package/dist/table/TableView.js +63 -91
  75. package/dist/table/grid-rows.js +4 -1
  76. package/dist/table/useTableTransfer.d.ts +3 -1
  77. package/dist/table/useTableTransfer.js +19 -5
  78. package/dist/testing/fake.d.ts +3 -1
  79. package/dist/testing/fake.js +7 -1
  80. package/dist/value/ValueEditor.d.ts +9 -0
  81. package/dist/value/ValueEditor.js +102 -0
  82. package/dist/value/ValuePanel.d.ts +1 -1
  83. package/dist/value/ValuePanel.js +3 -94
  84. package/dist/workbench/DatabaseWorkbench.js +4 -7
  85. package/package.json +6 -6
  86. package/src/DatabaseProvider.tsx +24 -5
  87. package/src/KeyIcon.tsx +15 -0
  88. package/src/actions.ts +28 -2
  89. package/src/client-context.ts +5 -1
  90. package/src/code-text.ts +2 -0
  91. package/src/column-keys.ts +8 -0
  92. package/src/connections/ConnectionManager.tsx +98 -68
  93. package/src/connections/connection-config.ts +2 -0
  94. package/src/console/QueryConsole.tsx +251 -150
  95. package/src/console/SqlEditor.tsx +33 -37
  96. package/src/console/StatementResultView.tsx +61 -27
  97. package/src/console/TransactionControls.tsx +8 -11
  98. package/src/console/editor-slot.ts +27 -0
  99. package/src/console/result-keys.ts +109 -0
  100. package/src/designer/ColumnsEditor.tsx +3 -3
  101. package/src/designer/DesignerView.tsx +14 -3
  102. package/src/designer/SqlPreview.tsx +2 -1
  103. package/src/designer/TableDesigner.tsx +5 -2
  104. package/src/explorer/DatabaseExplorer.tsx +170 -26
  105. package/src/explorer/RowMenu.tsx +2 -2
  106. package/src/explorer/expansion.ts +4 -4
  107. package/src/explorer/folders.ts +25 -0
  108. package/src/explorer/tree.ts +219 -28
  109. package/src/grid/CellEditor.tsx +3 -2
  110. package/src/grid/DataGrid.tsx +114 -176
  111. package/src/grid/EnumPicker.tsx +2 -1
  112. package/src/grid/GridHeaderCell.tsx +14 -9
  113. package/src/grid/GridRowView.tsx +184 -0
  114. package/src/grid/RecordView.tsx +188 -75
  115. package/src/grid/ValueDock.tsx +12 -3
  116. package/src/grid/cell-id.ts +2 -0
  117. package/src/grid/layout.ts +16 -6
  118. package/src/grid/types.ts +15 -3
  119. package/src/index.ts +5 -1
  120. package/src/locales/en.json +32 -15
  121. package/src/locales/nl.json +32 -15
  122. package/src/protocol/index.ts +13 -1
  123. package/src/protocol/messages.ts +1 -1
  124. package/src/protocol/schema.ts +28 -0
  125. package/src/structure/StructureView.tsx +16 -6
  126. package/src/table/CommandField.tsx +2 -2
  127. package/src/table/TableStatusBar.tsx +3 -3
  128. package/src/table/TableToolbar.tsx +107 -92
  129. package/src/table/TableView.tsx +95 -132
  130. package/src/table/grid-rows.ts +5 -3
  131. package/src/table/useTableTransfer.ts +21 -6
  132. package/src/testing/fake.ts +18 -1
  133. package/src/value/ValueEditor.tsx +213 -0
  134. package/src/value/ValuePanel.tsx +4 -206
  135. package/src/workbench/DatabaseWorkbench.tsx +9 -10
@@ -1,4 +1,4 @@
1
- import type { Ref } from 'react';
1
+ import type { ReactNode, Ref } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import {
4
4
  ChevronsLeft,
@@ -16,7 +16,7 @@ import {
16
16
  Undo2
17
17
  } from 'lucide-react';
18
18
  import { useTranslation } from 'react-i18next';
19
- import { Button, Icon, IconButton, Menu } from '@adecore/ui';
19
+ import { Button, ButtonGroup, Icon, IconButton, Menu, Separator } from '@adecore/ui';
20
20
  import { formatNumber } from '@adecore/ui/format';
21
21
  import type { Engine, FileFormat } from '../protocol/index.ts';
22
22
  import { CommandField } from './CommandField.tsx';
@@ -35,13 +35,14 @@ export interface TransferMenu {
35
35
  const EXPORT_FORMATS: readonly FileFormat[] = ['csv', 'tsv', 'json', 'sql'];
36
36
 
37
37
  export interface TableToolbarProps {
38
+ /* The app's own content before the command field, such as where the table is, with a separator after it and after the field. */
39
+ start?: ReactNode;
38
40
  refreshing: boolean;
39
41
  /* Why rows cannot be added, changed or deleted, or `null` when they can. */
40
42
  readOnlyReason: string | null;
41
43
  hasSelection: boolean;
42
44
  /* Whether any selected row has a change to take back. */
43
45
  canRevertSelection: boolean;
44
- valuePanelOpen: boolean;
45
46
  /* The record view replaces the grid with the focused row as a list of fields. */
46
47
  recordViewOpen?: boolean;
47
48
  transfer?: TransferMenu;
@@ -62,7 +63,6 @@ export interface TableToolbarProps {
62
63
  onDeleteRows(): void;
63
64
  onCloneRows(): void;
64
65
  onRevertRows(): void;
65
- onToggleValuePanel(): void;
66
66
  onToggleRecordView?(): void;
67
67
  onPageSizeChange(size: number): void;
68
68
  onFirstPage(): void;
@@ -76,11 +76,11 @@ export interface TableToolbarProps {
76
76
 
77
77
  /* The command field for filtering, sorting and jumping to a column, refresh, add row, the submit of pending changes, and a menu of the rest. */
78
78
  export function TableToolbar({
79
+ start,
79
80
  refreshing,
80
81
  readOnlyReason,
81
82
  hasSelection,
82
83
  canRevertSelection,
83
- valuePanelOpen,
84
84
  recordViewOpen = false,
85
85
  transfer,
86
86
  pendingCount,
@@ -98,7 +98,6 @@ export function TableToolbar({
98
98
  onDeleteRows,
99
99
  onCloneRows,
100
100
  onRevertRows,
101
- onToggleValuePanel,
102
101
  onToggleRecordView,
103
102
  onPageSizeChange,
104
103
  onFirstPage,
@@ -110,11 +109,19 @@ export function TableToolbar({
110
109
  }: TableToolbarProps) {
111
110
  const { t } = useTranslation('database');
112
111
  const readOnly = readOnlyReason !== null;
112
+ const hasStart = start !== undefined && start !== null && start !== false;
113
113
  const tooltipOf = (label: string): string => (readOnly ? t('table.unavailable', { action: label, reason: readOnlyReason }) : label);
114
114
 
115
115
  return (
116
116
  <div ref={ref} className={clsx('flex shrink-0 items-center gap-2 border-b border-border px-3 py-2', className)}>
117
+ {hasStart && (
118
+ <>
119
+ {start}
120
+ <Separator />
121
+ </>
122
+ )}
117
123
  <CommandField chips={chips} columns={columns} engine={engine} inputRef={commandRef} onChipsChange={onChipsChange} onJumpToColumn={onJumpToColumn} />
124
+ {hasStart && <Separator />}
118
125
  {pendingCount > 0 && (
119
126
  <>
120
127
  <Button variant="primary" size="sm" disabled={submitting} onClick={onSubmit}>
@@ -125,93 +132,101 @@ export function TableToolbar({
125
132
  </Button>
126
133
  </>
127
134
  )}
128
- <IconButton icon={RefreshCw} size="sm" label={t('table.refresh')} busy={refreshing} onClick={onRefresh} />
129
- <IconButton
130
- icon={Plus}
131
- size="sm"
132
- label={t('table.addRow')}
133
- tooltip={tooltipOf(t('table.addRow'))}
134
- aria-disabled={readOnly || undefined}
135
- onClick={() => !readOnly && onAddRow()}
136
- />
137
- <Menu.Root>
138
- <IconButton icon={Ellipsis} size="sm" label={t('table.more')} render={<Menu.Trigger />} />
139
- <Menu.Popup align="end">
140
- <Menu.SubmenuRoot>
141
- <Menu.SubmenuTrigger>
142
- <Icon icon={Rows3} size={14} />
143
- {t('table.pageSize')}
144
- </Menu.SubmenuTrigger>
145
- <Menu.Popup>
146
- <Menu.RadioGroup value={String(pageSize)} onValueChange={(value) => onPageSizeChange(Number(value))}>
147
- {PAGE_SIZES.map((size) => (
148
- <Menu.RadioItem key={size} value={String(size)}>
149
- {t('table.perPage', { size: formatNumber(size) })}
150
- </Menu.RadioItem>
151
- ))}
152
- </Menu.RadioGroup>
153
- </Menu.Popup>
154
- </Menu.SubmenuRoot>
155
- <Menu.Item disabled={!bounds.hasPrevious} onClick={onFirstPage}>
156
- <Icon icon={ChevronsLeft} size={14} />
157
- {t('table.firstPage')}
158
- </Menu.Item>
159
- <Menu.Item disabled={!bounds.hasNext} onClick={onLastPage}>
160
- <Icon icon={ChevronsRight} size={14} />
161
- {t('table.lastPage')}
162
- {!bounds.exact && <Menu.Hint>{t('table.lastPageCounts')}</Menu.Hint>}
163
- </Menu.Item>
164
- <Menu.Separator />
165
- {onToggleRecordView !== undefined && (
166
- <Menu.CheckboxItem checked={recordViewOpen} onCheckedChange={onToggleRecordView}>
167
- <Icon icon={TableProperties} size={14} />
168
- {t('table.recordView')}
169
- </Menu.CheckboxItem>
170
- )}
171
- <Menu.CheckboxItem checked={valuePanelOpen} onCheckedChange={onToggleValuePanel}>
172
- <Icon icon={PanelRight} size={14} />
173
- {t('table.valuePanel')}
174
- </Menu.CheckboxItem>
175
- <Menu.Separator />
176
- {readOnly && <Menu.Label>{readOnlyReason}</Menu.Label>}
177
- <Menu.Item disabled={readOnly || !hasSelection} onClick={onCloneRows}>
178
- <Icon icon={CopyPlus} size={14} />
179
- {t('table.cloneRows')}
180
- </Menu.Item>
181
- <Menu.Item disabled={!canRevertSelection} onClick={onRevertRows}>
182
- <Icon icon={Undo2} size={14} />
183
- {t('table.revertRows')}
184
- </Menu.Item>
185
- <Menu.Item disabled={readOnly || !hasSelection} onClick={onDeleteRows}>
186
- <Icon icon={Trash2} size={14} />
187
- {t('table.deleteRows')}
188
- </Menu.Item>
189
- {transfer !== undefined && (
190
- <>
191
- <Menu.Separator />
192
- <Menu.SubmenuRoot>
193
- <Menu.SubmenuTrigger disabled={transfer.busy}>
194
- <Icon icon={Download} size={14} />
195
- {t('table.export.label')}
196
- </Menu.SubmenuTrigger>
197
- <Menu.Popup>
198
- {EXPORT_FORMATS.map((format) => (
199
- <Menu.Item key={format} onClick={() => transfer.onExport(format)}>
200
- {t('table.export.as', { format: format.toUpperCase() })}
201
- </Menu.Item>
135
+ <ButtonGroup>
136
+ <IconButton icon={RefreshCw} size="sm" label={t('table.refresh')} busy={refreshing} onClick={onRefresh} />
137
+ <IconButton
138
+ icon={Plus}
139
+ size="sm"
140
+ label={t('table.addRow')}
141
+ tooltip={tooltipOf(t('table.addRow'))}
142
+ aria-disabled={readOnly || undefined}
143
+ onClick={() => !readOnly && onAddRow()}
144
+ />
145
+ {onToggleRecordView !== undefined && (
146
+ <IconButton
147
+ icon={PanelRight}
148
+ size="sm"
149
+ label={t('table.recordView')}
150
+ aria-pressed={recordViewOpen}
151
+ active={recordViewOpen}
152
+ onClick={onToggleRecordView}
153
+ />
154
+ )}
155
+ <Menu.Root>
156
+ <IconButton icon={Ellipsis} size="sm" label={t('table.more')} render={<Menu.Trigger />} />
157
+ <Menu.Popup align="end">
158
+ <Menu.SubmenuRoot>
159
+ <Menu.SubmenuTrigger>
160
+ <Icon icon={Rows3} size={14} />
161
+ {t('table.pageSize')}
162
+ </Menu.SubmenuTrigger>
163
+ <Menu.Popup>
164
+ <Menu.RadioGroup value={String(pageSize)} onValueChange={(value) => onPageSizeChange(Number(value))}>
165
+ {PAGE_SIZES.map((size) => (
166
+ <Menu.RadioItem key={size} value={String(size)}>
167
+ {t('table.perPage', { size: formatNumber(size) })}
168
+ </Menu.RadioItem>
202
169
  ))}
203
- </Menu.Popup>
204
- </Menu.SubmenuRoot>
205
- {transfer.onImport !== undefined && (
206
- <Menu.Item onClick={transfer.onImport}>
207
- <Icon icon={FileInput} size={14} />
208
- {t('table.import.menu')}
209
- </Menu.Item>
210
- )}
211
- </>
212
- )}
213
- </Menu.Popup>
214
- </Menu.Root>
170
+ </Menu.RadioGroup>
171
+ </Menu.Popup>
172
+ </Menu.SubmenuRoot>
173
+ <Menu.Item disabled={!bounds.hasPrevious} onClick={onFirstPage}>
174
+ <Icon icon={ChevronsLeft} size={14} />
175
+ {t('table.firstPage')}
176
+ </Menu.Item>
177
+ <Menu.Item disabled={!bounds.hasNext} onClick={onLastPage}>
178
+ <Icon icon={ChevronsRight} size={14} />
179
+ {t('table.lastPage')}
180
+ {!bounds.exact && <Menu.Hint>{t('table.lastPageCounts')}</Menu.Hint>}
181
+ </Menu.Item>
182
+ <Menu.Separator />
183
+ {onToggleRecordView !== undefined && (
184
+ <Menu.CheckboxItem checked={recordViewOpen} onCheckedChange={onToggleRecordView}>
185
+ <Icon icon={TableProperties} size={14} />
186
+ {t('table.recordView')}
187
+ </Menu.CheckboxItem>
188
+ )}
189
+ <Menu.Separator />
190
+ {readOnly && <Menu.Label>{readOnlyReason}</Menu.Label>}
191
+ <Menu.Item disabled={readOnly || !hasSelection} onClick={onCloneRows}>
192
+ <Icon icon={CopyPlus} size={14} />
193
+ {t('table.cloneRows')}
194
+ </Menu.Item>
195
+ <Menu.Item disabled={!canRevertSelection} onClick={onRevertRows}>
196
+ <Icon icon={Undo2} size={14} />
197
+ {t('table.revertRows')}
198
+ </Menu.Item>
199
+ <Menu.Item disabled={readOnly || !hasSelection} onClick={onDeleteRows}>
200
+ <Icon icon={Trash2} size={14} />
201
+ {t('table.deleteRows')}
202
+ </Menu.Item>
203
+ {transfer !== undefined && (
204
+ <>
205
+ <Menu.Separator />
206
+ <Menu.SubmenuRoot>
207
+ <Menu.SubmenuTrigger disabled={transfer.busy}>
208
+ <Icon icon={Download} size={14} />
209
+ {t('table.export.label')}
210
+ </Menu.SubmenuTrigger>
211
+ <Menu.Popup>
212
+ {EXPORT_FORMATS.map((format) => (
213
+ <Menu.Item key={format} onClick={() => transfer.onExport(format)}>
214
+ {t('table.export.as', { format: format.toUpperCase() })}
215
+ </Menu.Item>
216
+ ))}
217
+ </Menu.Popup>
218
+ </Menu.SubmenuRoot>
219
+ {transfer.onImport !== undefined && (
220
+ <Menu.Item onClick={transfer.onImport}>
221
+ <Icon icon={FileInput} size={14} />
222
+ {t('table.import.menu')}
223
+ </Menu.Item>
224
+ )}
225
+ </>
226
+ )}
227
+ </Menu.Popup>
228
+ </Menu.Root>
229
+ </ButtonGroup>
215
230
  </div>
216
231
  );
217
232
  }