@mongoosejs/studio 0.0.136 → 0.0.138
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/README.md +30 -0
- package/frontend/public/app.js +412 -68
- package/frontend/public/tw.css +111 -0
- package/frontend/src/list-json/list-json.html +17 -3
- package/frontend/src/list-json/list-json.js +350 -25
- package/frontend/src/models/models.css +1 -0
- package/frontend/src/models/models.html +19 -4
- package/frontend/src/models/models.js +58 -27
- package/next.js +97 -0
- package/package.json +1 -1
- package/frontend/src/list-json/list-json.css +0 -3
package/frontend/public/tw.css
CHANGED
|
@@ -594,6 +594,10 @@ video {
|
|
|
594
594
|
pointer-events: none;
|
|
595
595
|
}
|
|
596
596
|
|
|
597
|
+
.invisible {
|
|
598
|
+
visibility: hidden;
|
|
599
|
+
}
|
|
600
|
+
|
|
597
601
|
.fixed {
|
|
598
602
|
position: fixed;
|
|
599
603
|
}
|
|
@@ -635,6 +639,10 @@ video {
|
|
|
635
639
|
right: 0.25rem;
|
|
636
640
|
}
|
|
637
641
|
|
|
642
|
+
.right-2 {
|
|
643
|
+
right: 0.5rem;
|
|
644
|
+
}
|
|
645
|
+
|
|
638
646
|
.right-4 {
|
|
639
647
|
right: 1rem;
|
|
640
648
|
}
|
|
@@ -643,6 +651,10 @@ video {
|
|
|
643
651
|
top: 0.25rem;
|
|
644
652
|
}
|
|
645
653
|
|
|
654
|
+
.top-2 {
|
|
655
|
+
top: 0.5rem;
|
|
656
|
+
}
|
|
657
|
+
|
|
646
658
|
.top-\[65px\] {
|
|
647
659
|
top: 65px;
|
|
648
660
|
}
|
|
@@ -701,6 +713,11 @@ video {
|
|
|
701
713
|
margin-bottom: -0.5rem;
|
|
702
714
|
}
|
|
703
715
|
|
|
716
|
+
.mx-1 {
|
|
717
|
+
margin-left: 0.25rem;
|
|
718
|
+
margin-right: 0.25rem;
|
|
719
|
+
}
|
|
720
|
+
|
|
704
721
|
.mx-4 {
|
|
705
722
|
margin-left: 1rem;
|
|
706
723
|
margin-right: 1rem;
|
|
@@ -764,6 +781,10 @@ video {
|
|
|
764
781
|
margin-left: 0.75rem;
|
|
765
782
|
}
|
|
766
783
|
|
|
784
|
+
.ml-4 {
|
|
785
|
+
margin-left: 1rem;
|
|
786
|
+
}
|
|
787
|
+
|
|
767
788
|
.ml-auto {
|
|
768
789
|
margin-left: auto;
|
|
769
790
|
}
|
|
@@ -1164,6 +1185,10 @@ video {
|
|
|
1164
1185
|
align-items: center;
|
|
1165
1186
|
}
|
|
1166
1187
|
|
|
1188
|
+
.items-baseline {
|
|
1189
|
+
align-items: baseline;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1167
1192
|
.justify-end {
|
|
1168
1193
|
justify-content: flex-end;
|
|
1169
1194
|
}
|
|
@@ -1238,6 +1263,12 @@ video {
|
|
|
1238
1263
|
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
|
1239
1264
|
}
|
|
1240
1265
|
|
|
1266
|
+
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
|
1267
|
+
--tw-space-y-reverse: 0;
|
|
1268
|
+
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
|
1269
|
+
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1241
1272
|
.divide-y > :not([hidden]) ~ :not([hidden]) {
|
|
1242
1273
|
--tw-divide-y-reverse: 0;
|
|
1243
1274
|
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
|
@@ -1856,14 +1887,27 @@ video {
|
|
|
1856
1887
|
text-transform: capitalize;
|
|
1857
1888
|
}
|
|
1858
1889
|
|
|
1890
|
+
.italic {
|
|
1891
|
+
font-style: italic;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1859
1894
|
.leading-6 {
|
|
1860
1895
|
line-height: 1.5rem;
|
|
1861
1896
|
}
|
|
1862
1897
|
|
|
1898
|
+
.leading-none {
|
|
1899
|
+
line-height: 1;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1863
1902
|
.leading-tight {
|
|
1864
1903
|
line-height: 1.25;
|
|
1865
1904
|
}
|
|
1866
1905
|
|
|
1906
|
+
.text-amber-600 {
|
|
1907
|
+
--tw-text-opacity: 1;
|
|
1908
|
+
color: rgb(217 119 6 / var(--tw-text-opacity));
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1867
1911
|
.text-black {
|
|
1868
1912
|
--tw-text-opacity: 1;
|
|
1869
1913
|
color: rgb(0 0 0 / var(--tw-text-opacity));
|
|
@@ -1879,6 +1923,11 @@ video {
|
|
|
1879
1923
|
color: rgb(30 64 175 / var(--tw-text-opacity));
|
|
1880
1924
|
}
|
|
1881
1925
|
|
|
1926
|
+
.text-emerald-600 {
|
|
1927
|
+
--tw-text-opacity: 1;
|
|
1928
|
+
color: rgb(5 150 105 / var(--tw-text-opacity));
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1882
1931
|
.text-forest-green-500 {
|
|
1883
1932
|
--tw-text-opacity: 1;
|
|
1884
1933
|
color: rgb(0 242 58 / var(--tw-text-opacity));
|
|
@@ -1959,6 +2008,21 @@ video {
|
|
|
1959
2008
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
1960
2009
|
}
|
|
1961
2010
|
|
|
2011
|
+
.text-slate-500 {
|
|
2012
|
+
--tw-text-opacity: 1;
|
|
2013
|
+
color: rgb(100 116 139 / var(--tw-text-opacity));
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
.text-slate-700 {
|
|
2017
|
+
--tw-text-opacity: 1;
|
|
2018
|
+
color: rgb(51 65 85 / var(--tw-text-opacity));
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
.text-slate-800 {
|
|
2022
|
+
--tw-text-opacity: 1;
|
|
2023
|
+
color: rgb(30 41 59 / var(--tw-text-opacity));
|
|
2024
|
+
}
|
|
2025
|
+
|
|
1962
2026
|
.text-ultramarine-600 {
|
|
1963
2027
|
--tw-text-opacity: 1;
|
|
1964
2028
|
color: rgb(24 35 255 / var(--tw-text-opacity));
|
|
@@ -1974,6 +2038,11 @@ video {
|
|
|
1974
2038
|
color: rgb(220 73 73 / var(--tw-text-opacity));
|
|
1975
2039
|
}
|
|
1976
2040
|
|
|
2041
|
+
.text-violet-600 {
|
|
2042
|
+
--tw-text-opacity: 1;
|
|
2043
|
+
color: rgb(124 58 237 / var(--tw-text-opacity));
|
|
2044
|
+
}
|
|
2045
|
+
|
|
1977
2046
|
.text-white {
|
|
1978
2047
|
--tw-text-opacity: 1;
|
|
1979
2048
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
|
@@ -1983,6 +2052,10 @@ video {
|
|
|
1983
2052
|
accent-color: #0284c7;
|
|
1984
2053
|
}
|
|
1985
2054
|
|
|
2055
|
+
.opacity-0 {
|
|
2056
|
+
opacity: 0;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
1986
2059
|
.opacity-25 {
|
|
1987
2060
|
opacity: 0.25;
|
|
1988
2061
|
}
|
|
@@ -2117,12 +2190,22 @@ video {
|
|
|
2117
2190
|
transition-duration: 150ms;
|
|
2118
2191
|
}
|
|
2119
2192
|
|
|
2193
|
+
.transition-opacity {
|
|
2194
|
+
transition-property: opacity;
|
|
2195
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
2196
|
+
transition-duration: 150ms;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2120
2199
|
.transition-transform {
|
|
2121
2200
|
transition-property: transform;
|
|
2122
2201
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
2123
2202
|
transition-duration: 150ms;
|
|
2124
2203
|
}
|
|
2125
2204
|
|
|
2205
|
+
.duration-150 {
|
|
2206
|
+
transition-duration: 150ms;
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2126
2209
|
.duration-200 {
|
|
2127
2210
|
transition-duration: 200ms;
|
|
2128
2211
|
}
|
|
@@ -2320,6 +2403,11 @@ video {
|
|
|
2320
2403
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
2321
2404
|
}
|
|
2322
2405
|
|
|
2406
|
+
.hover\:text-slate-700:hover {
|
|
2407
|
+
--tw-text-opacity: 1;
|
|
2408
|
+
color: rgb(51 65 85 / var(--tw-text-opacity));
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2323
2411
|
.hover\:text-ultramarine-900:hover {
|
|
2324
2412
|
--tw-text-opacity: 1;
|
|
2325
2413
|
color: rgb(6 14 172 / var(--tw-text-opacity));
|
|
@@ -2438,6 +2526,10 @@ video {
|
|
|
2438
2526
|
--tw-ring-offset-color: #1f2937;
|
|
2439
2527
|
}
|
|
2440
2528
|
|
|
2529
|
+
.focus-visible\:opacity-100:focus-visible {
|
|
2530
|
+
opacity: 1;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2441
2533
|
.focus-visible\:outline:focus-visible {
|
|
2442
2534
|
outline-style: solid;
|
|
2443
2535
|
}
|
|
@@ -2494,6 +2586,21 @@ video {
|
|
|
2494
2586
|
outline-color: #1823ff;
|
|
2495
2587
|
}
|
|
2496
2588
|
|
|
2589
|
+
.focus-visible\:ring-2:focus-visible {
|
|
2590
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
2591
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
2592
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
.focus-visible\:ring-slate-400:focus-visible {
|
|
2596
|
+
--tw-ring-opacity: 1;
|
|
2597
|
+
--tw-ring-color: rgb(148 163 184 / var(--tw-ring-opacity));
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
.focus-visible\:ring-offset-1:focus-visible {
|
|
2601
|
+
--tw-ring-offset-width: 1px;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2497
2604
|
.disabled\:cursor-not-allowed:disabled {
|
|
2498
2605
|
cursor: not-allowed;
|
|
2499
2606
|
}
|
|
@@ -2522,6 +2629,10 @@ video {
|
|
|
2522
2629
|
opacity: 0.5;
|
|
2523
2630
|
}
|
|
2524
2631
|
|
|
2632
|
+
.group:hover .group-hover\:opacity-100 {
|
|
2633
|
+
opacity: 1;
|
|
2634
|
+
}
|
|
2635
|
+
|
|
2525
2636
|
@media (min-width: 640px) {
|
|
2526
2637
|
.sm\:-mx-6 {
|
|
2527
2638
|
margin-left: -1.5rem;
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
<div class="
|
|
2
|
-
<
|
|
1
|
+
<div class="tooltip w-full font-mono text-sm py-3 text-slate-800">
|
|
2
|
+
<div class="w-full">
|
|
3
|
+
<json-node
|
|
4
|
+
:node-key="null"
|
|
5
|
+
:value="value"
|
|
6
|
+
:level="0"
|
|
7
|
+
:is-last="true"
|
|
8
|
+
path="root"
|
|
9
|
+
:toggle-collapse="toggleCollapse"
|
|
10
|
+
:is-collapsed="isPathCollapsed"
|
|
11
|
+
:create-child-path="createChildPath"
|
|
12
|
+
:indent-size="indentSize"
|
|
13
|
+
:max-top-level-fields="maxTopLevelFields"
|
|
14
|
+
:top-level-expanded="topLevelExpanded"
|
|
15
|
+
:expand-top-level="expandTopLevel"
|
|
16
|
+
></json-node>
|
|
17
|
+
</div>
|
|
3
18
|
</div>
|
|
4
|
-
|
|
@@ -1,40 +1,365 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const api = require('../api');
|
|
4
3
|
const template = require('./list-json.html');
|
|
5
4
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const JsonNodeTemplate = `
|
|
6
|
+
<div>
|
|
7
|
+
<div class="flex items-baseline whitespace-pre" :style="indentStyle">
|
|
8
|
+
<button
|
|
9
|
+
v-if="showToggle"
|
|
10
|
+
type="button"
|
|
11
|
+
class="w-4 h-4 mr-1 inline-flex items-center justify-center leading-none text-gray-500 hover:text-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-slate-400 cursor-pointer"
|
|
12
|
+
@click.stop="handleToggle"
|
|
13
|
+
>
|
|
14
|
+
{{ isCollapsedNode ? '+' : '-' }}
|
|
15
|
+
</button>
|
|
16
|
+
<span v-else class="w-4 h-4 mr-1 inline-flex items-center justify-center invisible flex-shrink-0"></span>
|
|
17
|
+
<template v-if="hasKey">
|
|
18
|
+
<span class="text-blue-600">"{{ nodeKey }}"</span><span>: </span>
|
|
19
|
+
</template>
|
|
20
|
+
<template v-if="isComplex">
|
|
21
|
+
<template v-if="hasChildren">
|
|
22
|
+
<span>{{ openingBracket }}</span>
|
|
23
|
+
<span v-if="isCollapsedNode" class="mx-1">…</span>
|
|
24
|
+
<span v-if="isCollapsedNode">{{ closingBracket }}{{ comma }}</span>
|
|
25
|
+
</template>
|
|
26
|
+
<template v-else>
|
|
27
|
+
<span>{{ openingBracket }}{{ closingBracket }}{{ comma }}</span>
|
|
28
|
+
</template>
|
|
29
|
+
</template>
|
|
30
|
+
<template v-else>
|
|
31
|
+
<!--
|
|
32
|
+
If value is a string and overflows its container (i.e. goes over one line), show an ellipsis.
|
|
33
|
+
This is done via CSS ellipsis strategy.
|
|
34
|
+
-->
|
|
35
|
+
<span
|
|
36
|
+
:class="valueClasses"
|
|
37
|
+
:style="typeof value === 'string'
|
|
38
|
+
? {
|
|
39
|
+
display: 'inline-block',
|
|
40
|
+
maxWidth: '100%',
|
|
41
|
+
overflow: 'hidden',
|
|
42
|
+
textOverflow: 'ellipsis',
|
|
43
|
+
whiteSpace: 'nowrap',
|
|
44
|
+
verticalAlign: 'bottom'
|
|
45
|
+
}
|
|
46
|
+
: {}"
|
|
47
|
+
:title="typeof value === 'string' && $el && $el.scrollWidth > $el.clientWidth ? value : undefined"
|
|
48
|
+
>
|
|
49
|
+
{{ formattedValue }}{{ comma }}
|
|
50
|
+
</span>
|
|
51
|
+
</template>
|
|
52
|
+
</div>
|
|
53
|
+
<template v-if="isComplex && hasChildren && !isCollapsedNode">
|
|
54
|
+
<json-node
|
|
55
|
+
v-for="child in children"
|
|
56
|
+
:key="child.path"
|
|
57
|
+
:node-key="child.displayKey"
|
|
58
|
+
:value="child.value"
|
|
59
|
+
:level="level + 1"
|
|
60
|
+
:is-last="child.isLast"
|
|
61
|
+
:path="child.path"
|
|
62
|
+
:toggle-collapse="toggleCollapse"
|
|
63
|
+
:is-collapsed="isCollapsed"
|
|
64
|
+
:create-child-path="createChildPath"
|
|
65
|
+
:indent-size="indentSize"
|
|
66
|
+
:max-top-level-fields="maxTopLevelFields"
|
|
67
|
+
:top-level-expanded="topLevelExpanded"
|
|
68
|
+
:expand-top-level="expandTopLevel"
|
|
69
|
+
></json-node>
|
|
70
|
+
<div
|
|
71
|
+
v-if="hasHiddenRootChildren"
|
|
72
|
+
class="flex items-baseline whitespace-pre"
|
|
73
|
+
:style="indentStyle"
|
|
74
|
+
>
|
|
75
|
+
<span class="w-4 h-4 mr-1 inline-flex items-center justify-center invisible"></span>
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
class="text-xs inline-flex items-center gap-1 ml-4 text-slate-500 hover:text-slate-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:ring-slate-400"
|
|
79
|
+
:title="hiddenChildrenTooltip"
|
|
80
|
+
@click.stop="handleExpandTopLevel"
|
|
81
|
+
>
|
|
82
|
+
<span aria-hidden="true">{{hiddenChildrenLabel}}…</span>
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="flex items-baseline whitespace-pre" :style="indentStyle">
|
|
86
|
+
<span class="w-4 h-4 mr-1 inline-flex items-center justify-center invisible"></span>
|
|
87
|
+
<span>{{ closingBracket }}{{ comma }}</span>
|
|
88
|
+
</div>
|
|
89
|
+
</template>
|
|
90
|
+
</div>
|
|
91
|
+
`;
|
|
9
92
|
|
|
10
93
|
module.exports = app => app.component('list-json', {
|
|
11
94
|
template: template,
|
|
12
95
|
props: ['value'],
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
96
|
+
data() {
|
|
97
|
+
return {
|
|
98
|
+
collapsedMap: {},
|
|
99
|
+
indentSize: 16,
|
|
100
|
+
maxTopLevelFields: 15,
|
|
101
|
+
topLevelExpanded: false
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
watch: {
|
|
105
|
+
value: {
|
|
106
|
+
handler() {
|
|
107
|
+
this.resetCollapse();
|
|
108
|
+
}
|
|
16
109
|
}
|
|
17
110
|
},
|
|
111
|
+
created() {
|
|
112
|
+
this.resetCollapse();
|
|
113
|
+
},
|
|
18
114
|
methods: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
115
|
+
resetCollapse() {
|
|
116
|
+
this.collapsedMap = {};
|
|
117
|
+
this.topLevelExpanded = false;
|
|
118
|
+
},
|
|
119
|
+
toggleCollapse(path) {
|
|
120
|
+
const current = this.isPathCollapsed(path);
|
|
121
|
+
this.collapsedMap = Object.assign({}, this.collapsedMap, { [path]: !current });
|
|
122
|
+
},
|
|
123
|
+
isPathCollapsed(path) {
|
|
124
|
+
if (path === 'root') {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
if (Object.prototype.hasOwnProperty.call(this.collapsedMap, path)) {
|
|
128
|
+
return this.collapsedMap[path];
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
},
|
|
132
|
+
createChildPath(parentPath, childKey, isArray) {
|
|
133
|
+
if (parentPath == null || parentPath === '') {
|
|
134
|
+
return isArray ? `[${childKey}]` : `${childKey}`;
|
|
135
|
+
}
|
|
136
|
+
if (parentPath === 'root') {
|
|
137
|
+
return isArray ? `root[${childKey}]` : `root.${childKey}`;
|
|
138
|
+
}
|
|
139
|
+
if (isArray) {
|
|
140
|
+
return `${parentPath}[${childKey}]`;
|
|
141
|
+
}
|
|
142
|
+
return `${parentPath}.${childKey}`;
|
|
143
|
+
},
|
|
144
|
+
expandTopLevel() {
|
|
145
|
+
this.topLevelExpanded = true;
|
|
35
146
|
}
|
|
36
147
|
},
|
|
37
|
-
|
|
38
|
-
|
|
148
|
+
components: {
|
|
149
|
+
JsonNode: {
|
|
150
|
+
name: 'JsonNode',
|
|
151
|
+
template: JsonNodeTemplate,
|
|
152
|
+
props: {
|
|
153
|
+
nodeKey: {
|
|
154
|
+
type: [String, Number],
|
|
155
|
+
default: null
|
|
156
|
+
},
|
|
157
|
+
value: {
|
|
158
|
+
required: true
|
|
159
|
+
},
|
|
160
|
+
level: {
|
|
161
|
+
type: Number,
|
|
162
|
+
required: true
|
|
163
|
+
},
|
|
164
|
+
isLast: {
|
|
165
|
+
type: Boolean,
|
|
166
|
+
default: false
|
|
167
|
+
},
|
|
168
|
+
path: {
|
|
169
|
+
type: String,
|
|
170
|
+
required: true
|
|
171
|
+
},
|
|
172
|
+
toggleCollapse: {
|
|
173
|
+
type: Function,
|
|
174
|
+
required: true
|
|
175
|
+
},
|
|
176
|
+
isCollapsed: {
|
|
177
|
+
type: Function,
|
|
178
|
+
required: true
|
|
179
|
+
},
|
|
180
|
+
createChildPath: {
|
|
181
|
+
type: Function,
|
|
182
|
+
required: true
|
|
183
|
+
},
|
|
184
|
+
indentSize: {
|
|
185
|
+
type: Number,
|
|
186
|
+
required: true
|
|
187
|
+
},
|
|
188
|
+
maxTopLevelFields: {
|
|
189
|
+
type: Number,
|
|
190
|
+
default: null
|
|
191
|
+
},
|
|
192
|
+
topLevelExpanded: {
|
|
193
|
+
type: Boolean,
|
|
194
|
+
default: false
|
|
195
|
+
},
|
|
196
|
+
expandTopLevel: {
|
|
197
|
+
type: Function,
|
|
198
|
+
default: null
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
computed: {
|
|
202
|
+
hasKey() {
|
|
203
|
+
return this.nodeKey !== null && this.nodeKey !== undefined;
|
|
204
|
+
},
|
|
205
|
+
isRoot() {
|
|
206
|
+
return this.path === 'root';
|
|
207
|
+
},
|
|
208
|
+
isArray() {
|
|
209
|
+
return Array.isArray(this.value);
|
|
210
|
+
},
|
|
211
|
+
isObject() {
|
|
212
|
+
if (this.value === null || this.isArray) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
return Object.prototype.toString.call(this.value) === '[object Object]';
|
|
216
|
+
},
|
|
217
|
+
isComplex() {
|
|
218
|
+
return this.isArray || this.isObject;
|
|
219
|
+
},
|
|
220
|
+
children() {
|
|
221
|
+
if (!this.isComplex) {
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
if (this.isArray) {
|
|
225
|
+
return this.value.map((childValue, index) => ({
|
|
226
|
+
displayKey: null,
|
|
227
|
+
value: childValue,
|
|
228
|
+
isLast: index === this.value.length - 1,
|
|
229
|
+
path: this.createChildPath(this.path, index, true)
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
const keys = Object.keys(this.value);
|
|
233
|
+
const visibleKeys = this.visibleObjectKeys(keys);
|
|
234
|
+
const hasHidden = this.hasHiddenRootChildren;
|
|
235
|
+
return visibleKeys.map((key, index) => ({
|
|
236
|
+
displayKey: key,
|
|
237
|
+
value: this.value[key],
|
|
238
|
+
isLast: !hasHidden && index === visibleKeys.length - 1,
|
|
239
|
+
path: this.createChildPath(this.path, key, false)
|
|
240
|
+
}));
|
|
241
|
+
},
|
|
242
|
+
hasChildren() {
|
|
243
|
+
return this.children.length > 0;
|
|
244
|
+
},
|
|
245
|
+
totalObjectChildCount() {
|
|
246
|
+
if (!this.isObject) {
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
return Object.keys(this.value).length;
|
|
250
|
+
},
|
|
251
|
+
hasHiddenRootChildren() {
|
|
252
|
+
if (!this.isRoot || !this.isObject) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
if (this.topLevelExpanded) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
if (typeof this.maxTopLevelFields !== 'number') {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
return this.totalObjectChildCount > this.maxTopLevelFields;
|
|
262
|
+
},
|
|
263
|
+
hiddenRootChildrenCount() {
|
|
264
|
+
if (!this.hasHiddenRootChildren) {
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
return this.totalObjectChildCount - this.maxTopLevelFields;
|
|
268
|
+
},
|
|
269
|
+
showToggle() {
|
|
270
|
+
return this.hasChildren && !this.isRoot;
|
|
271
|
+
},
|
|
272
|
+
openingBracket() {
|
|
273
|
+
return this.isArray ? '[' : '{';
|
|
274
|
+
},
|
|
275
|
+
closingBracket() {
|
|
276
|
+
return this.isArray ? ']' : '}';
|
|
277
|
+
},
|
|
278
|
+
isCollapsedNode() {
|
|
279
|
+
return this.isCollapsed(this.path);
|
|
280
|
+
},
|
|
281
|
+
formattedValue() {
|
|
282
|
+
if (typeof this.value === 'bigint') {
|
|
283
|
+
return `${this.value.toString()}n`;
|
|
284
|
+
}
|
|
285
|
+
const stringified = JSON.stringify(this.value);
|
|
286
|
+
if (stringified === undefined) {
|
|
287
|
+
if (typeof this.value === 'symbol') {
|
|
288
|
+
return this.value.toString();
|
|
289
|
+
}
|
|
290
|
+
return String(this.value);
|
|
291
|
+
}
|
|
292
|
+
return stringified;
|
|
293
|
+
},
|
|
294
|
+
valueClasses() {
|
|
295
|
+
const classes = ['text-slate-700'];
|
|
296
|
+
if (this.value === null) {
|
|
297
|
+
classes.push('text-gray-500', 'italic');
|
|
298
|
+
return classes;
|
|
299
|
+
}
|
|
300
|
+
const type = typeof this.value;
|
|
301
|
+
if (type === 'string') {
|
|
302
|
+
classes.push('text-emerald-600');
|
|
303
|
+
return classes;
|
|
304
|
+
}
|
|
305
|
+
if (type === 'number' || type === 'bigint') {
|
|
306
|
+
classes.push('text-amber-600');
|
|
307
|
+
return classes;
|
|
308
|
+
}
|
|
309
|
+
if (type === 'boolean') {
|
|
310
|
+
classes.push('text-violet-600');
|
|
311
|
+
return classes;
|
|
312
|
+
}
|
|
313
|
+
if (type === 'undefined') {
|
|
314
|
+
classes.push('text-gray-500');
|
|
315
|
+
return classes;
|
|
316
|
+
}
|
|
317
|
+
return classes;
|
|
318
|
+
},
|
|
319
|
+
comma() {
|
|
320
|
+
return this.isLast ? '' : ',';
|
|
321
|
+
},
|
|
322
|
+
indentStyle() {
|
|
323
|
+
return {
|
|
324
|
+
paddingLeft: `${this.level * this.indentSize}px`
|
|
325
|
+
};
|
|
326
|
+
},
|
|
327
|
+
hiddenChildrenLabel() {
|
|
328
|
+
if (!this.hasHiddenRootChildren) {
|
|
329
|
+
return '';
|
|
330
|
+
}
|
|
331
|
+
const count = this.hiddenRootChildrenCount;
|
|
332
|
+
const suffix = count === 1 ? 'field' : 'fields';
|
|
333
|
+
return `${count} more ${suffix}`;
|
|
334
|
+
},
|
|
335
|
+
hiddenChildrenTooltip() {
|
|
336
|
+
return this.hiddenChildrenLabel;
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
methods: {
|
|
340
|
+
visibleObjectKeys(keys) {
|
|
341
|
+
if (!this.isRoot || this.topLevelExpanded) {
|
|
342
|
+
return keys;
|
|
343
|
+
}
|
|
344
|
+
if (typeof this.maxTopLevelFields !== 'number') {
|
|
345
|
+
return keys;
|
|
346
|
+
}
|
|
347
|
+
if (keys.length <= this.maxTopLevelFields) {
|
|
348
|
+
return keys;
|
|
349
|
+
}
|
|
350
|
+
return keys.slice(0, this.maxTopLevelFields);
|
|
351
|
+
},
|
|
352
|
+
handleToggle() {
|
|
353
|
+
if (!this.isRoot) {
|
|
354
|
+
this.toggleCollapse(this.path);
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
handleExpandTopLevel() {
|
|
358
|
+
if (this.isRoot && typeof this.expandTopLevel === 'function') {
|
|
359
|
+
this.expandTopLevel();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
39
364
|
}
|
|
40
365
|
});
|
|
@@ -98,14 +98,14 @@
|
|
|
98
98
|
</button>
|
|
99
99
|
<span class="isolate inline-flex rounded-md shadow-sm">
|
|
100
100
|
<button
|
|
101
|
-
@click="
|
|
101
|
+
@click="setOutputType('table')"
|
|
102
102
|
type="button"
|
|
103
103
|
class="relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
|
|
104
104
|
:class="outputType === 'table' ? 'bg-gray-200' : 'bg-white'">
|
|
105
105
|
<img class="h-5 w-5" src="images/table.svg">
|
|
106
106
|
</button>
|
|
107
107
|
<button
|
|
108
|
-
@click="
|
|
108
|
+
@click="setOutputType('json')"
|
|
109
109
|
type="button"
|
|
110
110
|
class="relative -ml-px inline-flex items-center rounded-none rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
|
|
111
111
|
:class="outputType === 'json' ? 'bg-gray-200' : 'bg-white'">
|
|
@@ -139,8 +139,23 @@
|
|
|
139
139
|
</tr>
|
|
140
140
|
</tbody>
|
|
141
141
|
</table>
|
|
142
|
-
<div v-if="outputType === 'json'">
|
|
143
|
-
<div
|
|
142
|
+
<div v-if="outputType === 'json'" class="flex flex-col space-y-6">
|
|
143
|
+
<div
|
|
144
|
+
v-for="document in documents"
|
|
145
|
+
:key="document._id"
|
|
146
|
+
@click="handleDocumentContainerClick(document, $event)"
|
|
147
|
+
:class="[
|
|
148
|
+
'group relative transition-colors',
|
|
149
|
+
selectedDocuments.some(x => x._id.toString() === document._id.toString()) ? 'bg-blue-200' : 'hover:bg-slate-100'
|
|
150
|
+
]"
|
|
151
|
+
>
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
class="absolute top-2 right-2 z-10 inline-flex items-center rounded bg-ultramarine-600 px-2 py-1 text-xs font-semibold text-white shadow-sm transition-opacity duration-150 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600"
|
|
155
|
+
@click.stop="openDocument(document)"
|
|
156
|
+
>
|
|
157
|
+
Open this Document
|
|
158
|
+
</button>
|
|
144
159
|
<list-json :value="filterDocument(document)">
|
|
145
160
|
</list-json>
|
|
146
161
|
</div>
|