-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathApp.vue
More file actions
98 lines (92 loc) · 3.95 KB
/
Copy pathApp.vue
File metadata and controls
98 lines (92 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<script setup lang="ts">
import type { SavedQueryScope } from '../engine'
import LayoutSplitPane from '@antfu/design/components/Layout/LayoutSplitPane.vue'
import { provideColorScheme } from '@antfu/design/composables/colorScheme'
import { Pane } from 'splitpanes'
import { onMounted, provide } from 'vue'
import AppHeader from './components/AppHeader.vue'
import DataSourcePanel from './components/DataSourcePanel.vue'
import QueryPanel from './components/QueryPanel.vue'
import ResultViewer from './components/ResultViewer.vue'
import SavedQueriesPanel from './components/SavedQueriesPanel.vue'
import { backend, connect, connection, onDockActivation } from './composables/rpc'
import { useSavedQueries } from './composables/saved'
import { colorScheme } from './composables/scheme'
import { useWorkbench, workbenchKey } from './composables/workbench'
import '@antfu/design/styles.css'
const wb = useWorkbench()
const savedApi = useSavedQueries()
// The workbench is the app's shared context; panels inject it rather than
// receiving it (and mutating it) through props.
provide(workbenchKey, wb)
// The app owns the color scheme; feed it to @antfu/design's opt-in context so
// the JS-colored surfaces (hash/hue `DisplayBadge`) tune their contrast to the
// active mode without threading a `colorScheme` prop through every panel.
provideColorScheme(() => colorScheme.value)
onMounted(async () => {
await connect()
if (!connection.connected)
return
await Promise.all([wb.loadSources(), savedApi.refresh()])
// Sources registered/unregistered after boot refresh the picker live.
backend().onSourcesChanged(() => void wb.loadSources())
// In a hub, another dock can deep-link straight to a source via dock
// activation (`hub:docks:activate` with `params.sourceId`); focus it.
void onDockActivation('devframes:plugin:data-inspector', id => wb.focusSource(id))
// An empty query runs `$`: the workbench lands on the full source object.
void wb.runNow()
void wb.loadSkeleton()
})
// Persisting a recipe spans both state holders: the editor's current query +
// filters (workbench) and the store it lands in (savedApi).
function saveCurrent(input: { title?: string, description?: string, scope: SavedQueryScope }): void {
void savedApi.save({
...input,
query: wb.query.value,
excludeFunctions: wb.settings.excludeFunctions || undefined,
excludeUnderscoreProps: wb.settings.excludeUnderscoreProps || undefined,
excludeDollarProps: wb.settings.excludeDollarProps || undefined,
})
}
</script>
<template>
<div class="h-100dvh flex flex-col bg-base color-base font-sans">
<main class="flex-1 min-h-0">
<LayoutSplitPane storage-key="data-inspector-panes" class="h-full">
<Pane :size="38" min-size="24" class="min-w-0">
<div class="flex flex-col h-full overflow-hidden min-h-0">
<AppHeader />
<DataSourcePanel />
<QueryPanel />
<SavedQueriesPanel
:saved="savedApi.saved.value"
:suggested="wb.activeSource.value?.queries ?? []"
:current-query="wb.query.value"
:current-filters="wb.settings"
:readonly="connection.mode === 'static'"
class="px3 py2"
@load="wb.applyRecipe($event)"
@remove="savedApi.remove($event)"
@save="saveCurrent"
/>
</div>
</Pane>
<Pane class="min-w-0">
<ResultViewer
:result="wb.result.value"
:has-result="wb.hasResult.value"
:stats="wb.stats.value"
:stats-stale="wb.statsStale.value"
:error="wb.serverError.value"
:running="wb.running.value"
:last-run-at="wb.lastRunAt.value"
:expand="wb.expandNode"
@rerun="wb.runNow()"
@query-subquery="wb.applySubquery($event)"
@query-append="wb.appendPath($event)"
/>
</Pane>
</LayoutSplitPane>
</main>
</div>
</template>