@tanstack/query-devtools 5.0.5 → 5.4.2
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.
- package/build/Devtools/{Y2E2LEWB.jsx → 7FRXYIEA.jsx} +1285 -228
- package/build/Devtools/{B2H37NSB.js → HESZYUBG.js} +1578 -468
- package/build/Devtools/{7SMWYMBY.jsx → KWB27UDF.jsx} +1285 -228
- package/build/Devtools/{3Y5CBXUA.js → MVUALMJ4.js} +1578 -468
- package/build/chunk/{AHAJNSNO.jsx → JRAMSUCV.jsx} +5 -0
- package/build/dev.cjs +1590 -473
- package/build/dev.js +1 -1
- package/build/dev.jsx +2 -2
- package/build/index.cjs +1590 -473
- package/build/index.js +1 -1
- package/build/index.jsx +2 -2
- package/package.json +1 -1
- package/src/Devtools.tsx +819 -131
- package/src/Explorer.tsx +5 -5
- package/src/icons/index.tsx +89 -0
- package/src/theme.ts +82 -82
- package/src/utils.tsx +46 -1
package/src/Devtools.tsx
CHANGED
|
@@ -15,16 +15,18 @@ import { TransitionGroup } from 'solid-transition-group'
|
|
|
15
15
|
import { Key } from '@solid-primitives/keyed'
|
|
16
16
|
import { createLocalStorage } from '@solid-primitives/storage'
|
|
17
17
|
import { createResizeObserver } from '@solid-primitives/resize-observer'
|
|
18
|
-
import { DropdownMenu } from '@kobalte/core'
|
|
18
|
+
import { DropdownMenu, RadioGroup } from '@kobalte/core'
|
|
19
19
|
import { tokens } from './theme'
|
|
20
20
|
import {
|
|
21
21
|
convertRemToPixels,
|
|
22
22
|
displayValue,
|
|
23
|
+
getMutationStatusColor,
|
|
23
24
|
getPreferredColorScheme,
|
|
24
25
|
getQueryStatusColor,
|
|
25
26
|
getQueryStatusColorByLabel,
|
|
26
27
|
getQueryStatusLabel,
|
|
27
28
|
getSidedProp,
|
|
29
|
+
mutationSortFns,
|
|
28
30
|
sortFns,
|
|
29
31
|
} from './utils'
|
|
30
32
|
import {
|
|
@@ -32,16 +34,20 @@ import {
|
|
|
32
34
|
ArrowLeft,
|
|
33
35
|
ArrowRight,
|
|
34
36
|
ArrowUp,
|
|
37
|
+
CheckCircle,
|
|
35
38
|
ChevronDown,
|
|
39
|
+
LoadingCircle,
|
|
36
40
|
Monitor,
|
|
37
41
|
Moon,
|
|
38
42
|
Offline,
|
|
43
|
+
PauseCircle,
|
|
39
44
|
Search,
|
|
40
45
|
Settings,
|
|
41
46
|
Sun,
|
|
42
47
|
TanstackLogo,
|
|
43
48
|
Trash,
|
|
44
49
|
Wifi,
|
|
50
|
+
XCircle,
|
|
45
51
|
} from './icons'
|
|
46
52
|
import Explorer from './Explorer'
|
|
47
53
|
import {
|
|
@@ -57,7 +63,13 @@ import type {
|
|
|
57
63
|
DevtoolsPosition,
|
|
58
64
|
QueryDevtoolsProps,
|
|
59
65
|
} from './Context'
|
|
60
|
-
import type {
|
|
66
|
+
import type {
|
|
67
|
+
Mutation,
|
|
68
|
+
MutationCache,
|
|
69
|
+
Query,
|
|
70
|
+
QueryCache,
|
|
71
|
+
QueryState,
|
|
72
|
+
} from '@tanstack/query-core'
|
|
61
73
|
import type { StorageObject, StorageSetter } from '@solid-primitives/storage'
|
|
62
74
|
import type { Accessor, Component, JSX, Setter } from 'solid-js'
|
|
63
75
|
|
|
@@ -68,7 +80,7 @@ interface DevtoolsPanelProps {
|
|
|
68
80
|
|
|
69
81
|
interface QueryStatusProps {
|
|
70
82
|
label: string
|
|
71
|
-
color: 'green' | 'yellow' | 'gray' | 'blue' | 'purple'
|
|
83
|
+
color: 'green' | 'yellow' | 'gray' | 'blue' | 'purple' | 'red'
|
|
72
84
|
count: number
|
|
73
85
|
}
|
|
74
86
|
|
|
@@ -84,10 +96,14 @@ const DEFAULT_HEIGHT = 500
|
|
|
84
96
|
const DEFAULT_WIDTH = 500
|
|
85
97
|
const DEFAULT_SORT_FN_NAME = Object.keys(sortFns)[0]
|
|
86
98
|
const DEFAULT_SORT_ORDER = 1
|
|
99
|
+
const DEFAULT_MUTATION_SORT_FN_NAME = Object.keys(mutationSortFns)[0]
|
|
87
100
|
|
|
88
101
|
const [selectedQueryHash, setSelectedQueryHash] = createSignal<string | null>(
|
|
89
102
|
null,
|
|
90
103
|
)
|
|
104
|
+
const [selectedMutationId, setSelectedMutationId] = createSignal<number | null>(
|
|
105
|
+
null,
|
|
106
|
+
)
|
|
91
107
|
const [panelWidth, setPanelWidth] = createSignal(0)
|
|
92
108
|
|
|
93
109
|
export const DevtoolsComponent: Component<QueryDevtoolsProps> = (props) => {
|
|
@@ -145,8 +161,9 @@ export const Devtools: Component<DevtoolsPanelProps> = (props) => {
|
|
|
145
161
|
)
|
|
146
162
|
})
|
|
147
163
|
|
|
164
|
+
let transitionsContainerRef!: HTMLDivElement
|
|
148
165
|
createEffect(() => {
|
|
149
|
-
const root =
|
|
166
|
+
const root = transitionsContainerRef.parentElement as HTMLElement
|
|
150
167
|
const height = props.localStore.height || DEFAULT_HEIGHT
|
|
151
168
|
const width = props.localStore.width || DEFAULT_WIDTH
|
|
152
169
|
const panelPosition = position()
|
|
@@ -160,6 +177,23 @@ export const Devtools: Component<DevtoolsPanelProps> = (props) => {
|
|
|
160
177
|
)
|
|
161
178
|
})
|
|
162
179
|
|
|
180
|
+
// Calculates the inherited font size of the parent and sets it as a CSS variable
|
|
181
|
+
// All the design tokens are calculated based on this variable
|
|
182
|
+
onMount(() => {
|
|
183
|
+
// This is to make sure that the font size is updated when the stylesheet is updated
|
|
184
|
+
// and the user focuses back on the window
|
|
185
|
+
const onFocus = () => {
|
|
186
|
+
const root = transitionsContainerRef.parentElement as HTMLElement
|
|
187
|
+
const fontSize = getComputedStyle(root).fontSize
|
|
188
|
+
root.style.setProperty('--tsqd-font-size', fontSize)
|
|
189
|
+
}
|
|
190
|
+
onFocus()
|
|
191
|
+
window.addEventListener('focus', onFocus)
|
|
192
|
+
onCleanup(() => {
|
|
193
|
+
window.removeEventListener('focus', onFocus)
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
|
|
163
197
|
return (
|
|
164
198
|
<div
|
|
165
199
|
// styles for animating the panel in and out
|
|
@@ -193,6 +227,7 @@ export const Devtools: Component<DevtoolsPanelProps> = (props) => {
|
|
|
193
227
|
`,
|
|
194
228
|
'tsqd-transitions-container',
|
|
195
229
|
)}
|
|
230
|
+
ref={transitionsContainerRef}
|
|
196
231
|
>
|
|
197
232
|
<TransitionGroup name="tsqd-panel-transition">
|
|
198
233
|
<Show when={isOpen()}>
|
|
@@ -234,13 +269,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
234
269
|
|
|
235
270
|
const [isResizing, setIsResizing] = createSignal(false)
|
|
236
271
|
|
|
237
|
-
const sort = createMemo(() => props.localStore.sort || DEFAULT_SORT_FN_NAME)
|
|
238
|
-
const sortOrder = createMemo(
|
|
239
|
-
() => Number(props.localStore.sortOrder) || DEFAULT_SORT_ORDER,
|
|
240
|
-
) as () => 1 | -1
|
|
241
|
-
|
|
242
|
-
const [offline, setOffline] = createSignal(false)
|
|
243
|
-
|
|
244
272
|
const position = createMemo(
|
|
245
273
|
() =>
|
|
246
274
|
(props.localStore.position ||
|
|
@@ -248,41 +276,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
248
276
|
POSITION) as DevtoolsPosition,
|
|
249
277
|
)
|
|
250
278
|
|
|
251
|
-
const sortFn = createMemo(() => sortFns[sort() as string])
|
|
252
|
-
|
|
253
|
-
const onlineManager = createMemo(
|
|
254
|
-
() => useQueryDevtoolsContext().onlineManager,
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
const cache = createMemo(() => {
|
|
258
|
-
return useQueryDevtoolsContext().client.getQueryCache()
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
const queryCount = createSubscribeToQueryCacheBatcher((queryCache) => {
|
|
262
|
-
return queryCache().getAll().length
|
|
263
|
-
}, false)
|
|
264
|
-
|
|
265
|
-
const queries = createMemo(
|
|
266
|
-
on(
|
|
267
|
-
() => [queryCount(), props.localStore.filter, sort(), sortOrder()],
|
|
268
|
-
() => {
|
|
269
|
-
const curr = cache().getAll()
|
|
270
|
-
|
|
271
|
-
const filtered = props.localStore.filter
|
|
272
|
-
? curr.filter(
|
|
273
|
-
(item) =>
|
|
274
|
-
rankItem(item.queryHash, props.localStore.filter || '').passed,
|
|
275
|
-
)
|
|
276
|
-
: [...curr]
|
|
277
|
-
|
|
278
|
-
const sorted = sortFn()
|
|
279
|
-
? filtered.sort((a, b) => sortFn()!(a, b) * sortOrder())
|
|
280
|
-
: filtered
|
|
281
|
-
return sorted
|
|
282
|
-
},
|
|
283
|
-
),
|
|
284
|
-
)
|
|
285
|
-
|
|
286
279
|
const handleDragStart: JSX.EventHandler<HTMLDivElement, MouseEvent> = (
|
|
287
280
|
event,
|
|
288
281
|
) => {
|
|
@@ -344,9 +337,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
344
337
|
document.addEventListener('mouseup', unsub, false)
|
|
345
338
|
}
|
|
346
339
|
|
|
347
|
-
setupQueryCacheSubscription()
|
|
348
|
-
|
|
349
|
-
let queriesContainerRef!: HTMLDivElement
|
|
350
340
|
let panelRef!: HTMLDivElement
|
|
351
341
|
|
|
352
342
|
onMount(() => {
|
|
@@ -357,10 +347,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
357
347
|
})
|
|
358
348
|
})
|
|
359
349
|
|
|
360
|
-
const setDevtoolsPosition = (pos: DevtoolsPosition) => {
|
|
361
|
-
props.setLocalStore('position', pos)
|
|
362
|
-
}
|
|
363
|
-
|
|
364
350
|
createEffect(() => {
|
|
365
351
|
const rootContainer = panelRef.parentElement?.parentElement?.parentElement
|
|
366
352
|
if (!rootContainer) return
|
|
@@ -465,51 +451,212 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
465
451
|
>
|
|
466
452
|
<ChevronDown />
|
|
467
453
|
</button>
|
|
454
|
+
<ContentView
|
|
455
|
+
localStore={props.localStore}
|
|
456
|
+
setLocalStore={props.setLocalStore}
|
|
457
|
+
/>
|
|
458
|
+
</aside>
|
|
459
|
+
)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const ContentView: Component<DevtoolsPanelProps> = (props) => {
|
|
463
|
+
setupQueryCacheSubscription()
|
|
464
|
+
setupMutationCacheSubscription()
|
|
465
|
+
|
|
466
|
+
let containerRef!: HTMLDivElement
|
|
467
|
+
const theme = useTheme()
|
|
468
|
+
const styles = createMemo(() => {
|
|
469
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
const [selectedView, setSelectedView] = createSignal<'queries' | 'mutations'>(
|
|
473
|
+
'queries',
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
const sort = createMemo(() => props.localStore.sort || DEFAULT_SORT_FN_NAME)
|
|
477
|
+
const sortOrder = createMemo(
|
|
478
|
+
() => Number(props.localStore.sortOrder) || DEFAULT_SORT_ORDER,
|
|
479
|
+
) as () => 1 | -1
|
|
480
|
+
|
|
481
|
+
const mutationSort = createMemo(
|
|
482
|
+
() => props.localStore.mutationSort || DEFAULT_MUTATION_SORT_FN_NAME,
|
|
483
|
+
)
|
|
484
|
+
const mutationSortOrder = createMemo(
|
|
485
|
+
() => Number(props.localStore.mutationSortOrder) || DEFAULT_SORT_ORDER,
|
|
486
|
+
) as () => 1 | -1
|
|
487
|
+
|
|
488
|
+
const [offline, setOffline] = createSignal(false)
|
|
489
|
+
|
|
490
|
+
const sortFn = createMemo(() => sortFns[sort() as string])
|
|
491
|
+
const mutationSortFn = createMemo(
|
|
492
|
+
() => mutationSortFns[mutationSort() as string],
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
const onlineManager = createMemo(
|
|
496
|
+
() => useQueryDevtoolsContext().onlineManager,
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
const query_cache = createMemo(() => {
|
|
500
|
+
return useQueryDevtoolsContext().client.getQueryCache()
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
const mutation_cache = createMemo(() => {
|
|
504
|
+
return useQueryDevtoolsContext().client.getMutationCache()
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
const queryCount = createSubscribeToQueryCacheBatcher((queryCache) => {
|
|
508
|
+
return queryCache().getAll().length
|
|
509
|
+
}, false)
|
|
510
|
+
|
|
511
|
+
const queries = createMemo(
|
|
512
|
+
on(
|
|
513
|
+
() => [queryCount(), props.localStore.filter, sort(), sortOrder()],
|
|
514
|
+
() => {
|
|
515
|
+
const curr = query_cache().getAll()
|
|
516
|
+
|
|
517
|
+
const filtered = props.localStore.filter
|
|
518
|
+
? curr.filter(
|
|
519
|
+
(item) =>
|
|
520
|
+
rankItem(item.queryHash, props.localStore.filter || '').passed,
|
|
521
|
+
)
|
|
522
|
+
: [...curr]
|
|
523
|
+
|
|
524
|
+
const sorted = sortFn()
|
|
525
|
+
? filtered.sort((a, b) => sortFn()!(a, b) * sortOrder())
|
|
526
|
+
: filtered
|
|
527
|
+
return sorted
|
|
528
|
+
},
|
|
529
|
+
),
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
const mutationCount = createSubscribeToMutationCacheBatcher(
|
|
533
|
+
(mutationCache) => {
|
|
534
|
+
return mutationCache().getAll().length
|
|
535
|
+
},
|
|
536
|
+
false,
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
const mutations = createMemo(
|
|
540
|
+
on(
|
|
541
|
+
() => [
|
|
542
|
+
mutationCount(),
|
|
543
|
+
props.localStore.mutationFilter,
|
|
544
|
+
mutationSort(),
|
|
545
|
+
mutationSortOrder(),
|
|
546
|
+
],
|
|
547
|
+
() => {
|
|
548
|
+
const curr = mutation_cache().getAll()
|
|
549
|
+
|
|
550
|
+
const filtered = props.localStore.mutationFilter
|
|
551
|
+
? curr.filter((item) => {
|
|
552
|
+
const value = `${
|
|
553
|
+
item.options.mutationKey
|
|
554
|
+
? JSON.stringify(item.options.mutationKey) + ' - '
|
|
555
|
+
: ''
|
|
556
|
+
}${new Date(item.state.submittedAt).toLocaleString()}`
|
|
557
|
+
return rankItem(value, props.localStore.mutationFilter || '')
|
|
558
|
+
.passed
|
|
559
|
+
})
|
|
560
|
+
: [...curr]
|
|
561
|
+
|
|
562
|
+
const sorted = mutationSortFn()
|
|
563
|
+
? filtered.sort(
|
|
564
|
+
(a, b) => mutationSortFn()!(a, b) * mutationSortOrder(),
|
|
565
|
+
)
|
|
566
|
+
: filtered
|
|
567
|
+
return sorted
|
|
568
|
+
},
|
|
569
|
+
),
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
const setDevtoolsPosition = (pos: DevtoolsPosition) => {
|
|
573
|
+
props.setLocalStore('position', pos)
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Sets the Font Size variable on portal menu elements since they will be outside
|
|
577
|
+
// the main panel container
|
|
578
|
+
const setComputedVariables = (el: HTMLDivElement) => {
|
|
579
|
+
const computedStyle = getComputedStyle(containerRef)
|
|
580
|
+
const variable = computedStyle.getPropertyValue('--tsqd-font-size')
|
|
581
|
+
el.style.setProperty('--tsqd-font-size', variable)
|
|
582
|
+
}
|
|
583
|
+
return (
|
|
584
|
+
<>
|
|
468
585
|
<div
|
|
469
|
-
ref={queriesContainerRef}
|
|
470
586
|
// When the panels are stacked we use the height style
|
|
471
587
|
// to divide the panels into two equal parts
|
|
472
588
|
class={cx(
|
|
473
589
|
styles().queriesContainer,
|
|
474
590
|
panelWidth() < secondBreakpoint &&
|
|
475
|
-
selectedQueryHash() &&
|
|
591
|
+
(selectedQueryHash() || selectedMutationId()) &&
|
|
476
592
|
css`
|
|
477
593
|
height: 50%;
|
|
478
594
|
max-height: 50%;
|
|
479
595
|
`,
|
|
480
596
|
'tsqd-queries-container',
|
|
481
597
|
)}
|
|
598
|
+
ref={containerRef}
|
|
482
599
|
>
|
|
483
600
|
<div class={cx(styles().row, 'tsqd-header')}>
|
|
484
|
-
<
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
<span class={cx(styles().tanstackLogo, 'tsqd-text-logo-tanstack')}>
|
|
490
|
-
TANSTACK
|
|
491
|
-
</span>
|
|
492
|
-
<span
|
|
493
|
-
class={cx(
|
|
494
|
-
styles().queryFlavorLogo,
|
|
495
|
-
'tsqd-text-logo-query-flavor',
|
|
496
|
-
)}
|
|
601
|
+
<div class={styles().logoAndToggleContainer}>
|
|
602
|
+
<button
|
|
603
|
+
class={cx(styles().logo, 'tsqd-text-logo-container')}
|
|
604
|
+
onClick={() => props.setLocalStore('open', 'false')}
|
|
605
|
+
aria-label="Close Tanstack query devtools"
|
|
497
606
|
>
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
607
|
+
<span
|
|
608
|
+
class={cx(styles().tanstackLogo, 'tsqd-text-logo-tanstack')}
|
|
609
|
+
>
|
|
610
|
+
TANSTACK
|
|
611
|
+
</span>
|
|
612
|
+
<span
|
|
613
|
+
class={cx(
|
|
614
|
+
styles().queryFlavorLogo,
|
|
615
|
+
'tsqd-text-logo-query-flavor',
|
|
616
|
+
)}
|
|
617
|
+
>
|
|
618
|
+
{useQueryDevtoolsContext().queryFlavor} v
|
|
619
|
+
{useQueryDevtoolsContext().version}
|
|
620
|
+
</span>
|
|
621
|
+
</button>
|
|
622
|
+
<RadioGroup.Root
|
|
623
|
+
class={cx(styles().viewToggle)}
|
|
624
|
+
value={selectedView()}
|
|
625
|
+
onChange={(value) => {
|
|
626
|
+
setSelectedView(value as 'queries' | 'mutations')
|
|
627
|
+
setSelectedQueryHash(null)
|
|
628
|
+
setSelectedMutationId(null)
|
|
629
|
+
}}
|
|
630
|
+
>
|
|
631
|
+
<RadioGroup.Item value="queries" class="tsqd-radio-toggle">
|
|
632
|
+
<RadioGroup.ItemInput />
|
|
633
|
+
<RadioGroup.ItemControl>
|
|
634
|
+
<RadioGroup.ItemIndicator />
|
|
635
|
+
</RadioGroup.ItemControl>
|
|
636
|
+
<RadioGroup.ItemLabel title="Toggle Queries View">
|
|
637
|
+
Queries
|
|
638
|
+
</RadioGroup.ItemLabel>
|
|
639
|
+
</RadioGroup.Item>
|
|
640
|
+
<RadioGroup.Item value="mutations" class="tsqd-radio-toggle">
|
|
641
|
+
<RadioGroup.ItemInput />
|
|
642
|
+
<RadioGroup.ItemControl>
|
|
643
|
+
<RadioGroup.ItemIndicator />
|
|
644
|
+
</RadioGroup.ItemControl>
|
|
645
|
+
<RadioGroup.ItemLabel title="Toggle Mutations View">
|
|
646
|
+
Mutations
|
|
647
|
+
</RadioGroup.ItemLabel>
|
|
648
|
+
</RadioGroup.Item>
|
|
649
|
+
</RadioGroup.Root>
|
|
650
|
+
</div>
|
|
651
|
+
|
|
652
|
+
<Show when={selectedView() === 'queries'}>
|
|
653
|
+
<QueryStatusCount />
|
|
654
|
+
</Show>
|
|
655
|
+
<Show when={selectedView() === 'mutations'}>
|
|
656
|
+
<MutationStatusCount />
|
|
657
|
+
</Show>
|
|
503
658
|
</div>
|
|
504
|
-
<div
|
|
505
|
-
class={cx(
|
|
506
|
-
styles().row,
|
|
507
|
-
css`
|
|
508
|
-
gap: ${tokens.size[2.5]};
|
|
509
|
-
`,
|
|
510
|
-
'tsqd-filters-actions-container',
|
|
511
|
-
)}
|
|
512
|
-
>
|
|
659
|
+
<div class={cx(styles().row, 'tsqd-filters-actions-container')}>
|
|
513
660
|
<div class={cx(styles().filtersContainer, 'tsqd-filters-container')}>
|
|
514
661
|
<div
|
|
515
662
|
class={cx(
|
|
@@ -522,11 +669,19 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
522
669
|
aria-label="Filter queries by query key"
|
|
523
670
|
type="text"
|
|
524
671
|
placeholder="Filter"
|
|
525
|
-
onInput={(e) =>
|
|
526
|
-
|
|
527
|
-
|
|
672
|
+
onInput={(e) => {
|
|
673
|
+
if (selectedView() === 'queries') {
|
|
674
|
+
props.setLocalStore('filter', e.currentTarget.value)
|
|
675
|
+
} else {
|
|
676
|
+
props.setLocalStore('mutationFilter', e.currentTarget.value)
|
|
677
|
+
}
|
|
678
|
+
}}
|
|
528
679
|
class="tsqd-query-filter-textfield"
|
|
529
|
-
value={
|
|
680
|
+
value={
|
|
681
|
+
selectedView() === 'queries'
|
|
682
|
+
? props.localStore.filter || ''
|
|
683
|
+
: props.localStore.mutationFilter || ''
|
|
684
|
+
}
|
|
530
685
|
/>
|
|
531
686
|
</div>
|
|
532
687
|
<div
|
|
@@ -535,33 +690,74 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
535
690
|
'tsqd-query-filter-sort-container',
|
|
536
691
|
)}
|
|
537
692
|
>
|
|
538
|
-
<
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
693
|
+
<Show when={selectedView() === 'queries'}>
|
|
694
|
+
<select
|
|
695
|
+
value={sort()}
|
|
696
|
+
onChange={(e) => {
|
|
697
|
+
props.setLocalStore('sort', e.currentTarget.value)
|
|
698
|
+
}}
|
|
699
|
+
>
|
|
700
|
+
{Object.keys(sortFns).map((key) => (
|
|
701
|
+
<option value={key}>Sort by {key}</option>
|
|
702
|
+
))}
|
|
703
|
+
</select>
|
|
704
|
+
</Show>
|
|
705
|
+
<Show when={selectedView() === 'mutations'}>
|
|
706
|
+
<select
|
|
707
|
+
value={mutationSort()}
|
|
708
|
+
onChange={(e) => {
|
|
709
|
+
props.setLocalStore('mutationSort', e.currentTarget.value)
|
|
710
|
+
}}
|
|
711
|
+
>
|
|
712
|
+
{Object.keys(mutationSortFns).map((key) => (
|
|
713
|
+
<option value={key}>Sort by {key}</option>
|
|
714
|
+
))}
|
|
715
|
+
</select>
|
|
716
|
+
</Show>
|
|
548
717
|
<ChevronDown />
|
|
549
718
|
</div>
|
|
550
719
|
<button
|
|
551
720
|
onClick={() => {
|
|
552
|
-
|
|
721
|
+
if (selectedView() === 'queries') {
|
|
722
|
+
props.setLocalStore('sortOrder', String(sortOrder() * -1))
|
|
723
|
+
} else {
|
|
724
|
+
props.setLocalStore(
|
|
725
|
+
'mutationSortOrder',
|
|
726
|
+
String(mutationSortOrder() * -1),
|
|
727
|
+
)
|
|
728
|
+
}
|
|
553
729
|
}}
|
|
554
730
|
aria-label={`Sort order ${
|
|
555
|
-
|
|
731
|
+
(selectedView() === 'queries'
|
|
732
|
+
? sortOrder()
|
|
733
|
+
: mutationSortOrder()) === -1
|
|
734
|
+
? 'descending'
|
|
735
|
+
: 'ascending'
|
|
556
736
|
}`}
|
|
557
|
-
aria-pressed={
|
|
737
|
+
aria-pressed={
|
|
738
|
+
(selectedView() === 'queries'
|
|
739
|
+
? sortOrder()
|
|
740
|
+
: mutationSortOrder()) === -1
|
|
741
|
+
}
|
|
558
742
|
class="tsqd-query-filter-sort-order-btn"
|
|
559
743
|
>
|
|
560
|
-
<Show
|
|
744
|
+
<Show
|
|
745
|
+
when={
|
|
746
|
+
(selectedView() === 'queries'
|
|
747
|
+
? sortOrder()
|
|
748
|
+
: mutationSortOrder()) === 1
|
|
749
|
+
}
|
|
750
|
+
>
|
|
561
751
|
<span>Asc</span>
|
|
562
752
|
<ArrowUp />
|
|
563
753
|
</Show>
|
|
564
|
-
<Show
|
|
754
|
+
<Show
|
|
755
|
+
when={
|
|
756
|
+
(selectedView() === 'queries'
|
|
757
|
+
? sortOrder()
|
|
758
|
+
: mutationSortOrder()) === -1
|
|
759
|
+
}
|
|
760
|
+
>
|
|
565
761
|
<span>Desc</span>
|
|
566
762
|
<ArrowDown />
|
|
567
763
|
</Show>
|
|
@@ -571,7 +767,11 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
571
767
|
<div class={cx(styles().actionsContainer, 'tsqd-actions-container')}>
|
|
572
768
|
<button
|
|
573
769
|
onClick={() => {
|
|
574
|
-
|
|
770
|
+
if (selectedView() === 'queries') {
|
|
771
|
+
query_cache().clear()
|
|
772
|
+
} else {
|
|
773
|
+
mutation_cache().clear()
|
|
774
|
+
}
|
|
575
775
|
}}
|
|
576
776
|
class={cx(
|
|
577
777
|
styles().actionsBtn,
|
|
@@ -579,7 +779,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
579
779
|
'tsqd-action-clear-cache',
|
|
580
780
|
)}
|
|
581
781
|
aria-label="Clear query cache"
|
|
582
|
-
title=
|
|
782
|
+
title={`Clear ${selectedView()} cache`}
|
|
583
783
|
>
|
|
584
784
|
<Trash />
|
|
585
785
|
</button>
|
|
@@ -624,7 +824,9 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
624
824
|
>
|
|
625
825
|
<Settings />
|
|
626
826
|
</DropdownMenu.Trigger>
|
|
627
|
-
<DropdownMenu.Portal
|
|
827
|
+
<DropdownMenu.Portal
|
|
828
|
+
ref={(el) => setComputedVariables(el as HTMLDivElement)}
|
|
829
|
+
>
|
|
628
830
|
<DropdownMenu.Content
|
|
629
831
|
class={cx(styles().settingsMenu, 'tsqd-settings-menu')}
|
|
630
832
|
>
|
|
@@ -647,7 +849,9 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
647
849
|
<span>Position</span>
|
|
648
850
|
<ChevronDown />
|
|
649
851
|
</DropdownMenu.SubTrigger>
|
|
650
|
-
<DropdownMenu.Portal
|
|
852
|
+
<DropdownMenu.Portal
|
|
853
|
+
ref={(el) => setComputedVariables(el as HTMLDivElement)}
|
|
854
|
+
>
|
|
651
855
|
<DropdownMenu.SubContent
|
|
652
856
|
class={cx(
|
|
653
857
|
styles().settingsMenu,
|
|
@@ -724,7 +928,9 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
724
928
|
<span>Theme</span>
|
|
725
929
|
<ChevronDown />
|
|
726
930
|
</DropdownMenu.SubTrigger>
|
|
727
|
-
<DropdownMenu.Portal
|
|
931
|
+
<DropdownMenu.Portal
|
|
932
|
+
ref={(el) => setComputedVariables(el as HTMLDivElement)}
|
|
933
|
+
>
|
|
728
934
|
<DropdownMenu.SubContent
|
|
729
935
|
class={cx(
|
|
730
936
|
styles().settingsMenu,
|
|
@@ -787,23 +993,43 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
787
993
|
</DropdownMenu.Root>
|
|
788
994
|
</div>
|
|
789
995
|
</div>
|
|
790
|
-
<
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
<
|
|
798
|
-
{(
|
|
799
|
-
|
|
996
|
+
<Show when={selectedView() === 'queries'}>
|
|
997
|
+
<div
|
|
998
|
+
class={cx(
|
|
999
|
+
styles().overflowQueryContainer,
|
|
1000
|
+
'tsqd-queries-overflow-container',
|
|
1001
|
+
)}
|
|
1002
|
+
>
|
|
1003
|
+
<div class="tsqd-queries-container">
|
|
1004
|
+
<Key by={(q) => q.queryHash} each={queries()}>
|
|
1005
|
+
{(query) => <QueryRow query={query()} />}
|
|
1006
|
+
</Key>
|
|
1007
|
+
</div>
|
|
800
1008
|
</div>
|
|
801
|
-
</
|
|
1009
|
+
</Show>
|
|
1010
|
+
<Show when={selectedView() === 'mutations'}>
|
|
1011
|
+
<div
|
|
1012
|
+
class={cx(
|
|
1013
|
+
styles().overflowQueryContainer,
|
|
1014
|
+
'tsqd-mutations-overflow-container',
|
|
1015
|
+
)}
|
|
1016
|
+
>
|
|
1017
|
+
<div class="tsqd-mutations-container">
|
|
1018
|
+
<Key by={(m) => m.mutationId} each={mutations()}>
|
|
1019
|
+
{(mutation) => <MutationRow mutation={mutation()} />}
|
|
1020
|
+
</Key>
|
|
1021
|
+
</div>
|
|
1022
|
+
</div>
|
|
1023
|
+
</Show>
|
|
802
1024
|
</div>
|
|
803
|
-
<Show when={selectedQueryHash()}>
|
|
1025
|
+
<Show when={selectedView() === 'queries' && selectedQueryHash()}>
|
|
804
1026
|
<QueryDetails />
|
|
805
1027
|
</Show>
|
|
806
|
-
|
|
1028
|
+
|
|
1029
|
+
<Show when={selectedView() === 'mutations' && selectedMutationId()}>
|
|
1030
|
+
<MutationDetails />
|
|
1031
|
+
</Show>
|
|
1032
|
+
</>
|
|
807
1033
|
)
|
|
808
1034
|
}
|
|
809
1035
|
|
|
@@ -907,6 +1133,114 @@ export const QueryRow: Component<{ query: Query }> = (props) => {
|
|
|
907
1133
|
)
|
|
908
1134
|
}
|
|
909
1135
|
|
|
1136
|
+
export const MutationRow: Component<{ mutation: Mutation }> = (props) => {
|
|
1137
|
+
const theme = useTheme()
|
|
1138
|
+
const styles = createMemo(() => {
|
|
1139
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1140
|
+
})
|
|
1141
|
+
|
|
1142
|
+
const { colors, alpha } = tokens
|
|
1143
|
+
const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
|
|
1144
|
+
|
|
1145
|
+
const mutationState = createSubscribeToMutationCacheBatcher(
|
|
1146
|
+
(mutationCache) => {
|
|
1147
|
+
const mutations = mutationCache().getAll()
|
|
1148
|
+
const mutation = mutations.find(
|
|
1149
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1150
|
+
)
|
|
1151
|
+
return mutation?.state
|
|
1152
|
+
},
|
|
1153
|
+
)
|
|
1154
|
+
|
|
1155
|
+
const isPaused = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1156
|
+
const mutations = mutationCache().getAll()
|
|
1157
|
+
const mutation = mutations.find(
|
|
1158
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1159
|
+
)
|
|
1160
|
+
if (!mutation) return false
|
|
1161
|
+
return mutation.state.isPaused
|
|
1162
|
+
})
|
|
1163
|
+
|
|
1164
|
+
const status = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1165
|
+
const mutations = mutationCache().getAll()
|
|
1166
|
+
const mutation = mutations.find(
|
|
1167
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1168
|
+
)
|
|
1169
|
+
if (!mutation) return 'idle'
|
|
1170
|
+
return mutation.state.status
|
|
1171
|
+
})
|
|
1172
|
+
|
|
1173
|
+
const color = createMemo(() =>
|
|
1174
|
+
getMutationStatusColor({
|
|
1175
|
+
isPaused: isPaused(),
|
|
1176
|
+
status: status(),
|
|
1177
|
+
}),
|
|
1178
|
+
)
|
|
1179
|
+
|
|
1180
|
+
const getObserverCountColorStyles = () => {
|
|
1181
|
+
if (color() === 'gray') {
|
|
1182
|
+
return css`
|
|
1183
|
+
background-color: ${t(colors[color()][200], colors[color()][700])};
|
|
1184
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1185
|
+
`
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
return css`
|
|
1189
|
+
background-color: ${t(
|
|
1190
|
+
colors[color()][200] + alpha[80],
|
|
1191
|
+
colors[color()][900],
|
|
1192
|
+
)};
|
|
1193
|
+
color: ${t(colors[color()][800], colors[color()][300])};
|
|
1194
|
+
`
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
return (
|
|
1198
|
+
<Show when={mutationState()}>
|
|
1199
|
+
<button
|
|
1200
|
+
onClick={() => {
|
|
1201
|
+
setSelectedMutationId(
|
|
1202
|
+
props.mutation.mutationId === selectedMutationId()
|
|
1203
|
+
? null
|
|
1204
|
+
: props.mutation.mutationId,
|
|
1205
|
+
)
|
|
1206
|
+
}}
|
|
1207
|
+
class={cx(
|
|
1208
|
+
styles().queryRow,
|
|
1209
|
+
selectedMutationId() === props.mutation.mutationId &&
|
|
1210
|
+
styles().selectedQueryRow,
|
|
1211
|
+
'tsqd-query-row',
|
|
1212
|
+
)}
|
|
1213
|
+
aria-label={`Mutation submitted at ${new Date(
|
|
1214
|
+
props.mutation.state.submittedAt,
|
|
1215
|
+
).toLocaleString()}`}
|
|
1216
|
+
>
|
|
1217
|
+
<div
|
|
1218
|
+
class={cx(getObserverCountColorStyles(), 'tsqd-query-observer-count')}
|
|
1219
|
+
>
|
|
1220
|
+
<Show when={color() === 'purple'}>
|
|
1221
|
+
<PauseCircle />
|
|
1222
|
+
</Show>
|
|
1223
|
+
<Show when={color() === 'green'}>
|
|
1224
|
+
<CheckCircle />
|
|
1225
|
+
</Show>
|
|
1226
|
+
<Show when={color() === 'red'}>
|
|
1227
|
+
<XCircle />
|
|
1228
|
+
</Show>
|
|
1229
|
+
<Show when={color() === 'yellow'}>
|
|
1230
|
+
<LoadingCircle />
|
|
1231
|
+
</Show>
|
|
1232
|
+
</div>
|
|
1233
|
+
<code class="tsqd-query-hash">
|
|
1234
|
+
<Show when={props.mutation.options.mutationKey}>
|
|
1235
|
+
{JSON.stringify(props.mutation.options.mutationKey)} -{' '}
|
|
1236
|
+
</Show>
|
|
1237
|
+
{new Date(props.mutation.state.submittedAt).toLocaleString()}
|
|
1238
|
+
</code>
|
|
1239
|
+
</button>
|
|
1240
|
+
</Show>
|
|
1241
|
+
)
|
|
1242
|
+
}
|
|
1243
|
+
|
|
910
1244
|
export const QueryStatusCount: Component = () => {
|
|
911
1245
|
const stale = createSubscribeToQueryCacheBatcher(
|
|
912
1246
|
(queryCache) =>
|
|
@@ -961,6 +1295,76 @@ export const QueryStatusCount: Component = () => {
|
|
|
961
1295
|
)
|
|
962
1296
|
}
|
|
963
1297
|
|
|
1298
|
+
export const MutationStatusCount: Component = () => {
|
|
1299
|
+
const success = createSubscribeToMutationCacheBatcher(
|
|
1300
|
+
(mutationCache) =>
|
|
1301
|
+
mutationCache()
|
|
1302
|
+
.getAll()
|
|
1303
|
+
.filter(
|
|
1304
|
+
(m) =>
|
|
1305
|
+
getMutationStatusColor({
|
|
1306
|
+
isPaused: m.state.isPaused,
|
|
1307
|
+
status: m.state.status,
|
|
1308
|
+
}) === 'green',
|
|
1309
|
+
).length,
|
|
1310
|
+
)
|
|
1311
|
+
|
|
1312
|
+
const pending = createSubscribeToMutationCacheBatcher(
|
|
1313
|
+
(mutationCache) =>
|
|
1314
|
+
mutationCache()
|
|
1315
|
+
.getAll()
|
|
1316
|
+
.filter(
|
|
1317
|
+
(m) =>
|
|
1318
|
+
getMutationStatusColor({
|
|
1319
|
+
isPaused: m.state.isPaused,
|
|
1320
|
+
status: m.state.status,
|
|
1321
|
+
}) === 'yellow',
|
|
1322
|
+
).length,
|
|
1323
|
+
)
|
|
1324
|
+
|
|
1325
|
+
const paused = createSubscribeToMutationCacheBatcher(
|
|
1326
|
+
(mutationCache) =>
|
|
1327
|
+
mutationCache()
|
|
1328
|
+
.getAll()
|
|
1329
|
+
.filter(
|
|
1330
|
+
(m) =>
|
|
1331
|
+
getMutationStatusColor({
|
|
1332
|
+
isPaused: m.state.isPaused,
|
|
1333
|
+
status: m.state.status,
|
|
1334
|
+
}) === 'purple',
|
|
1335
|
+
).length,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
const error = createSubscribeToMutationCacheBatcher(
|
|
1339
|
+
(mutationCache) =>
|
|
1340
|
+
mutationCache()
|
|
1341
|
+
.getAll()
|
|
1342
|
+
.filter(
|
|
1343
|
+
(m) =>
|
|
1344
|
+
getMutationStatusColor({
|
|
1345
|
+
isPaused: m.state.isPaused,
|
|
1346
|
+
status: m.state.status,
|
|
1347
|
+
}) === 'red',
|
|
1348
|
+
).length,
|
|
1349
|
+
)
|
|
1350
|
+
|
|
1351
|
+
const theme = useTheme()
|
|
1352
|
+
const styles = createMemo(() => {
|
|
1353
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1354
|
+
})
|
|
1355
|
+
|
|
1356
|
+
return (
|
|
1357
|
+
<div
|
|
1358
|
+
class={cx(styles().queryStatusContainer, 'tsqd-query-status-container')}
|
|
1359
|
+
>
|
|
1360
|
+
<QueryStatus label="Paused" color="purple" count={paused()} />
|
|
1361
|
+
<QueryStatus label="Pending" color="yellow" count={pending()} />
|
|
1362
|
+
<QueryStatus label="Success" color="green" count={success()} />
|
|
1363
|
+
<QueryStatus label="Error" color="red" count={error()} />
|
|
1364
|
+
</div>
|
|
1365
|
+
)
|
|
1366
|
+
}
|
|
1367
|
+
|
|
964
1368
|
export const QueryStatus: Component<QueryStatusProps> = (props) => {
|
|
965
1369
|
const theme = useTheme()
|
|
966
1370
|
const styles = createMemo(() => {
|
|
@@ -1430,7 +1834,7 @@ const QueryDetails = () => {
|
|
|
1430
1834
|
</div>
|
|
1431
1835
|
<div
|
|
1432
1836
|
style={{
|
|
1433
|
-
padding:
|
|
1837
|
+
padding: tokens.size[2],
|
|
1434
1838
|
}}
|
|
1435
1839
|
class="tsqd-query-details-explorer-container tsqd-query-details-data-explorer"
|
|
1436
1840
|
>
|
|
@@ -1447,7 +1851,7 @@ const QueryDetails = () => {
|
|
|
1447
1851
|
</div>
|
|
1448
1852
|
<div
|
|
1449
1853
|
style={{
|
|
1450
|
-
padding:
|
|
1854
|
+
padding: tokens.size[2],
|
|
1451
1855
|
}}
|
|
1452
1856
|
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1453
1857
|
>
|
|
@@ -1462,7 +1866,170 @@ const QueryDetails = () => {
|
|
|
1462
1866
|
)
|
|
1463
1867
|
}
|
|
1464
1868
|
|
|
1465
|
-
const
|
|
1869
|
+
const MutationDetails = () => {
|
|
1870
|
+
const theme = useTheme()
|
|
1871
|
+
const styles = createMemo(() => {
|
|
1872
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1873
|
+
})
|
|
1874
|
+
|
|
1875
|
+
const { colors } = tokens
|
|
1876
|
+
const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
|
|
1877
|
+
|
|
1878
|
+
const isPaused = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1879
|
+
const mutations = mutationCache().getAll()
|
|
1880
|
+
const mutation = mutations.find(
|
|
1881
|
+
(m) => m.mutationId === selectedMutationId(),
|
|
1882
|
+
)
|
|
1883
|
+
if (!mutation) return false
|
|
1884
|
+
return mutation.state.isPaused
|
|
1885
|
+
})
|
|
1886
|
+
|
|
1887
|
+
const status = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1888
|
+
const mutations = mutationCache().getAll()
|
|
1889
|
+
const mutation = mutations.find(
|
|
1890
|
+
(m) => m.mutationId === selectedMutationId(),
|
|
1891
|
+
)
|
|
1892
|
+
if (!mutation) return 'idle'
|
|
1893
|
+
return mutation.state.status
|
|
1894
|
+
})
|
|
1895
|
+
|
|
1896
|
+
const color = createMemo(() =>
|
|
1897
|
+
getMutationStatusColor({
|
|
1898
|
+
isPaused: isPaused(),
|
|
1899
|
+
status: status(),
|
|
1900
|
+
}),
|
|
1901
|
+
)
|
|
1902
|
+
|
|
1903
|
+
const activeMutation = createSubscribeToMutationCacheBatcher(
|
|
1904
|
+
(mutationCache) =>
|
|
1905
|
+
mutationCache()
|
|
1906
|
+
.getAll()
|
|
1907
|
+
.find((mutation) => mutation.mutationId === selectedMutationId()),
|
|
1908
|
+
false,
|
|
1909
|
+
)
|
|
1910
|
+
|
|
1911
|
+
const getQueryStatusColors = () => {
|
|
1912
|
+
if (color() === 'gray') {
|
|
1913
|
+
return css`
|
|
1914
|
+
background-color: ${t(colors[color()][200], colors[color()][700])};
|
|
1915
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1916
|
+
border-color: ${t(colors[color()][400], colors[color()][600])};
|
|
1917
|
+
`
|
|
1918
|
+
}
|
|
1919
|
+
return css`
|
|
1920
|
+
background-color: ${t(colors[color()][100], colors[color()][900])};
|
|
1921
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1922
|
+
border-color: ${t(colors[color()][400], colors[color()][600])};
|
|
1923
|
+
`
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
return (
|
|
1927
|
+
<Show when={activeMutation()}>
|
|
1928
|
+
<div
|
|
1929
|
+
class={cx(styles().detailsContainer, 'tsqd-query-details-container')}
|
|
1930
|
+
>
|
|
1931
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1932
|
+
Mutation Details
|
|
1933
|
+
</div>
|
|
1934
|
+
<div
|
|
1935
|
+
class={cx(
|
|
1936
|
+
styles().detailsBody,
|
|
1937
|
+
'tsqd-query-details-summary-container',
|
|
1938
|
+
)}
|
|
1939
|
+
>
|
|
1940
|
+
<div class="tsqd-query-details-summary">
|
|
1941
|
+
<pre>
|
|
1942
|
+
<code>
|
|
1943
|
+
<Show
|
|
1944
|
+
when={activeMutation()!.options.mutationKey}
|
|
1945
|
+
fallback={'No mutationKey found'}
|
|
1946
|
+
>
|
|
1947
|
+
{displayValue(activeMutation()!.options.mutationKey, true)}
|
|
1948
|
+
</Show>
|
|
1949
|
+
</code>
|
|
1950
|
+
</pre>
|
|
1951
|
+
<span
|
|
1952
|
+
class={cx(styles().queryDetailsStatus, getQueryStatusColors())}
|
|
1953
|
+
>
|
|
1954
|
+
<Show when={color() === 'purple'}>pending</Show>
|
|
1955
|
+
<Show when={color() !== 'purple'}>{status()}</Show>
|
|
1956
|
+
</span>
|
|
1957
|
+
</div>
|
|
1958
|
+
<div class="tsqd-query-details-last-updated">
|
|
1959
|
+
<span>Submitted At:</span>
|
|
1960
|
+
<span>
|
|
1961
|
+
{new Date(
|
|
1962
|
+
activeMutation()!.state.submittedAt,
|
|
1963
|
+
).toLocaleTimeString()}
|
|
1964
|
+
</span>
|
|
1965
|
+
</div>
|
|
1966
|
+
</div>
|
|
1967
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1968
|
+
Variables Details
|
|
1969
|
+
</div>
|
|
1970
|
+
<div
|
|
1971
|
+
style={{
|
|
1972
|
+
padding: tokens.size[2],
|
|
1973
|
+
}}
|
|
1974
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1975
|
+
>
|
|
1976
|
+
<Explorer
|
|
1977
|
+
label="Variables"
|
|
1978
|
+
defaultExpanded={['Variables']}
|
|
1979
|
+
value={activeMutation()!.state.variables}
|
|
1980
|
+
/>
|
|
1981
|
+
</div>
|
|
1982
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1983
|
+
Context Details
|
|
1984
|
+
</div>
|
|
1985
|
+
<div
|
|
1986
|
+
style={{
|
|
1987
|
+
padding: tokens.size[2],
|
|
1988
|
+
}}
|
|
1989
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1990
|
+
>
|
|
1991
|
+
<Explorer
|
|
1992
|
+
label="Context"
|
|
1993
|
+
defaultExpanded={['Context']}
|
|
1994
|
+
value={activeMutation()!.state.context}
|
|
1995
|
+
/>
|
|
1996
|
+
</div>
|
|
1997
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1998
|
+
Data Explorer
|
|
1999
|
+
</div>
|
|
2000
|
+
<div
|
|
2001
|
+
style={{
|
|
2002
|
+
padding: tokens.size[2],
|
|
2003
|
+
}}
|
|
2004
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
2005
|
+
>
|
|
2006
|
+
<Explorer
|
|
2007
|
+
label="Data"
|
|
2008
|
+
defaultExpanded={['Data']}
|
|
2009
|
+
value={activeMutation()!.state.data}
|
|
2010
|
+
/>
|
|
2011
|
+
</div>
|
|
2012
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
2013
|
+
Mutations Explorer
|
|
2014
|
+
</div>
|
|
2015
|
+
<div
|
|
2016
|
+
style={{
|
|
2017
|
+
padding: tokens.size[2],
|
|
2018
|
+
}}
|
|
2019
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
2020
|
+
>
|
|
2021
|
+
<Explorer
|
|
2022
|
+
label="Mutation"
|
|
2023
|
+
defaultExpanded={['Mutation']}
|
|
2024
|
+
value={activeMutation()}
|
|
2025
|
+
/>
|
|
2026
|
+
</div>
|
|
2027
|
+
</div>
|
|
2028
|
+
</Show>
|
|
2029
|
+
)
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
const queryCacheMap = new Map<(q: Accessor<QueryCache>) => any, Setter<any>>()
|
|
1466
2033
|
|
|
1467
2034
|
const setupQueryCacheSubscription = () => {
|
|
1468
2035
|
const queryCache = createMemo(() => {
|
|
@@ -1471,7 +2038,7 @@ const setupQueryCacheSubscription = () => {
|
|
|
1471
2038
|
})
|
|
1472
2039
|
|
|
1473
2040
|
const unsub = queryCache().subscribe(() => {
|
|
1474
|
-
for (const [callback, setter] of
|
|
2041
|
+
for (const [callback, setter] of queryCacheMap.entries()) {
|
|
1475
2042
|
queueMicrotask(() => {
|
|
1476
2043
|
setter(callback(queryCache))
|
|
1477
2044
|
})
|
|
@@ -1479,7 +2046,7 @@ const setupQueryCacheSubscription = () => {
|
|
|
1479
2046
|
})
|
|
1480
2047
|
|
|
1481
2048
|
onCleanup(() => {
|
|
1482
|
-
|
|
2049
|
+
queryCacheMap.clear()
|
|
1483
2050
|
unsub()
|
|
1484
2051
|
})
|
|
1485
2052
|
|
|
@@ -1505,11 +2072,67 @@ const createSubscribeToQueryCacheBatcher = <T,>(
|
|
|
1505
2072
|
})
|
|
1506
2073
|
|
|
1507
2074
|
// @ts-ignore
|
|
1508
|
-
|
|
2075
|
+
queryCacheMap.set(callback, setValue)
|
|
1509
2076
|
|
|
1510
2077
|
onCleanup(() => {
|
|
1511
2078
|
// @ts-ignore
|
|
1512
|
-
|
|
2079
|
+
queryCacheMap.delete(callback)
|
|
2080
|
+
})
|
|
2081
|
+
|
|
2082
|
+
return value
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
const mutationCacheMap = new Map<
|
|
2086
|
+
(q: Accessor<MutationCache>) => any,
|
|
2087
|
+
Setter<any>
|
|
2088
|
+
>()
|
|
2089
|
+
|
|
2090
|
+
const setupMutationCacheSubscription = () => {
|
|
2091
|
+
const mutationCache = createMemo(() => {
|
|
2092
|
+
const client = useQueryDevtoolsContext().client
|
|
2093
|
+
return client.getMutationCache()
|
|
2094
|
+
})
|
|
2095
|
+
|
|
2096
|
+
const unsub = mutationCache().subscribe(() => {
|
|
2097
|
+
for (const [callback, setter] of mutationCacheMap.entries()) {
|
|
2098
|
+
queueMicrotask(() => {
|
|
2099
|
+
setter(callback(mutationCache))
|
|
2100
|
+
})
|
|
2101
|
+
}
|
|
2102
|
+
})
|
|
2103
|
+
|
|
2104
|
+
onCleanup(() => {
|
|
2105
|
+
mutationCacheMap.clear()
|
|
2106
|
+
unsub()
|
|
2107
|
+
})
|
|
2108
|
+
|
|
2109
|
+
return unsub
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
const createSubscribeToMutationCacheBatcher = <T,>(
|
|
2113
|
+
callback: (queryCache: Accessor<MutationCache>) => Exclude<T, Function>,
|
|
2114
|
+
equalityCheck: boolean = true,
|
|
2115
|
+
) => {
|
|
2116
|
+
const mutationCache = createMemo(() => {
|
|
2117
|
+
const client = useQueryDevtoolsContext().client
|
|
2118
|
+
return client.getMutationCache()
|
|
2119
|
+
})
|
|
2120
|
+
|
|
2121
|
+
const [value, setValue] = createSignal<T>(
|
|
2122
|
+
callback(mutationCache),
|
|
2123
|
+
!equalityCheck ? { equals: false } : undefined,
|
|
2124
|
+
)
|
|
2125
|
+
|
|
2126
|
+
createEffect(() => {
|
|
2127
|
+
setValue(callback(mutationCache))
|
|
2128
|
+
})
|
|
2129
|
+
|
|
2130
|
+
// @ts-ignore
|
|
2131
|
+
mutationCacheMap.set(callback, setValue)
|
|
2132
|
+
|
|
2133
|
+
onCleanup(() => {
|
|
2134
|
+
// @ts-ignore
|
|
2135
|
+
mutationCacheMap.delete(callback)
|
|
1513
2136
|
})
|
|
1514
2137
|
|
|
1515
2138
|
return value
|
|
@@ -1606,7 +2229,7 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1606
2229
|
right: 0;
|
|
1607
2230
|
left: 0;
|
|
1608
2231
|
max-height: 90%;
|
|
1609
|
-
min-height:
|
|
2232
|
+
min-height: ${size[14]};
|
|
1610
2233
|
border-bottom: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
|
|
1611
2234
|
`,
|
|
1612
2235
|
'panel-position-bottom': css`
|
|
@@ -1614,7 +2237,7 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1614
2237
|
right: 0;
|
|
1615
2238
|
left: 0;
|
|
1616
2239
|
max-height: 90%;
|
|
1617
|
-
min-height:
|
|
2240
|
+
min-height: ${size[14]};
|
|
1618
2241
|
border-top: ${t(colors.gray[400], colors.darkGray[300])} 1px solid;
|
|
1619
2242
|
`,
|
|
1620
2243
|
'panel-position-right': css`
|
|
@@ -1788,7 +2411,7 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1788
2411
|
justify-content: space-between;
|
|
1789
2412
|
align-items: center;
|
|
1790
2413
|
padding: ${tokens.size[2]} ${tokens.size[2.5]};
|
|
1791
|
-
gap: ${tokens.size[
|
|
2414
|
+
gap: ${tokens.size[2.5]};
|
|
1792
2415
|
border-bottom: ${t(colors.gray[300], colors.darkGray[500])} 1px solid;
|
|
1793
2416
|
align-items: center;
|
|
1794
2417
|
& > button {
|
|
@@ -1800,8 +2423,19 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1800
2423
|
flex-direction: column;
|
|
1801
2424
|
}
|
|
1802
2425
|
`,
|
|
2426
|
+
logoAndToggleContainer: css`
|
|
2427
|
+
display: flex;
|
|
2428
|
+
gap: ${tokens.size[3]};
|
|
2429
|
+
align-items: center;
|
|
2430
|
+
`,
|
|
1803
2431
|
logo: css`
|
|
1804
2432
|
cursor: pointer;
|
|
2433
|
+
display: flex;
|
|
2434
|
+
flex-direction: column;
|
|
2435
|
+
background-color: transparent;
|
|
2436
|
+
border: none;
|
|
2437
|
+
gap: ${tokens.size[0.5]};
|
|
2438
|
+
padding: 0px;
|
|
1805
2439
|
&:hover {
|
|
1806
2440
|
opacity: 0.7;
|
|
1807
2441
|
}
|
|
@@ -1935,6 +2569,8 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1935
2569
|
outline: 2px solid ${colors.blue[800]};
|
|
1936
2570
|
}
|
|
1937
2571
|
& svg {
|
|
2572
|
+
width: ${tokens.size[3]};
|
|
2573
|
+
height: ${tokens.size[3]};
|
|
1938
2574
|
color: ${t(colors.gray[500], colors.gray[400])};
|
|
1939
2575
|
}
|
|
1940
2576
|
}
|
|
@@ -2020,8 +2656,8 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
2020
2656
|
border-radius: ${tokens.border.radius.sm};
|
|
2021
2657
|
background-color: ${t(colors.gray[100], colors.darkGray[400])};
|
|
2022
2658
|
border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
|
|
2023
|
-
width:
|
|
2024
|
-
height:
|
|
2659
|
+
width: ${tokens.size[6.5]};
|
|
2660
|
+
height: ${tokens.size[6.5]};
|
|
2025
2661
|
justify-content: center;
|
|
2026
2662
|
display: flex;
|
|
2027
2663
|
align-items: center;
|
|
@@ -2173,6 +2809,8 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
2173
2809
|
|
|
2174
2810
|
& pre {
|
|
2175
2811
|
margin: 0;
|
|
2812
|
+
display: flex;
|
|
2813
|
+
align-items: center;
|
|
2176
2814
|
}
|
|
2177
2815
|
`,
|
|
2178
2816
|
queryDetailsStatus: css`
|
|
@@ -2353,6 +2991,56 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
2353
2991
|
background-color: ${t(colors.purple[100], colors.purple[900])};
|
|
2354
2992
|
}
|
|
2355
2993
|
`,
|
|
2994
|
+
viewToggle: css`
|
|
2995
|
+
border-radius: ${tokens.border.radius.sm};
|
|
2996
|
+
background-color: ${t(colors.gray[200], colors.darkGray[600])};
|
|
2997
|
+
border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
|
|
2998
|
+
display: flex;
|
|
2999
|
+
padding: 0;
|
|
3000
|
+
font-size: ${font.size.xs};
|
|
3001
|
+
color: ${t(colors.gray[700], colors.gray[300])};
|
|
3002
|
+
overflow: hidden;
|
|
3003
|
+
|
|
3004
|
+
&:has(:focus-visible) {
|
|
3005
|
+
outline: 2px solid ${colors.blue[800]};
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
& .tsqd-radio-toggle {
|
|
3009
|
+
opacity: 0.5;
|
|
3010
|
+
display: flex;
|
|
3011
|
+
& label {
|
|
3012
|
+
display: flex;
|
|
3013
|
+
align-items: center;
|
|
3014
|
+
cursor: pointer;
|
|
3015
|
+
line-height: ${font.lineHeight.md};
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
& label:hover {
|
|
3019
|
+
background-color: ${t(colors.gray[100], colors.darkGray[500])};
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
& > [data-checked] {
|
|
3024
|
+
opacity: 1;
|
|
3025
|
+
background-color: ${t(colors.gray[100], colors.darkGray[400])};
|
|
3026
|
+
& label:hover {
|
|
3027
|
+
background-color: ${t(colors.gray[100], colors.darkGray[400])};
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
& .tsqd-radio-toggle:first-child {
|
|
3032
|
+
& label {
|
|
3033
|
+
padding: 0 ${tokens.size[1.5]} 0 ${tokens.size[2]};
|
|
3034
|
+
}
|
|
3035
|
+
border-right: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
& .tsqd-radio-toggle:nth-child(2) {
|
|
3039
|
+
& label {
|
|
3040
|
+
padding: 0 ${tokens.size[2]} 0 ${tokens.size[1.5]};
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
`,
|
|
2356
3044
|
}
|
|
2357
3045
|
}
|
|
2358
3046
|
|