@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
package/src/grid/types.ts CHANGED
@@ -4,6 +4,8 @@ import type { Shown } from './display.ts';
4
4
  /* A column of a result, with what the grid draws from its table when it comes from one. */
5
5
  export interface GridColumn extends ResultColumn {
6
6
  readonly primaryKey?: boolean;
7
+ /* A column of a foreign key of its table. */
8
+ readonly foreignKey?: boolean;
7
9
  /* `false` makes Set NULL unavailable; unknown (an expression) leaves it open. */
8
10
  readonly nullable?: boolean;
9
11
  /* A column no cell of which can be edited, such as a generated one. */
@@ -29,10 +31,15 @@ export interface GridRow {
29
31
  readonly locked?: boolean;
30
32
  }
31
33
 
32
- /* Builds the column of a table from the result column and the structure's column of the same name. */
33
- export const gridColumnOf = (column: ResultColumn, info: ColumnInfo | undefined, primaryKey: readonly string[]): GridColumn => ({
34
+ /* Builds the column of a table from the result column, the structure's column of the same name and the columns of its keys. */
35
+ export const gridColumnOf = (
36
+ column: ResultColumn,
37
+ info: ColumnInfo | undefined,
38
+ keys: { readonly primaryKey: readonly string[]; readonly foreignKey: readonly string[] }
39
+ ): GridColumn => ({
34
40
  ...column,
35
- primaryKey: primaryKey.includes(column.name),
41
+ primaryKey: keys.primaryKey.includes(column.name),
42
+ foreignKey: keys.foreignKey.includes(column.name),
36
43
  nullable: info?.nullable,
37
44
  readOnly: info?.generated === true,
38
45
  defaultValue: info?.defaultValue,
@@ -45,6 +52,11 @@ export interface FocusedCell {
45
52
  readonly column: number;
46
53
  }
47
54
 
55
+ /* A cell to move the grid's focus to. `quiet` moves it without taking the keyboard, for a panel beside the grid that follows along. */
56
+ export interface FocusRequest extends FocusedCell {
57
+ readonly quiet?: boolean;
58
+ }
59
+
48
60
  /* What a menu item added to the grid's context menu acts on. */
49
61
  export interface GridMenuContext {
50
62
  /* The selected rows when the row under the pointer is one of them, else that row alone. */
package/src/index.ts CHANGED
@@ -20,16 +20,20 @@ export {
20
20
  type TableRef
21
21
  } from './client/index.ts';
22
22
 
23
- export type { DatabaseAction, DatabaseFiles, DatabaseStorage, ExplorerSelection } from './actions.ts';
23
+ export type { DatabaseAction, DatabaseFiles, DatabaseNotice, DatabaseStorage, ExplorerSelection } from './actions.ts';
24
24
 
25
25
  export { ConnectionForm, type ConnectionFormProps } from './connections/ConnectionForm.tsx';
26
+ export { configProblems, isValidConfig, type ConfigProblem, type ConfigProblems } from './connections/connection-config.ts';
26
27
  export { ConnectionManager, type ConnectionManagerProps } from './connections/ConnectionManager.tsx';
28
+ export { connectionFromContainer, containerTitle, isMysqlContainer, withContainer } from './connections/docker.ts';
27
29
  export { DatabaseExplorer, type DatabaseExplorerProps } from './explorer/DatabaseExplorer.tsx';
30
+ export type { ExplorerFolder, ExplorerItem } from './explorer/folders.ts';
28
31
  export { TableDesigner, type TableDesignerProps } from './designer/TableDesigner.tsx';
29
32
  export { DatabaseProvider, type DatabaseProviderProps } from './DatabaseProvider.tsx';
30
33
  export { useDatabaseClient } from './client-context.ts';
31
34
  export type { NumberNotation } from './grid/display.ts';
32
35
  export { QueryConsole, type QueryConsoleProps } from './console/QueryConsole.tsx';
36
+ export type { QueryConsoleEditorHandle, QueryConsoleEditorProps, QueryConsoleRunScope } from './console/editor-slot.ts';
33
37
  export { StructureView, type StructureViewProps } from './structure/StructureView.tsx';
34
38
  export { TableView, type TableViewProps } from './table/TableView.tsx';
35
39
  export { DatabaseWorkbench, type DatabaseWorkbenchProps } from './workbench/DatabaseWorkbench.tsx';
@@ -17,7 +17,8 @@
17
17
  "test": {
18
18
  "action": "Test connection",
19
19
  "success": "Connected to {{server}}.",
20
- "failed": "The connection failed."
20
+ "failed": "The connection failed.",
21
+ "dismiss": "Dismiss"
21
22
  },
22
23
  "delete": {
23
24
  "action": "Delete",
@@ -116,6 +117,18 @@
116
117
  "views": "Views",
117
118
  "primaryKey": "Primary key",
118
119
  "foreignKey": "Foreign key",
120
+ "primaryAndForeignKey": "Primary key and foreign key",
121
+ "parts": {
122
+ "columns": "Columns",
123
+ "keys": "Keys",
124
+ "foreignKeys": "Foreign keys",
125
+ "indexes": "Indexes",
126
+ "checks": "Checks",
127
+ "triggers": "Triggers"
128
+ },
129
+ "references": "{{columns}} → {{table}} ({{referenced}})",
130
+ "unique": "unique",
131
+ "check": "Check",
119
132
  "readOnly": "Read only",
120
133
  "schemaCount": "{{shown}} of {{total}}",
121
134
  "schemaCountHint_one": "{{shown}} of {{total}} schema shown, system schemas are hidden",
@@ -272,7 +285,6 @@
272
285
  },
273
286
  "cloneRows": "Clone selected rows",
274
287
  "revertRows": "Revert selected rows",
275
- "valuePanel": "Value editor",
276
288
  "firstPage": "First page",
277
289
  "lastPage": "Last page",
278
290
  "lastPageCounts": "Counts the rows first",
@@ -295,7 +307,10 @@
295
307
  "next": "Next row",
296
308
  "newRow": "New row",
297
309
  "row": "Row {{number}}",
298
- "position": "{{index}} of {{count}} on this page"
310
+ "position": "{{index}} of {{count}} on this page",
311
+ "close": "Close record view",
312
+ "expand": "Show the whole value",
313
+ "collapse": "Hide the whole value"
299
314
  },
300
315
  "aggregates": {
301
316
  "sum": "Sum",
@@ -313,7 +328,8 @@
313
328
  "running": "Exporting as {{format}}",
314
329
  "cancel": "Cancel",
315
330
  "done_one": "Exported {{rows}} row.",
316
- "done_other": "Exported {{rows}} rows."
331
+ "done_other": "Exported {{rows}} rows.",
332
+ "failed": "Export failed"
317
333
  },
318
334
  "import": {
319
335
  "menu": "Import from file",
@@ -329,7 +345,8 @@
329
345
  "skip": "Skip",
330
346
  "preview": "First {{count}} rows of the file",
331
347
  "cancel": "Cancel",
332
- "confirm": "Import"
348
+ "confirm": "Import",
349
+ "readFailed": "Could not read the file"
333
350
  },
334
351
  "more": "More actions",
335
352
  "of": "of",
@@ -357,6 +374,8 @@
357
374
  "running": "Running",
358
375
  "cancelled": "The statement was cancelled.",
359
376
  "result": "Result",
377
+ "results": "Results",
378
+ "closeResults": "Close results",
360
379
  "noRows": "The statement returned no rows.",
361
380
  "rows": "Rows: {{rows}}",
362
381
  "hasMore": "More rows exist but are not shown.",
@@ -369,10 +388,6 @@
369
388
  "runAll": "Run all",
370
389
  "loading": "Loading",
371
390
  "dismiss": "Dismiss",
372
- "ranStatement": "Ran: {{statement}}",
373
- "ranSelection": "Ran the selection",
374
- "ranAll_one": "Ran {{formatted}} statement",
375
- "ranAll_other": "Ran all {{formatted}} statements",
376
391
  "rowRange": "Rows: {{from}} to {{to}}",
377
392
  "page": "Page {{page}}",
378
393
  "previousPage": "Previous page",
@@ -384,15 +399,15 @@
384
399
  "schema": "Schema",
385
400
  "schemaPlaceholder": "Schema",
386
401
  "transaction": {
387
- "mode": "Transaction mode",
388
- "auto": "Auto",
389
- "manual": "Manual",
390
- "hint": "Auto commits every run. Manual keeps a transaction open until you commit or roll back.",
402
+ "autoCommit": "Auto-commit",
403
+ "hint": "On, every run commits. Off, a transaction stays open until you commit or roll back.",
391
404
  "open": "Transaction open",
392
405
  "commit": "Commit",
393
406
  "rollback": "Roll back",
394
407
  "endTitle": "End the transaction?",
395
- "endDescription": "A transaction is still open. Commit it to keep its changes, or roll it back to discard them."
408
+ "endDescription": "A transaction is still open. Commit it to keep its changes, or roll it back to discard them.",
409
+ "commitFailed": "Could not commit",
410
+ "rollbackFailed": "Could not roll back"
396
411
  },
397
412
  "destructive": {
398
413
  "title": "Run destructive statements?",
@@ -414,7 +429,9 @@
414
429
  "hint": "Click to edit, double click to run.",
415
430
  "rows_one": "{{formatted}} row",
416
431
  "rows_other": "{{formatted}} rows"
417
- }
432
+ },
433
+ "pageFailed": "Could not read the page",
434
+ "exportFailed": "Export failed"
418
435
  },
419
436
  "value": {
420
437
  "title": "Value",
@@ -17,7 +17,8 @@
17
17
  "test": {
18
18
  "action": "Verbinding testen",
19
19
  "success": "Verbonden met {{server}}.",
20
- "failed": "De verbinding is mislukt."
20
+ "failed": "De verbinding is mislukt.",
21
+ "dismiss": "Sluiten"
21
22
  },
22
23
  "delete": {
23
24
  "action": "Verwijderen",
@@ -116,6 +117,18 @@
116
117
  "views": "Views",
117
118
  "primaryKey": "Primaire sleutel",
118
119
  "foreignKey": "Refererende sleutel",
120
+ "primaryAndForeignKey": "Primaire en refererende sleutel",
121
+ "parts": {
122
+ "columns": "Kolommen",
123
+ "keys": "Sleutels",
124
+ "foreignKeys": "Refererende sleutels",
125
+ "indexes": "Indexen",
126
+ "checks": "Checks",
127
+ "triggers": "Triggers"
128
+ },
129
+ "references": "{{columns}} → {{table}} ({{referenced}})",
130
+ "unique": "uniek",
131
+ "check": "Check",
119
132
  "readOnly": "Alleen lezen",
120
133
  "schemaCount": "{{shown}} van {{total}}",
121
134
  "schemaCountHint_one": "{{shown}} van {{total}} schema getoond, systeemschema's zijn verborgen",
@@ -272,7 +285,6 @@
272
285
  },
273
286
  "cloneRows": "Geselecteerde rijen klonen",
274
287
  "revertRows": "Geselecteerde rijen terugdraaien",
275
- "valuePanel": "Waardeneditor",
276
288
  "firstPage": "Eerste pagina",
277
289
  "lastPage": "Laatste pagina",
278
290
  "lastPageCounts": "Telt eerst de rijen",
@@ -295,7 +307,10 @@
295
307
  "next": "Volgende rij",
296
308
  "newRow": "Nieuwe rij",
297
309
  "row": "Rij {{number}}",
298
- "position": "{{index}} van {{count}} op deze pagina"
310
+ "position": "{{index}} van {{count}} op deze pagina",
311
+ "close": "Recordweergave sluiten",
312
+ "expand": "Hele waarde tonen",
313
+ "collapse": "Hele waarde verbergen"
299
314
  },
300
315
  "aggregates": {
301
316
  "sum": "Som",
@@ -313,7 +328,8 @@
313
328
  "running": "Exporteren als {{format}}",
314
329
  "cancel": "Annuleren",
315
330
  "done_one": "{{rows}} rij geëxporteerd.",
316
- "done_other": "{{rows}} rijen geëxporteerd."
331
+ "done_other": "{{rows}} rijen geëxporteerd.",
332
+ "failed": "Exporteren is mislukt"
317
333
  },
318
334
  "import": {
319
335
  "menu": "Importeren uit bestand",
@@ -329,7 +345,8 @@
329
345
  "skip": "Overslaan",
330
346
  "preview": "Eerste {{count}} rijen van het bestand",
331
347
  "cancel": "Annuleren",
332
- "confirm": "Importeren"
348
+ "confirm": "Importeren",
349
+ "readFailed": "Het bestand kon niet worden gelezen"
333
350
  },
334
351
  "more": "Meer acties",
335
352
  "of": "van",
@@ -357,6 +374,8 @@
357
374
  "running": "Bezig",
358
375
  "cancelled": "De opdracht is geannuleerd.",
359
376
  "result": "Resultaat",
377
+ "results": "Resultaten",
378
+ "closeResults": "Resultaten sluiten",
360
379
  "noRows": "De opdracht gaf geen rijen terug.",
361
380
  "rows": "Rijen: {{rows}}",
362
381
  "hasMore": "Er zijn meer rijen, maar die worden niet getoond.",
@@ -369,10 +388,6 @@
369
388
  "runAll": "Alles uitvoeren",
370
389
  "loading": "Laden",
371
390
  "dismiss": "Sluiten",
372
- "ranStatement": "Uitgevoerd: {{statement}}",
373
- "ranSelection": "De selectie is uitgevoerd",
374
- "ranAll_one": "{{formatted}} opdracht uitgevoerd",
375
- "ranAll_other": "Alle {{formatted}} opdrachten uitgevoerd",
376
391
  "rowRange": "Rijen: {{from}} tot {{to}}",
377
392
  "page": "Pagina {{page}}",
378
393
  "previousPage": "Vorige pagina",
@@ -384,15 +399,15 @@
384
399
  "schema": "Schema",
385
400
  "schemaPlaceholder": "Schema",
386
401
  "transaction": {
387
- "mode": "Transactiemodus",
388
- "auto": "Automatisch",
389
- "manual": "Handmatig",
390
- "hint": "Automatisch legt elke uitvoering vast. Handmatig houdt een transactie open tot je vastlegt of terugdraait.",
402
+ "autoCommit": "Automatisch vastleggen",
403
+ "hint": "Aan legt elke uitvoering vast. Uit houdt een transactie open tot je vastlegt of terugdraait.",
391
404
  "open": "Transactie open",
392
405
  "commit": "Vastleggen",
393
406
  "rollback": "Terugdraaien",
394
407
  "endTitle": "De transactie afsluiten?",
395
- "endDescription": "Er staat nog een transactie open. Leg haar vast om de wijzigingen te bewaren, of draai haar terug om ze weg te gooien."
408
+ "endDescription": "Er staat nog een transactie open. Leg haar vast om de wijzigingen te bewaren, of draai haar terug om ze weg te gooien.",
409
+ "commitFailed": "Vastleggen is mislukt",
410
+ "rollbackFailed": "Terugdraaien is mislukt"
396
411
  },
397
412
  "destructive": {
398
413
  "title": "Destructieve opdrachten uitvoeren?",
@@ -414,7 +429,9 @@
414
429
  "hint": "Klik om te bewerken, dubbelklik om uit te voeren.",
415
430
  "rows_one": "{{formatted}} rij",
416
431
  "rows_other": "{{formatted}} rijen"
417
- }
432
+ },
433
+ "pageFailed": "De pagina kon niet worden gelezen",
434
+ "exportFailed": "Exporteren is mislukt"
418
435
  },
419
436
  "value": {
420
437
  "title": "Waarde",
@@ -29,5 +29,17 @@ export {
29
29
  type RowsResult,
30
30
  type StatementResult
31
31
  } from './messages.ts';
32
- export type { ColumnInfo, ForeignKeyInfo, IndexInfo, ResultColumn, SchemaInfo, TableInfo, TableKind, TableStructure } from './schema.ts';
32
+ export type {
33
+ CheckInfo,
34
+ ColumnInfo,
35
+ ColumnSource,
36
+ ForeignKeyInfo,
37
+ IndexInfo,
38
+ ResultColumn,
39
+ SchemaInfo,
40
+ TableInfo,
41
+ TableKind,
42
+ TableStructure,
43
+ TriggerInfo
44
+ } from './schema.ts';
33
45
  export { valueOfCell, type BinaryCell, type BinaryValue, type Cell, type EditValue, type LongTextCell, type Value, type ValueKind } from './values.ts';
@@ -4,7 +4,7 @@ import type { ResultColumn, SchemaInfo, TableInfo, TableStructure } from './sche
4
4
  import type { Cell, EditValue, Value } from './values.ts';
5
5
 
6
6
  /* Raised whenever a message changes shape, so a host refuses a helper from another release. */
7
- export const PROTOCOL_VERSION = 2;
7
+ export const PROTOCOL_VERSION = 3;
8
8
 
9
9
  /* The columns of the row key and their values. */
10
10
  export type RowKey = Readonly<Record<string, Value>>;
@@ -50,6 +50,21 @@ export interface ForeignKeyInfo {
50
50
  readonly onDelete: string | null;
51
51
  }
52
52
 
53
+ export interface CheckInfo {
54
+ /* `null` where the engine keeps no name. */
55
+ readonly name: string | null;
56
+ /* The condition as the server writes it, without `CHECK` and the parentheses around it. */
57
+ readonly expression: string;
58
+ }
59
+
60
+ export interface TriggerInfo {
61
+ readonly name: string;
62
+ /* `BEFORE`, `AFTER` or `INSTEAD OF`. */
63
+ readonly timing: string;
64
+ /* `INSERT`, `UPDATE` or `DELETE`. */
65
+ readonly event: string;
66
+ }
67
+
53
68
  export interface TableStructure {
54
69
  readonly schema: string;
55
70
  readonly name: string;
@@ -63,14 +78,27 @@ export interface TableStructure {
63
78
  readonly rowKey: readonly string[] | null;
64
79
  readonly indexes: readonly IndexInfo[];
65
80
  readonly foreignKeys: readonly ForeignKeyInfo[];
81
+ /* Left out on a view, and where the engine keeps no list of them: SQLite has its checks only inside the DDL. */
82
+ readonly checks?: readonly CheckInfo[];
83
+ /* Left out on a view. */
84
+ readonly triggers?: readonly TriggerInfo[];
66
85
  /* The `CREATE` statement as the server writes it. */
67
86
  readonly ddl: string | null;
68
87
  }
69
88
 
89
+ /* The column of a table a result column holds, as the server reports it. */
90
+ export interface ColumnSource {
91
+ readonly schema: string;
92
+ readonly table: string;
93
+ readonly column: string;
94
+ }
95
+
70
96
  /* A column of a result, which may come from a table or from an expression. */
71
97
  export interface ResultColumn {
72
98
  readonly name: string;
73
99
  /* The engine's name for the type of the value, such as `VARCHAR`; empty when it reports none. */
74
100
  readonly type: string;
75
101
  readonly kind: ValueKind;
102
+ /* Where the values come from, when the server says: left out for an expression, an alias of one and, on MySQL, a derived table. */
103
+ readonly source?: ColumnSource;
76
104
  }
@@ -2,9 +2,10 @@ import { useEffect, useState, type ReactNode, type Ref } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import { CircleAlert, Copy, KeyRound, Link2 } from 'lucide-react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { Banner, Button, EmptyState, Icon, Pill, Spinner, Tabs, copyText, messageOf } from '@adecore/ui';
5
+ import { Banner, Button, EmptyState, Icon, Pill, Separator, Spinner, Tabs, copyText, messageOf } from '@adecore/ui';
6
6
  import { useDatabaseClient } from '../client-context.ts';
7
7
  import type { Connection } from '../client/types.ts';
8
+ import { CODE_TEXT } from '../code-text.ts';
8
9
  import type { ColumnInfo, ForeignKeyInfo, IndexInfo, TableStructure } from '../protocol/index.ts';
9
10
  import { useSchemaChange } from '../use-schema-change.ts';
10
11
  import { referenceOf } from './structure-text.ts';
@@ -13,6 +14,8 @@ export interface StructureViewProps {
13
14
  connection: Connection;
14
15
  schema: string;
15
16
  table: string;
17
+ /* The app's own content before the tabs, such as where the table is, with a separator after it. */
18
+ toolbarStart?: ReactNode;
16
19
  className?: string;
17
20
  ref?: Ref<HTMLDivElement>;
18
21
  }
@@ -33,10 +36,10 @@ interface Answer {
33
36
 
34
37
  const TH = 'sticky top-0 h-7 bg-surface px-3 text-left text-xs font-medium whitespace-nowrap text-text-faint';
35
38
  const TD = 'h-7 border-t border-border-soft px-3 text-xs whitespace-nowrap text-text select-text';
36
- const MONO = 'font-mono text-code';
39
+ const MONO = CODE_TEXT;
37
40
 
38
41
  /* The columns, indexes, foreign keys and DDL of one table or view. */
39
- export function StructureView({ connection, schema, table, className, ref }: StructureViewProps) {
42
+ export function StructureView({ connection, schema, table, toolbarStart, className, ref }: StructureViewProps) {
40
43
  const { t } = useTranslation('database');
41
44
  const client = useDatabaseClient();
42
45
  const [answer, setAnswer] = useState<Answer | null>(null);
@@ -83,16 +86,23 @@ export function StructureView({ connection, schema, table, className, ref }: Str
83
86
  </Banner>
84
87
  </div>
85
88
  )}
86
- {load.status === 'ready' && <StructureTabs structure={load.structure} />}
89
+ {load.status === 'ready' && <StructureTabs structure={load.structure} start={toolbarStart} />}
87
90
  </div>
88
91
  );
89
92
  }
90
93
 
91
- export function StructureTabs({ structure }: { structure: TableStructure }) {
94
+ export function StructureTabs({ structure, start }: { structure: TableStructure; start?: ReactNode }) {
92
95
  const { t } = useTranslation('database');
96
+ const head =
97
+ start === undefined || start === null || start === false ? undefined : (
98
+ <span className="flex items-center gap-4">
99
+ {start}
100
+ <Separator />
101
+ </span>
102
+ );
93
103
  return (
94
104
  <Tabs.Root defaultValue="columns" className="flex min-h-0 grow flex-col">
95
- <Tabs.List className="shrink-0 px-3">
105
+ <Tabs.List className="shrink-0 px-3" start={head}>
96
106
  <Tabs.Tab value="columns">
97
107
  {t('structure.columns')}
98
108
  <Tabs.Count value={structure.columns.length} />
@@ -2,7 +2,7 @@ import { useId, useImperativeHandle, useMemo, useRef, useState, type KeyboardEve
2
2
  import clsx from 'clsx';
3
3
  import { ArrowDown, ArrowDownWideNarrow, ArrowRightToLine, ArrowUp, Code, Filter, Search, X, type LucideIcon } from 'lucide-react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { Icon, IconButton, Kbd, KEY_SHORTCUTS, Menu, shortcut } from '@adecore/ui';
5
+ import { Icon, IconButton, Kbd, KEY_SHORTCUTS, Keys, Menu, shortcut } from '@adecore/ui';
6
6
  import type { Engine } from '../protocol/index.ts';
7
7
  import {
8
8
  addChip,
@@ -194,7 +194,7 @@ export function CommandField({ chips, columns, engine, onChipsChange, onJumpToCo
194
194
  onFocus={() => setFocused(true)}
195
195
  onBlur={handleBlur}
196
196
  />
197
- <Kbd shortcut={FOCUS_SHORTCUT} variant="inline" className="shrink-0" />
197
+ <Keys shortcut={FOCUS_SHORTCUT} size="sm" className="shrink-0" />
198
198
  {open && (
199
199
  <div
200
200
  id={listId}
@@ -2,7 +2,7 @@ import type { Ref } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import { ChevronLeft, ChevronRight } from 'lucide-react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { Button, IconButton, Spinner, Tooltip } from '@adecore/ui';
5
+ import { Button, ButtonGroup, IconButton, Spinner, Tooltip } from '@adecore/ui';
6
6
  import { formatDecimal, formatNumber, formatRounded } from '@adecore/ui/format';
7
7
  import { useNumberNotation } from '../client-context.ts';
8
8
  import type { Aggregates } from '../grid/aggregates.ts';
@@ -49,10 +49,10 @@ export function TableStatusBar({ elapsedMs, bounds, counting, selection, onCount
49
49
  </>
50
50
  ))}
51
51
  </span>
52
- <span className="flex items-center">
52
+ <ButtonGroup>
53
53
  <IconButton icon={ChevronLeft} size="sm" label={t('table.previousPage')} disabled={!bounds.hasPrevious} onClick={onPrevious} />
54
54
  <IconButton icon={ChevronRight} size="sm" label={t('table.nextPage')} disabled={!bounds.hasNext} onClick={onNext} />
55
- </span>
55
+ </ButtonGroup>
56
56
  <Tooltip label={t('table.queryTime')}>
57
57
  <span className="text-text-faint tabular-nums">{t('table.elapsed', { value: formatDecimal(elapsedMs) })}</span>
58
58
  </Tooltip>