@antelopejs/dms-database 0.0.13 → 0.1.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 (173) hide show
  1. package/README.md +30 -5
  2. package/dist/db/models/query_history.model.d.ts +1 -0
  3. package/dist/db/models/query_history.model.js +6 -0
  4. package/dist/db/models/query_history.model.js.map +1 -1
  5. package/dist/db/tables/query_history.table.d.ts +3 -0
  6. package/dist/db/tables/query_history.table.js +12 -0
  7. package/dist/db/tables/query_history.table.js.map +1 -1
  8. package/dist/db/tables/saved_queries.table.d.ts +1 -0
  9. package/dist/db/tables/saved_queries.table.js +4 -0
  10. package/dist/db/tables/saved_queries.table.js.map +1 -1
  11. package/dist/i18n/messages.d.ts +39 -0
  12. package/dist/i18n/messages.js +64 -0
  13. package/dist/i18n/messages.js.map +1 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.js +1 -7
  16. package/dist/index.js.map +1 -1
  17. package/dist/module.d.ts +11 -0
  18. package/dist/module.js +55 -0
  19. package/dist/module.js.map +1 -0
  20. package/dist/pages/data.d.ts +1 -1
  21. package/dist/pages/data.js +9 -6
  22. package/dist/pages/data.js.map +1 -1
  23. package/dist/pages/diagram.d.ts +9 -0
  24. package/dist/pages/diagram.js +45 -0
  25. package/dist/pages/diagram.js.map +1 -0
  26. package/dist/pages/index.d.ts +1 -0
  27. package/dist/pages/index.js +1 -0
  28. package/dist/pages/index.js.map +1 -1
  29. package/dist/pages/overview.d.ts +4 -1
  30. package/dist/pages/overview.js +113 -6
  31. package/dist/pages/overview.js.map +1 -1
  32. package/dist/pages/query.d.ts +1 -1
  33. package/dist/pages/query.js +22 -6
  34. package/dist/pages/query.js.map +1 -1
  35. package/dist/pages/schemas.d.ts +2 -1
  36. package/dist/pages/schemas.js +143 -6
  37. package/dist/pages/schemas.js.map +1 -1
  38. package/dist/routes/data.d.ts +8 -0
  39. package/dist/routes/data.js +84 -21
  40. package/dist/routes/data.js.map +1 -1
  41. package/dist/routes/index.d.ts +1 -0
  42. package/dist/routes/index.js +1 -0
  43. package/dist/routes/index.js.map +1 -1
  44. package/dist/routes/overview.d.ts +12 -0
  45. package/dist/routes/overview.js +55 -0
  46. package/dist/routes/overview.js.map +1 -0
  47. package/dist/routes/query.d.ts +5 -1
  48. package/dist/routes/query.js +162 -27
  49. package/dist/routes/query.js.map +1 -1
  50. package/dist/routes/tables.d.ts +15 -12
  51. package/dist/routes/tables.js +95 -55
  52. package/dist/routes/tables.js.map +1 -1
  53. package/dist/service/catalog.d.ts +3 -0
  54. package/dist/service/catalog.js +26 -0
  55. package/dist/service/catalog.js.map +1 -0
  56. package/dist/service/health.d.ts +3 -3
  57. package/dist/service/health.js +17 -14
  58. package/dist/service/health.js.map +1 -1
  59. package/dist/service/introspect.d.ts +3 -1
  60. package/dist/service/introspect.js +131 -43
  61. package/dist/service/introspect.js.map +1 -1
  62. package/dist/service/overview.d.ts +9 -0
  63. package/dist/service/overview.js +113 -0
  64. package/dist/service/overview.js.map +1 -0
  65. package/dist/service/queryInspection.d.ts +15 -0
  66. package/dist/service/queryInspection.js +107 -0
  67. package/dist/service/queryInspection.js.map +1 -0
  68. package/dist/service/references.d.ts +9 -0
  69. package/dist/service/references.js +52 -0
  70. package/dist/service/references.js.map +1 -0
  71. package/dist/service/schemaFilters.d.ts +26 -0
  72. package/dist/service/schemaFilters.js +42 -0
  73. package/dist/service/schemaFilters.js.map +1 -0
  74. package/dist/service/stagedSerialization.d.ts +2 -0
  75. package/dist/service/stagedSerialization.js +38 -10
  76. package/dist/service/stagedSerialization.js.map +1 -1
  77. package/dist/service/types.d.ts +11 -1
  78. package/dist/types/constants.d.ts +2 -0
  79. package/dist/types/constants.js +3 -1
  80. package/dist/types/constants.js.map +1 -1
  81. package/dist/utils/query.d.ts +0 -2
  82. package/dist/utils/query.js +0 -20
  83. package/dist/utils/query.js.map +1 -1
  84. package/frontend-vue/app/{composables → build/composables}/useDataBrowserGrid.ts +65 -50
  85. package/frontend-vue/app/build/composables/useDataBrowserTabs.ts +366 -0
  86. package/frontend-vue/app/build/composables/useDatabaseHealth.ts +50 -0
  87. package/frontend-vue/app/build/composables/useDatabaseSchemas.ts +140 -0
  88. package/frontend-vue/app/{composables → build/composables}/useDiagramPersistence.ts +47 -39
  89. package/frontend-vue/app/build/composables/useQueryRuntime.ts +217 -0
  90. package/frontend-vue/app/build/composables/useQueryStore.ts +162 -0
  91. package/frontend-vue/app/build/data/cellValues.ts +132 -0
  92. package/frontend-vue/app/build/data/instanceOptions.ts +36 -0
  93. package/frontend-vue/app/build/data/pickerMenus.ts +175 -0
  94. package/frontend-vue/app/build/data/recentTables.ts +48 -0
  95. package/frontend-vue/app/build/data/stagedEdits.ts +117 -0
  96. package/frontend-vue/app/build/data/stagedWrites.ts +64 -0
  97. package/frontend-vue/app/build/data/useStagedSave.ts +298 -0
  98. package/frontend-vue/app/build/diagram/autosave.ts +72 -0
  99. package/frontend-vue/app/build/diagram/graph.ts +585 -0
  100. package/frontend-vue/app/build/diagram/history.ts +178 -0
  101. package/frontend-vue/app/build/diagram/shortcuts.ts +62 -0
  102. package/frontend-vue/app/build/diagram/sync.ts +137 -0
  103. package/frontend-vue/app/build/query/completion.ts +100 -0
  104. package/frontend-vue/app/build/query/csv.ts +32 -0
  105. package/frontend-vue/app/build/query/examples.ts +38 -0
  106. package/frontend-vue/app/build/query/runs.ts +168 -0
  107. package/frontend-vue/app/build/query/tableColumns.ts +35 -0
  108. package/frontend-vue/app/build/query/target.ts +143 -0
  109. package/frontend-vue/app/build/schemas/filterState.ts +128 -0
  110. package/frontend-vue/app/build/schemas/useSchemasListing.ts +62 -0
  111. package/frontend-vue/app/build/utils/databaseLinks.ts +98 -0
  112. package/frontend-vue/app/build/utils/fieldTypes.ts +198 -0
  113. package/frontend-vue/app/build/utils/relativeTime.ts +19 -0
  114. package/frontend-vue/app/{utils → build/utils}/stagedSerialization.ts +7 -1
  115. package/frontend-vue/app/components/ConnectionStatus.vue +122 -0
  116. package/frontend-vue/app/components/DataBrowser.vue +126 -0
  117. package/frontend-vue/app/components/DataBrowserSidebar.vue +293 -210
  118. package/frontend-vue/app/components/DataBrowserTabBar.vue +185 -93
  119. package/frontend-vue/app/components/DataFilterBar.vue +163 -0
  120. package/frontend-vue/app/components/DataGrid.vue +737 -499
  121. package/frontend-vue/app/components/DataGridCell.vue +125 -77
  122. package/frontend-vue/app/components/DataGridHeaderCell.vue +119 -81
  123. package/frontend-vue/app/components/DiagramNoteNode.vue +81 -63
  124. package/frontend-vue/app/components/DiagramRelationEdge.vue +57 -27
  125. package/frontend-vue/app/components/DiagramStubNode.vue +16 -17
  126. package/frontend-vue/app/components/DiagramTableNode.vue +106 -68
  127. package/frontend-vue/app/components/InstancePicker.vue +195 -0
  128. package/frontend-vue/app/components/JsonCellPanel.vue +30 -29
  129. package/frontend-vue/app/components/QueryBuilderPanel.vue +290 -238
  130. package/frontend-vue/app/components/QueryConsole.vue +726 -0
  131. package/frontend-vue/app/components/QueryLibrary.vue +314 -0
  132. package/frontend-vue/app/components/QueryResultPanel.vue +556 -126
  133. package/frontend-vue/app/components/RowDrawer.vue +520 -0
  134. package/frontend-vue/app/components/SchemaDiagram.vue +1016 -1051
  135. package/frontend-vue/app/components/SchemaPicker.vue +86 -0
  136. package/frontend-vue/app/components/SchemasFilterBar.vue +201 -0
  137. package/frontend-vue/app/components/TableInspector.vue +741 -0
  138. package/frontend-vue/app/config/shortcuts-registry.ts +65 -0
  139. package/frontend-vue/dms.frontend.ts +5 -14
  140. package/frontend-vue/i18n/locales/database-en-GB.json +526 -193
  141. package/frontend-vue/i18n/locales/database-fr-FR.json +528 -195
  142. package/frontend-vue/package.json +2 -1
  143. package/frontend-vue/pnpm-lock.yaml +2601 -858
  144. package/frontend-vue/pnpm-workspace.yaml +1 -1
  145. package/frontend-vue/tests/dataBrowser.test.ts +206 -0
  146. package/frontend-vue/tests/diagram.test.ts +516 -0
  147. package/frontend-vue/tests/helpers.test.ts +205 -0
  148. package/frontend-vue/tests/instanceOptions.test.ts +53 -0
  149. package/frontend-vue/tests/locales.test.ts +56 -0
  150. package/frontend-vue/tests/persistence.test.ts +106 -5
  151. package/frontend-vue/tests/pickerMenus.test.ts +254 -0
  152. package/frontend-vue/tests/queryConsole.test.ts +282 -0
  153. package/frontend-vue/tests/queryRuntime.test.ts +2 -2
  154. package/frontend-vue/tests/registration.test.ts +36 -25
  155. package/frontend-vue/tests/schemasFilters.test.ts +115 -0
  156. package/package.json +9 -6
  157. package/frontend-vue/app/components/QueryFavoritesPanel.vue +0 -127
  158. package/frontend-vue/app/components/QueryHistoryPanel.vue +0 -134
  159. package/frontend-vue/app/components/SchemaTableInspector.vue +0 -278
  160. package/frontend-vue/app/composables/useDataBrowserTabs.ts +0 -255
  161. package/frontend-vue/app/composables/useDatabaseHealth.ts +0 -50
  162. package/frontend-vue/app/composables/useDatabaseSchemas.ts +0 -92
  163. package/frontend-vue/app/composables/useQueryRuntime.ts +0 -118
  164. package/frontend-vue/app/composables/useQueryStore.ts +0 -117
  165. package/frontend-vue/app/composables/useTableViewRowClick.ts +0 -22
  166. package/frontend-vue/app/custom-pages/database/data.vue +0 -41
  167. package/frontend-vue/app/custom-pages/database/overview.vue +0 -367
  168. package/frontend-vue/app/custom-pages/database/query.vue +0 -436
  169. package/frontend-vue/app/custom-pages/database/schemas.vue +0 -218
  170. package/frontend-vue/app/utils/databaseFieldModifiers.ts +0 -33
  171. package/frontend-vue/app/utils/databaseFieldTypeIcons.ts +0 -224
  172. package/frontend-vue/app/utils/dmsTableView.ts +0 -83
  173. package/frontend-vue/app/utils/relativeTime.ts +0 -18
