@@ -5,10 +5,9 @@ import ActionDarkToggle from '@antfu/design/components/Action/ActionDarkToggle.v
55import DisplayBadge from ' @antfu/design/components/Display/DisplayBadge.vue'
66import FormSelect from ' @antfu/design/components/Form/FormSelect.vue'
77import LayoutSplitPane from ' @antfu/design/components/Layout/LayoutSplitPane.vue'
8- import LayoutToolbar from ' @antfu/design/components/Layout/LayoutToolbar.vue'
98import { Pane } from ' splitpanes'
10- import { computed , onMounted } from ' vue'
11- import DataSourceInfoPanel from ' ./components/DataSourceInfoPanel .vue'
9+ import { computed , onMounted , ref } from ' vue'
10+ import DataShapePanel from ' ./components/DataShapePanel .vue'
1211import QueryEditor from ' ./components/QueryEditor.vue'
1312import QuerySettings from ' ./components/QuerySettings.vue'
1413import ResultViewer from ' ./components/ResultViewer.vue'
@@ -26,6 +25,8 @@ const sourceOptions = computed(() =>
2625 wb .sources .value .map (s => ({ value: s .id , label: s .title })),
2726)
2827
28+ const showDataSourceDetails = ref (false )
29+
2930onMounted (async () => {
3031 await connect ()
3132 if (! connection .connected )
@@ -75,45 +76,67 @@ function queryAppend(path: string): void {
7576
7677<template >
7778 <div class =" h-100dvh flex flex-col bg-base color-base font-sans" >
78- <LayoutToolbar :glass =" false " >
79- <div class =" flex items-center gap-1.5 shrink-0 font-semibold text-sm select-none" >
80- <span class =" i-ph:tree-structure-duotone text-base color-active" />
81- <span >Data Inspector</span >
82- </div >
83-
84- <div class =" flex items-center gap-2" >
85- <FormSelect v-model =" wb .sourceId .value " :options =" sourceOptions " placeholder="Data source" />
86- <DisplayBadge v-if =" wb .activeSource .value ?.static " text="static" :color =" false " />
87- </div >
88-
89- <template #end >
90- <span
91- class =" flex items-center gap-1.5 text-xs color-muted select-none"
92- :title =" connection.error ?? undefined"
93- >
94- <span
95- class =" inline-block w-2 h-2 rounded-full"
96- :class =" connection.connected ? 'bg-green-600 dark:bg-green-400' : 'bg-red-600 dark:bg-red-400'"
97- />
98- {{ connection.status }}
99- </span >
100- <ActionDarkToggle
101- :color-scheme =" colorScheme "
102- @update :color-scheme =" colorScheme = $event "
103- />
104- </template >
105- </LayoutToolbar >
106-
10779 <main class =" flex-1 min-h-0" >
10880 <LayoutSplitPane storage-key="data-inspector-panes" class="h-full">
10981 <Pane :size =" 38 " min-size="24" class="min-w-0">
110- <!-- The left column's sections resize with the same split-pane setup. -->
111- <LayoutSplitPane horizontal storage-key="data-inspector-left-panes" class="h-full">
112- <Pane :size =" 42 " min-size="20" class="flex flex-col gap-2 p-3 pb-1.5 min-h-0">
113- <div class =" flex items-center gap-2 font-semibold text-sm select-none" >
114- <div >Jora Query</div >
82+ <div class =" flex flex-col h-full overflow-hidden min-h-0" >
83+ <div class =" flex items-center gap-1.5 shrink-0 select-none border-b border-base py1 px3" >
84+ <span class =" i-ph-crosshair-duotone text-base color-primary" />
85+ <span class =" color-primary font-semibold" >Data Inspector</span >
86+ <span class =" op-fade text-sm" >Inspect server side data/objects interactively</span >
87+ <DisplayBadge
88+ v-if =" connection .status !== ' connected' "
89+ class="flex items-center gap-1.5 py-1 text-xs select-none capitalize"
90+ :title =" connection .error ?? undefined "
91+ :text =" connection .status "
92+ :color =" connection .connected ? 100 : 200 "
93+ />
94+ <div class =" flex-auto" />
95+ <ActionDarkToggle
96+ :color-scheme =" colorScheme "
97+ @update :color-scheme =" colorScheme = $event "
98+ />
99+ </div >
100+
101+ <div class =" px3 py2 border-b border-base flex flex-col gap-2 shrink-0" >
102+ <div class =" flex items-center gap-2" >
103+ <div class =" font-semibold text-xs op-fade uppercase tracking-wide select-none" >
104+ Data Source
105+ </div >
106+ <FormSelect v-model =" wb .sourceId .value " :options =" sourceOptions " placeholder="Data source" class="text-sm font-semibold text-primary" />
107+ <DisplayBadge v-if =" wb .activeSource .value ?.static " text="static" :color =" false " />
108+ <div v-if =" wb.activeSource.value?.description && !showDataSourceDetails" class =" text-xs op-fade ws-nowrap of-hidden shrink" :title =" wb.activeSource.value?.description" >
109+ {{ wb.activeSource.value?.description }}
110+ </div >
111+ <div class =" flex-auto" />
112+ <Button
113+ size="sm"
114+ :icon =" showDataSourceDetails ? ' i-ph:eye-slash-duotone' : ' i-ph:eye-duotone' "
115+ @click =" showDataSourceDetails = ! showDataSourceDetails "
116+ >
117+ <span >{{ showDataSourceDetails ? 'Hide' : 'Show' }} details</span >
118+ </Button >
119+ </div >
120+
121+ <template v-if =" showDataSourceDetails " >
122+ <DataShapePanel
123+ :source =" wb .activeSource .value "
124+ :skeleton =" wb .skeleton .value "
125+ :error =" wb .skeletonError .value "
126+ :loading =" wb .skeletonLoading .value "
127+ @refresh =" wb .loadSkeleton ()"
128+ @select =" queryProp "
129+ />
130+ </template >
131+ </div >
132+
133+ <div class =" border-b border-base flex-auto flex-col flex" >
134+ <div class =" flex px3 py2 items-center gap-2 select-none " >
135+ <div class =" font-semibold text-xs op-fade uppercase tracking-wide select-none" >
136+ Jora Query
137+ </div >
115138 <a
116- href =" https://discoveryjs.github.io/jora/"
139+ href =" https://discoveryjs.github.io/jora/#article:jora-syntax "
117140 target =" _blank"
118141 title =" Jora query language reference"
119142 class =" flex items-center gap-1 color-muted hover:color-active"
@@ -124,6 +147,7 @@ function queryAppend(path: string): void {
124147 <Button
125148 v-if =" wb .query .value "
126149 :disabled =" ! wb .query .value "
150+ class="text-sm"
127151 title="Clear query"
128152 icon="i-ph:trash-duotone "
129153 @click =" wb .query .value = ' ' "
@@ -133,6 +157,7 @@ function queryAppend(path: string): void {
133157 <Button
134158 :disabled =" wb .running .value "
135159 :loading =" wb .running .value "
160+ class="text-sm"
136161 title="Run query"
137162 icon="i-ph:play-duotone "
138163 @click =" wb .runNow ()"
@@ -144,37 +169,25 @@ function queryAppend(path: string): void {
144169 v-model =" wb .query .value "
145170 :syntax =" wb .syntax .value "
146171 :suggestions =" wb .suggestions .value "
147- class="flex-1 min-h-0"
172+ class="flex-1 min-h-0 mx2 "
148173 @run =" wb .runNow ()"
149174 @suggest =" wb .scheduleSuggestions ($event )"
150175 @accept =" wb .acceptSuggestion ($event )"
151176 @dismiss =" wb .suggestions .value = []"
152177 />
153- <QuerySettings v-model =" wb .settings " />
154- </Pane >
155- <Pane min-size="12" class="p-3 pt-1.5 min-h-0">
156- <SavedQueriesPanel
157- :saved =" savedApi .saved .value "
158- :suggested =" wb .activeSource .value ?.queries ?? []"
159- :current-query =" wb .query .value "
160- :current-filters =" wb .settings "
161- class="h-full"
162- @load =" loadRecipe "
163- @remove =" savedApi .remove ($event )"
164- @save =" saveCurrent "
165- />
166- </Pane >
167- <Pane :size =" 33 " min-size="12" class="p-3 py-1.5 min-h-0">
168- <DataSourceInfoPanel
169- :source =" wb .activeSource .value "
170- :skeleton =" wb .skeleton .value "
171- :error =" wb .skeletonError .value "
172- :loading =" wb .skeletonLoading .value "
173- @refresh =" wb .loadSkeleton ()"
174- @select =" queryProp "
175- />
176- </Pane >
177- </LayoutSplitPane >
178+ <QuerySettings v-model =" wb .settings " class="py2 px4" />
179+ </div >
180+ <SavedQueriesPanel
181+ :saved =" savedApi .saved .value "
182+ :suggested =" wb .activeSource .value ?.queries ?? []"
183+ :current-query =" wb .query .value "
184+ :current-filters =" wb .settings "
185+ class="px3 py2"
186+ @load =" loadRecipe "
187+ @remove =" savedApi .remove ($event )"
188+ @save =" saveCurrent "
189+ />
190+ </div >
178191 </Pane >
179192 <Pane class="min-w-0">
180193 <ResultViewer
0 commit comments