@@ -0,0 +1,195 @@
1
+ <script setup lang="ts">
2
+ import { watchDebounced } from '@vueuse/core'
3
+ import {
4
+ PICKER_LIMIT,
5
+ type InstanceChoice,
6
+ } from '../build/data/instanceOptions'
7
+ import {
8
+ ALL_ICON,
9
+ INSTANCE_ICON,
10
+ PICKER_MENU_UI,
11
+ READ_ONLY_ICON,
12
+ instanceMenu,
13
+ instancePickChoice,
14
+ instancePickValue,
15
+ type AllInstancesMode,
16
+ type InstancesStatus,
17
+ } from '../build/data/pickerMenus'
18
+
19
+ // An instance picked from a searchable menu, shared by the Schemas page's
20
+ // filter bar and the data browser's sidebar. A SaaS schema may hold one
21
+ // instance per tenant: the named ones load when the menu opens and the
22
+ // server searches them, a hundred at most with how many matched. "All
23
+ // instances" (with their count) and "default" are pinned first, "all" after
24
+ // the matches of a search; "all" is a filter on the Schemas page, the data
25
+ // browser's read-only view there.
26
+
27
+ const props = withDefaults(
28
+ defineProps<{
29
+ modelValue: InstanceChoice
30
+ /** The schema whose named instances are listed; null for none. */
31
+ schema: string | null
32
+ allMode?: AllInstancesMode
33
+ disabled?: boolean
34
+ }>(),
35
+ { allMode: 'filter' },
36
+ )
37
+
38
+ const emit = defineEmits<{ 'update:modelValue': [choice: InstanceChoice] }>()
39
+
40
+ const INSTANCES_ENDPOINT = '/api/database/tables/instances'
41
+ const SEARCH_DEBOUNCE_MS = 250
42
+
43
+ const { t, n } = useI18n()
44
+ const { $authFetch } = useAuthFetch()
45
+
46
+ const search = ref('')
47
+ const open = ref(false)
48
+ const names = ref<string[]>([])
49
+ const matched = ref(0)
50
+ // Named instances of the schema, before any search; null until known.
51
+ const total = ref<number | null>(null)
52
+ const status = ref<InstancesStatus>('idle')
53
+ let request = 0
54
+ let loadedKey: string | null = null
55
+
56
+ async function load() {
57
+ const schema = props.schema
58
+ if (!schema) return
59
+ const term = search.value.trim()
60
+ const key = `${schema}\u0000${term}`
61
+ if (key === loadedKey) return
62
+ const current = ++request
63
+ status.value = 'pending'
64
+ try {
65
+ const res = await $authFetch<{ instances: string[]; total: number }>(
66
+ INSTANCES_ENDPOINT,
67
+ {
68
+ query: {
69
+ schema,
70
+ search: term || undefined,
71
+ limit: PICKER_LIMIT,
72
+ },
73
+ },
74
+ )
75
+ if (current !== request) return
76
+ names.value = res.instances
77
+ matched.value = res.total
78
+ if (!term) total.value = res.total
79
+ status.value = 'success'
80
+ loadedKey = key
81
+ } catch {
82
+ if (current === request) status.value = 'error'
83
+ }
84
+ }
85
+
86
+ // Another schema, other instances: they load when the menu opens.
87
+ watch(
88
+ () => props.schema,
89
+ () => {
90
+ request++
91
+ loadedKey = null
92
+ names.value = []
93
+ matched.value = 0
94
+ total.value = null
95
+ status.value = 'idle'
96
+ if (open.value) void load()
97
+ },
98
+ )
99
+
100
+ function onOpen(value: boolean) {
101
+ open.value = value
102
+ if (value) void load()
103
+ }
104
+
105
+ watchDebounced(
106
+ search,
107
+ () => {
108
+ if (open.value) void load()
109
+ },
110
+ { debounce: SEARCH_DEBOUNCE_MS },
111
+ )
112
+
113
+ const items = computed(() =>
114
+ instanceMenu({
115
+ search: search.value,
116
+ hasSchema: Boolean(props.schema),
117
+ names: names.value,
118
+ matched: matched.value,
119
+ total: total.value,
120
+ status: status.value,
121
+ allMode: props.allMode,
122
+ labels: {
123
+ all: t('dms_database.pickers.instance.all'),
124
+ readOnly: t('dms_database.pickers.instance.read_only'),
125
+ default: t('dms_database.pickers.instance.default'),
126
+ pickSchema: t('dms_database.pickers.instance.pick_schema'),
127
+ loading: t('dms_database.pickers.instance.loading'),
128
+ failed: t('dms_database.pickers.instance.failed'),
129
+ noNamed: t('dms_database.pickers.instance.no_named'),
130
+ noMatch: t('dms_database.pickers.instance.no_match'),
131
+ more: (shown, all) =>
132
+ t('dms_database.pickers.instance.more', {
133
+ shown: n(shown),
134
+ total: n(all),
135
+ }),
136
+ count: (value) => n(value),
137
+ },
138
+ }),
139
+ )
140
+
141
+ const name = computed(() => {
142
+ const choice = props.modelValue
143
+ if (choice.kind === 'all') return t('dms_database.pickers.instance.all')
144
+ if (choice.kind === 'default')
145
+ return t('dms_database.pickers.instance.default')
146
+ return choice.id
147
+ })
148
+
149
+ const icon = computed(() => {
150
+ if (props.modelValue.kind !== 'all') return INSTANCE_ICON
151
+ return props.allMode === 'readonly' ? READ_ONLY_ICON : ALL_ICON
152
+ })
153
+
154
+ function pick(value: unknown) {
155
+ if (typeof value === 'string')
156
+ emit('update:modelValue', instancePickChoice(value))
157
+ }
158
+ </script>
159
+
160
+ <template>
161
+ <USelectMenu
162
+ v-model:search-term="search"
163
+ :model-value="instancePickValue(modelValue)"
164
+ :items="items"
165
+ value-key="value"
166
+ ignore-filter
167
+ :search-input="{
168
+ placeholder: t('dms_database.pickers.instance.find'),
169
+ icon: 'i-ph-magnifying-glass',
170
+ }"
171
+ :icon="icon"
172
+ :disabled="disabled"
173
+ :aria-label="t('dms_database.pickers.instance.label')"
174
+ size="sm"
175
+ :ui="PICKER_MENU_UI"
176
+ data-dms-database-instance-picker
177
+ @update:open="onOpen"
178
+ @update:model-value="pick"
179
+ >
180
+ <span
181
+ class="truncate"
182
+ :class="{ 'font-mono': modelValue.kind !== 'all' }"
183
+ :title="
184
+ modelValue.kind === 'all' && allMode === 'readonly'
185
+ ? t('dms_database.pickers.instance.read_only')
186
+ : undefined
187
+ "
188
+ >
189
+ {{ name }}
190
+ </span>
191
+ <template #empty>
192
+ {{ t('dms_database.pickers.instance.no_match') }}
193
+ </template>
194
+ </USelectMenu>
195
+ </template>
@@ -1,67 +1,69 @@
1
1
  <script setup lang="ts">
2
2
  const props = defineProps<{
3
- open: boolean;
4
- column: string;
5
- value: unknown;
6
- saving: boolean;
7
- readOnly: boolean;
8
- }>();
3
+ open: boolean
4
+ column: string
5
+ value: unknown
6
+ readOnly: boolean
7
+ }>()
9
8
 
10
9
  const emit = defineEmits<{
11
- "update:open": [open: boolean];
12
- save: [value: unknown];
13
- }>();
10
+ 'update:open': [open: boolean]
11
+ save: [value: unknown]
12
+ }>()
14
13
 
15
- const { t } = useI18n();
14
+ // Edits a structured cell (an object or a list) as JSON; applying stages the
15
+ // value like any other cell. null empties the cell.
16
+ const { t } = useI18n()
16
17
 
17
- const draft = ref("");
18
+ const draft = ref('')
18
19
 
19
20
  watch(
20
21
  () => props.open,
21
22
  (open) => {
22
- if (!open) return;
23
+ if (!open) return
23
24
  try {
24
- draft.value = JSON.stringify(props.value, null, 2) ?? "";
25
+ draft.value = JSON.stringify(props.value, null, 2) ?? ''
25
26
  } catch {
26
- draft.value = "";
27
+ draft.value = ''
27
28
  }
28
29
  },
29
30
  { immediate: true },
30
- );
31
+ )
31
32
 
32
33
  const parseError = computed(() => {
33
34
  try {
34
- const parsed = JSON.parse(draft.value);
35
- if (parsed === null || typeof parsed !== "object") {
36
- return t("dms_database.data.jsonNotStructured");
35
+ const parsed = JSON.parse(draft.value)
36
+ if (parsed !== null && typeof parsed !== 'object') {
37
+ return t('dms_database.data.json.not_structured')
37
38
  }
38
- return null;
39
+ return null
39
40
  } catch (error) {
40
41
  // Localized prefix + the engine's parse detail (position, token…).
41
42
  return error instanceof Error
42
- ? `${t("dms_database.data.jsonInvalid")} — ${error.message}`
43
- : t("dms_database.data.jsonInvalid");
43
+ ? `${t('dms_database.data.json.invalid')} — ${error.message}`
44
+ : t('dms_database.data.json.invalid')
44
45
  }
45
- });
46
+ })
46
47
 
47
48
  function save() {
48
- if (parseError.value || props.readOnly) return;
49
- emit("save", JSON.parse(draft.value));
49
+ if (parseError.value || props.readOnly) return
50
+ emit('save', JSON.parse(draft.value))
50
51
  }
51
52
  </script>
52
53
 
53
54
  <template>
54
55
  <USlideover
55
56
  :open="open"
56
- :title="t('dms_database.data.jsonPanelTitle', { column })"
57
+ :title="t('dms_database.data.json.title', { column })"
57
58
  @update:open="emit('update:open', $event)"
58
59
  >
59
60
  <template #body>
60
61
  <div class="flex h-full flex-col gap-3">
61
62
  <textarea
62
63
  v-model="draft"
64
+ :aria-label="t('dms_database.data.json.title', { column })"
63
65
  :readonly="readOnly"
64
- class="min-h-96 flex-1 resize-none rounded-md border border-default bg-default p-3 font-mono text-xs outline-none focus:border-primary"
66
+ class="border-default bg-default focus:border-primary min-h-96 flex-1 resize-none rounded-md border p-3 font-mono text-xs outline-none"
65
67
  spellcheck="false"
66
68
  />
67
69
  <UAlert
@@ -77,14 +79,13 @@ function save() {
77
79
  <UButton
78
80
  variant="ghost"
79
81
  color="neutral"
80
- :label="t('dms_database.data.cancel')"
82
+ :label="t('dms_database.common.cancel')"
81
83
  @click="emit('update:open', false)"
82
84
  />
83
85
  <UButton
84
86
  v-if="!readOnly"
85
- :label="t('dms_database.data.save')"
87
+ :label="t('dms_database.data.json.apply')"
86
88
  :disabled="Boolean(parseError)"
87
- :loading="saving"
88
89
  @click="save"
89
90
  />
90
91
  </div>