@viamrobotics/test-widgets 0.10.1 → 0.11.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.
- package/dist/components/audio-properties.svelte +3 -3
- package/dist/components/connection-status.svelte +1 -3
- package/dist/components/error.svelte +15 -10
- package/dist/components/queries.svelte +9 -4
- package/dist/components/readings-list.svelte +30 -30
- package/dist/components/refetch-controller.svelte +2 -2
- package/dist/components/widgets/audio-input/audio-input.svelte +85 -83
- package/dist/components/widgets/audio-output/audio-output.svelte +93 -91
- package/dist/components/widgets/board/pin-selector.svelte +1 -1
- package/dist/components/widgets/board/read-write-pins.svelte +1 -1
- package/dist/components/widgets/camera/camera.svelte +6 -5
- package/dist/components/widgets/camera/live-or-polling-video.svelte +2 -2
- package/dist/components/widgets/discovery/resources-list.svelte +35 -33
- package/dist/components/widgets/do-command/do-command.svelte +44 -41
- package/dist/components/widgets/gripper/gripper.svelte +41 -39
- package/dist/components/widgets/pcd/inputs.svelte +1 -1
- package/dist/components/widgets/pcd/pcd-widget.svelte +19 -17
- package/dist/components/widgets/servo/servo.svelte +69 -64
- package/dist/components/widgets/vision-service/image.svelte +10 -3
- package/dist/components/widgets/vision-service/object-point-clouds.svelte +1 -1
- package/dist/components/widgets/vision-service/vision-service.svelte +5 -5
- package/package.json +2 -2
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
<dl class="font-roboto-mono flex flex-col gap-y-2 text-sm">
|
|
12
12
|
<div class="flex flex-col gap-0.5">
|
|
13
|
-
<dt class="text-default
|
|
13
|
+
<dt class="text-default pr-2 font-medium">Supported Codecs</dt>
|
|
14
14
|
<dd class="text-subtle-1">
|
|
15
15
|
{supportedCodecs.length > 0 ? supportedCodecs.join(', ') : 'None'}
|
|
16
16
|
</dd>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="flex flex-col gap-0.5">
|
|
19
|
-
<dt class="text-default
|
|
19
|
+
<dt class="text-default pr-2 font-medium">Sample Rate</dt>
|
|
20
20
|
<dd class="text-subtle-1">{sampleRateHz} Hz</dd>
|
|
21
21
|
</div>
|
|
22
22
|
<div class="flex flex-col gap-0.5">
|
|
23
|
-
<dt class="text-default
|
|
23
|
+
<dt class="text-default pr-2 font-medium">Channels</dt>
|
|
24
24
|
<dd class="text-subtle-1">{numChannels}</dd>
|
|
25
25
|
</div>
|
|
26
26
|
</dl>
|
|
@@ -39,18 +39,23 @@
|
|
|
39
39
|
<div class="flex items-center justify-between gap-1">
|
|
40
40
|
<p
|
|
41
41
|
{id}
|
|
42
|
-
class={twMerge(
|
|
42
|
+
class={twMerge(
|
|
43
|
+
'font-roboto-mono text-danger-dark min-w-0 overflow-auto text-xs wrap-break-word',
|
|
44
|
+
className
|
|
45
|
+
)}
|
|
43
46
|
>
|
|
44
47
|
{errorText}
|
|
45
48
|
</p>
|
|
46
|
-
<
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
<div class="shrink-0">
|
|
50
|
+
<Tooltip let:tooltipID>
|
|
51
|
+
<IconButton
|
|
52
|
+
aria-describedby={tooltipID}
|
|
53
|
+
icon={showCopySuccess ? 'check' : 'content-copy'}
|
|
54
|
+
label="Copy error"
|
|
55
|
+
on:click={copyErrorToClipboard}
|
|
56
|
+
/>
|
|
57
|
+
<div slot="description">Copy error</div>
|
|
58
|
+
</Tooltip>
|
|
59
|
+
</div>
|
|
55
60
|
</div>
|
|
56
61
|
{/if}
|
|
@@ -29,13 +29,18 @@
|
|
|
29
29
|
let errors = $state.raw<Error[]>([])
|
|
30
30
|
let data = $state.raw<unknown[]>([])
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
|
|
32
|
+
const errorKey = (error: Error) => `${error.name}\0${error.message}`
|
|
33
|
+
const serializeErrors = (errs: Error[]) => errs.map((element) => errorKey(element)).join('\0\0')
|
|
34
|
+
const dedupeErrors = (errs: Error[]) => [
|
|
35
|
+
...new Map(errs.map((error) => [errorKey(error), error])).values(),
|
|
36
|
+
]
|
|
34
37
|
|
|
35
38
|
// Errors are null during loading, so keep the latest errors during polling.
|
|
36
39
|
// Only update errors if the content has changed to avoid re-rendering identical errors.
|
|
37
40
|
$effect.pre(() => {
|
|
38
|
-
const nextErrors =
|
|
41
|
+
const nextErrors = dedupeErrors(
|
|
42
|
+
queries.map((query) => query.error).filter((error) => error !== null)
|
|
43
|
+
)
|
|
39
44
|
if (nextErrors.length > 0) {
|
|
40
45
|
if (serializeErrors(nextErrors) !== serializeErrors(errors)) {
|
|
41
46
|
errors = nextErrors
|
|
@@ -61,7 +66,7 @@
|
|
|
61
66
|
{contentRect}
|
|
62
67
|
cx={contentCx}
|
|
63
68
|
>
|
|
64
|
-
{#each errors as error (
|
|
69
|
+
{#each errors as error (errorKey(error))}
|
|
65
70
|
<ErrorDisplay lastError={error} />
|
|
66
71
|
{/each}
|
|
67
72
|
</ContentRect>
|
|
@@ -39,35 +39,35 @@
|
|
|
39
39
|
<div slot="description">Copy JSON</div>
|
|
40
40
|
</Tooltip>
|
|
41
41
|
</div>
|
|
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
|
-
</
|
|
42
|
+
<div class="@container">
|
|
43
|
+
<dl class="font-roboto-mono flex flex-col gap-y-2">
|
|
44
|
+
{#each sortedData as [key, value] (key)}
|
|
45
|
+
{@const valueString = JSON.stringify(value, null, 2)}
|
|
46
|
+
<div class="flex flex-col gap-y-1 @lg:flex-row @lg:gap-y-0">
|
|
47
|
+
<dt
|
|
48
|
+
class="text-default truncate pr-2 font-medium @lg:w-50 @lg:min-w-50"
|
|
49
|
+
title={key}
|
|
50
|
+
>
|
|
51
|
+
{key}
|
|
52
|
+
</dt>
|
|
53
|
+
<dd class="text-subtle-1 min-w-0 grow wrap-break-word">
|
|
54
|
+
{#if value !== null && typeof value === 'object'}
|
|
55
|
+
<div class="border-light bg-extralight border px-3 py-2">
|
|
56
|
+
<pre class="whitespace-pre-wrap"><code>{valueString}</code></pre>
|
|
57
|
+
</div>
|
|
58
|
+
{:else if typeof value === 'string' && value.startsWith('data:image/')}
|
|
59
|
+
<img
|
|
60
|
+
class="max-h-80 max-w-full"
|
|
61
|
+
src={value}
|
|
62
|
+
alt={key}
|
|
63
|
+
/>
|
|
64
|
+
{:else}
|
|
65
|
+
{truncate(valueString, { length: 300 })}
|
|
66
|
+
{/if}
|
|
67
|
+
</dd>
|
|
68
|
+
</div>
|
|
69
|
+
{/each}
|
|
70
|
+
</dl>
|
|
71
|
+
</div>
|
|
72
72
|
</div>
|
|
73
73
|
{/if}
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
})
|
|
92
92
|
</script>
|
|
93
93
|
|
|
94
|
-
<div class="text-default flex flex-
|
|
95
|
-
<div class="w-50">
|
|
94
|
+
<div class="text-default flex flex-wrap gap-2 text-xs">
|
|
95
|
+
<div class="w-50 max-w-full">
|
|
96
96
|
<Select on:change={onChange}>
|
|
97
97
|
{#each refetchOptions as option (option)}
|
|
98
98
|
<option selected={selectedOption === option}>{option}</option>
|
|
@@ -58,97 +58,99 @@
|
|
|
58
58
|
/>
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
|
-
<div class="
|
|
62
|
-
<div class="flex
|
|
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
|
-
|
|
61
|
+
<div class="@container">
|
|
62
|
+
<div class="flex flex-col divide-y @2xl:flex-row @2xl:divide-x @2xl:divide-y-0">
|
|
63
|
+
<div class="flex w-full flex-col divide-y">
|
|
64
|
+
<MutationSection
|
|
65
|
+
title="GetAudio"
|
|
66
|
+
api="rdk:component:audio_input"
|
|
67
|
+
description="Capture audio from the device"
|
|
68
|
+
lastError={capture.error}
|
|
69
|
+
>
|
|
70
|
+
<div class="flex flex-col gap-2">
|
|
71
|
+
<Label cx="gap-1 text-xs">
|
|
72
|
+
Codec
|
|
73
|
+
<Select
|
|
74
|
+
slot="input"
|
|
75
|
+
value={selectedCodec}
|
|
76
|
+
on:change={(e) => {
|
|
77
|
+
captureCodec = (e.target as HTMLSelectElement).value
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
{#each availableCodecs as codec (codec)}
|
|
81
|
+
<option value={codec}>{codec}</option>
|
|
82
|
+
{/each}
|
|
83
|
+
</Select>
|
|
84
|
+
</Label>
|
|
85
|
+
<Label cx="gap-1 text-xs">
|
|
86
|
+
Duration (seconds, 0 = stream until stopped)
|
|
87
|
+
<NumericInput
|
|
88
|
+
slot="input"
|
|
89
|
+
value={captureDuration}
|
|
90
|
+
on:change={(e) => {
|
|
91
|
+
captureDuration = numberValueFromEvent(e) ?? 3
|
|
92
|
+
}}
|
|
93
|
+
/>
|
|
94
|
+
</Label>
|
|
95
|
+
</div>
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<p class="font-roboto-mono text-subtle-1 text-xs">
|
|
99
|
-
{(capture.totalBytes / 1024).toFixed(1)} kB captured
|
|
100
|
-
</p>
|
|
101
|
-
<Button
|
|
102
|
-
icon="stop-circle-outline"
|
|
103
|
-
onclick={capture.stop}
|
|
104
|
-
>
|
|
105
|
-
Stop
|
|
106
|
-
</Button>
|
|
107
|
-
{:else}
|
|
108
|
-
{#if capture.downloadUrl}
|
|
97
|
+
<div class="mt-auto flex flex-col items-start gap-2">
|
|
98
|
+
{#if capture.status === 'recording'}
|
|
109
99
|
<p class="font-roboto-mono text-subtle-1 text-xs">
|
|
110
100
|
{(capture.totalBytes / 1024).toFixed(1)} kB captured
|
|
111
101
|
</p>
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
<Button
|
|
103
|
+
icon="stop-circle-outline"
|
|
104
|
+
onclick={capture.stop}
|
|
105
|
+
>
|
|
106
|
+
Stop
|
|
107
|
+
</Button>
|
|
108
|
+
{:else}
|
|
109
|
+
{#if capture.downloadUrl}
|
|
110
|
+
<p class="font-roboto-mono text-subtle-1 text-xs">
|
|
111
|
+
{(capture.totalBytes / 1024).toFixed(1)} kB captured
|
|
112
|
+
</p>
|
|
113
|
+
<a
|
|
114
|
+
href={capture.downloadUrl}
|
|
115
|
+
download="audio-capture.{selectedCodec}"
|
|
116
|
+
rel="external"
|
|
117
|
+
>
|
|
118
|
+
<Button icon="download">Download</Button>
|
|
119
|
+
</a>
|
|
120
|
+
{/if}
|
|
121
|
+
<Button
|
|
122
|
+
icon="play-circle-outline"
|
|
123
|
+
onclick={() => capture.start(selectedCodec, captureDuration)}
|
|
124
|
+
disabled={!client.current}
|
|
116
125
|
>
|
|
117
|
-
|
|
118
|
-
</
|
|
126
|
+
{capture.status === 'done' ? 'Capture Again' : 'Start Capture'}
|
|
127
|
+
</Button>
|
|
119
128
|
{/if}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
disabled={!client.current}
|
|
124
|
-
>
|
|
125
|
-
{capture.status === 'done' ? 'Capture Again' : 'Start Capture'}
|
|
126
|
-
</Button>
|
|
127
|
-
{/if}
|
|
128
|
-
</div>
|
|
129
|
-
</MutationSection>
|
|
130
|
-
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</MutationSection>
|
|
131
|
+
</div>
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
>
|
|
139
|
-
<Query
|
|
140
|
-
query={propertiesQuery}
|
|
141
|
-
contentCx="h-6"
|
|
133
|
+
<div class="flex w-full flex-col divide-y @2xl:ml-auto @2xl:max-w-1/2 @4xl:max-w-1/3">
|
|
134
|
+
<ApiSection
|
|
135
|
+
title="GetProperties"
|
|
136
|
+
api="rdk:component:audio_input"
|
|
137
|
+
description="Audio input properties"
|
|
138
|
+
class="relative"
|
|
142
139
|
>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
140
|
+
<Query
|
|
141
|
+
query={propertiesQuery}
|
|
142
|
+
contentCx="h-6"
|
|
143
|
+
>
|
|
144
|
+
{#if propertiesQuery.data !== undefined}
|
|
145
|
+
<Properties
|
|
146
|
+
supportedCodecs={propertiesQuery.data.supportedCodecs}
|
|
147
|
+
sampleRateHz={propertiesQuery.data.sampleRateHz}
|
|
148
|
+
numChannels={propertiesQuery.data.numChannels}
|
|
149
|
+
/>
|
|
150
|
+
{/if}
|
|
151
|
+
</Query>
|
|
152
|
+
</ApiSection>
|
|
153
|
+
</div>
|
|
152
154
|
</div>
|
|
153
155
|
</div>
|
|
154
156
|
{/snippet}
|
|
@@ -103,99 +103,101 @@
|
|
|
103
103
|
/>
|
|
104
104
|
</div>
|
|
105
105
|
|
|
106
|
-
<div class="
|
|
107
|
-
<div class="flex
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
106
|
+
<div class="@container">
|
|
107
|
+
<div class="flex flex-col divide-y @2xl:flex-row @2xl:divide-x @2xl:divide-y-0">
|
|
108
|
+
<div class="flex w-full flex-col divide-y">
|
|
109
|
+
<MutationSection
|
|
110
|
+
title="Play"
|
|
111
|
+
api="rdk:component:audio_output"
|
|
112
|
+
description="Send audio data to the device"
|
|
113
|
+
lastError={playContext.error}
|
|
114
|
+
>
|
|
115
|
+
<div class="flex flex-col gap-2">
|
|
116
|
+
<Label cx="gap-1 text-xs">
|
|
117
|
+
Audio file
|
|
118
|
+
<input
|
|
119
|
+
slot="input"
|
|
120
|
+
type="file"
|
|
121
|
+
accept={availableCodecs.map((c) => `.${c}`).join(',')}
|
|
122
|
+
class="text-xs"
|
|
123
|
+
onchange={handleFileChange}
|
|
124
|
+
/>
|
|
125
|
+
</Label>
|
|
126
|
+
{#if fileInputError}
|
|
127
|
+
<p class="text-xs text-red-500">{fileInputError}</p>
|
|
128
|
+
{/if}
|
|
129
|
+
{#if selectedFile}
|
|
130
|
+
<p class="font-roboto-mono text-subtle-1 text-xs">{selectedFile.name}</p>
|
|
131
|
+
{/if}
|
|
132
|
+
<Label cx="gap-1 text-xs">
|
|
133
|
+
Codec
|
|
134
|
+
<Select
|
|
135
|
+
slot="input"
|
|
136
|
+
value={selectedCodec}
|
|
137
|
+
on:change={(e) => {
|
|
138
|
+
playCodec = (e.target as HTMLSelectElement).value
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
{#each availableCodecs as codec (codec)}
|
|
142
|
+
<option value={codec}>{codec}</option>
|
|
143
|
+
{/each}
|
|
144
|
+
</Select>
|
|
145
|
+
</Label>
|
|
146
|
+
<Label cx="gap-1 text-xs">
|
|
147
|
+
Sample rate (Hz)
|
|
148
|
+
<NumericInput
|
|
149
|
+
slot="input"
|
|
150
|
+
value={selectedSampleRateHz}
|
|
151
|
+
on:change={(e) => {
|
|
152
|
+
playSampleRateHz = numberValueFromEvent(e) ?? null
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
</Label>
|
|
156
|
+
<Label cx="gap-1 text-xs">
|
|
157
|
+
Channels
|
|
158
|
+
<NumericInput
|
|
159
|
+
slot="input"
|
|
160
|
+
value={selectedNumChannels}
|
|
161
|
+
on:change={(e) => {
|
|
162
|
+
playNumChannels = numberValueFromEvent(e) ?? null
|
|
163
|
+
}}
|
|
164
|
+
/>
|
|
165
|
+
</Label>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<div class="mt-auto">
|
|
169
|
+
<Button
|
|
170
|
+
icon="play-circle-outline"
|
|
171
|
+
onclick={play}
|
|
172
|
+
disabled={!client.current || playContext.status === 'playing'}
|
|
139
173
|
>
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}}
|
|
153
|
-
/>
|
|
154
|
-
</Label>
|
|
155
|
-
<Label cx="gap-1 text-xs">
|
|
156
|
-
Channels
|
|
157
|
-
<NumericInput
|
|
158
|
-
slot="input"
|
|
159
|
-
value={selectedNumChannels}
|
|
160
|
-
on:change={(e) => {
|
|
161
|
-
playNumChannels = numberValueFromEvent(e) ?? null
|
|
162
|
-
}}
|
|
163
|
-
/>
|
|
164
|
-
</Label>
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
<div class="mt-auto">
|
|
168
|
-
<Button
|
|
169
|
-
icon="play-circle-outline"
|
|
170
|
-
onclick={play}
|
|
171
|
-
disabled={!client.current || playContext.status === 'playing'}
|
|
172
|
-
>
|
|
173
|
-
{playButtonLabel}
|
|
174
|
-
</Button>
|
|
175
|
-
</div>
|
|
176
|
-
</MutationSection>
|
|
177
|
-
</div>
|
|
178
|
-
|
|
179
|
-
<div class="ml-auto flex w-full max-w-1/2 flex-col divide-y sm:max-w-1/3">
|
|
180
|
-
<ApiSection
|
|
181
|
-
title="GetProperties"
|
|
182
|
-
api="rdk:component:audio_output"
|
|
183
|
-
description="Audio output properties"
|
|
184
|
-
class="relative"
|
|
185
|
-
>
|
|
186
|
-
<Query
|
|
187
|
-
query={propertiesQuery}
|
|
188
|
-
contentCx="h-6"
|
|
174
|
+
{playButtonLabel}
|
|
175
|
+
</Button>
|
|
176
|
+
</div>
|
|
177
|
+
</MutationSection>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div class="flex w-full flex-col divide-y @2xl:ml-auto @2xl:max-w-1/2 @4xl:max-w-1/3">
|
|
181
|
+
<ApiSection
|
|
182
|
+
title="GetProperties"
|
|
183
|
+
api="rdk:component:audio_output"
|
|
184
|
+
description="Audio output properties"
|
|
185
|
+
class="relative"
|
|
189
186
|
>
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
187
|
+
<Query
|
|
188
|
+
query={propertiesQuery}
|
|
189
|
+
contentCx="h-6"
|
|
190
|
+
>
|
|
191
|
+
{#if propertiesQuery.data !== undefined}
|
|
192
|
+
<Properties
|
|
193
|
+
supportedCodecs={propertiesQuery.data.supportedCodecs}
|
|
194
|
+
sampleRateHz={propertiesQuery.data.sampleRateHz}
|
|
195
|
+
numChannels={propertiesQuery.data.numChannels}
|
|
196
|
+
/>
|
|
197
|
+
{/if}
|
|
198
|
+
</Query>
|
|
199
|
+
</ApiSection>
|
|
200
|
+
</div>
|
|
199
201
|
</div>
|
|
200
202
|
</div>
|
|
201
203
|
{/snippet}
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
</Label>
|
|
182
182
|
</div>
|
|
183
183
|
{#if isPlaying}
|
|
184
|
-
<div class="flex gap-4 p-4 pb-3">
|
|
184
|
+
<div class="flex flex-wrap gap-4 p-4 pb-3">
|
|
185
185
|
<RefetchController
|
|
186
186
|
{refetchInterval}
|
|
187
187
|
allowLive
|
|
@@ -216,8 +216,8 @@
|
|
|
216
216
|
{/if}
|
|
217
217
|
</div>
|
|
218
218
|
{/if}
|
|
219
|
-
<div class="flex h-full w-full gap-4 p-4">
|
|
220
|
-
<div class="grow">
|
|
219
|
+
<div class="flex h-full w-full flex-wrap gap-4 p-4">
|
|
220
|
+
<div class="min-w-0 grow basis-80">
|
|
221
221
|
{#if isPlaying}
|
|
222
222
|
{#if displayAs360}
|
|
223
223
|
{#if isLive}
|
|
@@ -242,6 +242,7 @@
|
|
|
242
242
|
{partID}
|
|
243
243
|
{resourceName}
|
|
244
244
|
showResolutionOptions
|
|
245
|
+
videoClass="h-auto max-w-full"
|
|
245
246
|
{isLive}
|
|
246
247
|
data={imageQuery.data}
|
|
247
248
|
error={imageQuery.error}
|
|
@@ -252,7 +253,7 @@
|
|
|
252
253
|
/>
|
|
253
254
|
{/if}
|
|
254
255
|
{:else}
|
|
255
|
-
<div class="bg-medium flex h-64 w-80 items-center justify-center">
|
|
256
|
+
<div class="bg-medium flex h-64 w-full max-w-80 items-center justify-center">
|
|
256
257
|
<Button
|
|
257
258
|
icon="play-circle-outline"
|
|
258
259
|
variant="dark"
|
|
@@ -266,7 +267,7 @@
|
|
|
266
267
|
{/if}
|
|
267
268
|
</div>
|
|
268
269
|
{#if isPlaying}
|
|
269
|
-
<div class="flex flex-col items-start gap-2">
|
|
270
|
+
<div class="flex shrink-0 flex-col items-start gap-2">
|
|
270
271
|
<ExportScreenshot
|
|
271
272
|
name={client.current?.name ?? ''}
|
|
272
273
|
sourceName={selectedSource}
|
|
@@ -339,7 +339,7 @@
|
|
|
339
339
|
{#if lastError}
|
|
340
340
|
<ContentRect
|
|
341
341
|
{contentRect}
|
|
342
|
-
cx="bg-medium/50 absolute flex h-64 w-80 items-center justify-center"
|
|
342
|
+
cx="bg-medium/50 absolute flex h-64 w-80 max-w-full items-center justify-center"
|
|
343
343
|
>
|
|
344
344
|
<ErrorDisplay
|
|
345
345
|
class="pb-4"
|
|
@@ -349,7 +349,7 @@
|
|
|
349
349
|
{:else if isLive ? isStreamLoading : isLoading}
|
|
350
350
|
<ContentRect
|
|
351
351
|
{contentRect}
|
|
352
|
-
cx="absolute h-64 w-80"
|
|
352
|
+
cx="absolute h-64 w-80 max-w-full"
|
|
353
353
|
>
|
|
354
354
|
<Progress />
|
|
355
355
|
</ContentRect>
|
|
@@ -66,44 +66,46 @@
|
|
|
66
66
|
<div slot="description">Copy JSON</div>
|
|
67
67
|
</Tooltip>
|
|
68
68
|
</div>
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<div class="flex flex-
|
|
75
|
-
<
|
|
76
|
-
<
|
|
77
|
-
|
|
69
|
+
<div class="@container">
|
|
70
|
+
<dl class="font-roboto-mono flex flex-col gap-y-4">
|
|
71
|
+
{#each sortedData as value (value)}
|
|
72
|
+
{@const valueString = JSON.stringify(value, null, 2)}
|
|
73
|
+
{@const preview = previews[value.name]}
|
|
74
|
+
<div class="flex flex-col gap-y-2">
|
|
75
|
+
<div class="flex flex-col gap-y-2 @lg:flex-row @lg:gap-y-0">
|
|
76
|
+
<dt class="text-default flex flex-col gap-2 pr-2 font-medium @lg:w-50 @lg:min-w-50">
|
|
77
|
+
<span class="truncate">{value.name}</span>
|
|
78
|
+
{#if onAddComponent}
|
|
79
|
+
<Button
|
|
80
|
+
class="w-fit"
|
|
81
|
+
icon="plus"
|
|
82
|
+
onclick={() => onAddComponent(parseComponentConfig(value))}
|
|
83
|
+
>
|
|
84
|
+
Add component
|
|
85
|
+
</Button>
|
|
86
|
+
{/if}
|
|
78
87
|
<Button
|
|
79
88
|
class="w-fit"
|
|
80
|
-
icon="
|
|
81
|
-
onclick={() =>
|
|
89
|
+
icon="content-copy"
|
|
90
|
+
onclick={async () => copyAttributes(value)}
|
|
82
91
|
>
|
|
83
|
-
|
|
92
|
+
Copy attributes
|
|
84
93
|
</Button>
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
class="
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<div class="border-light bg-extralight relative min-w-50 border px-3 py-2">
|
|
96
|
-
<pre class="whitespace-pre-wrap"><code>{valueString}</code></pre>
|
|
94
|
+
</dt>
|
|
95
|
+
<dd class="text-subtle-1 min-w-0 grow">
|
|
96
|
+
<div class="border-light bg-extralight relative border px-3 py-2">
|
|
97
|
+
<pre class="wrap-break-word whitespace-pre-wrap"><code>{valueString}</code></pre>
|
|
98
|
+
</div>
|
|
99
|
+
</dd>
|
|
100
|
+
</div>
|
|
101
|
+
{#if preview}
|
|
102
|
+
<div class="flex w-full @lg:pl-50">
|
|
103
|
+
{@render componentPreview?.(preview)}
|
|
97
104
|
</div>
|
|
98
|
-
|
|
105
|
+
{/if}
|
|
99
106
|
</div>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
</div>
|
|
104
|
-
{/if}
|
|
105
|
-
</div>
|
|
106
|
-
{/each}
|
|
107
|
-
</dl>
|
|
107
|
+
{/each}
|
|
108
|
+
</dl>
|
|
109
|
+
</div>
|
|
108
110
|
</div>
|
|
109
111
|
{/if}
|
|
@@ -79,51 +79,54 @@
|
|
|
79
79
|
{@render header({ input: displayInput, setInput })}
|
|
80
80
|
</div>
|
|
81
81
|
{/if}
|
|
82
|
-
<div class="
|
|
83
|
-
<div class="flex
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
<div class="@container">
|
|
83
|
+
<div class="flex flex-col @2xl:flex-row">
|
|
84
|
+
<div class="flex min-w-0 flex-col gap-2 py-2 @2xl:flex-1">
|
|
85
|
+
<span class="text-gray-9 px-4 text-sm font-medium">Input</span>
|
|
86
|
+
<CodeEditor
|
|
87
|
+
label="input"
|
|
88
|
+
language="json"
|
|
89
|
+
value={displayInput}
|
|
90
|
+
onChange={(nextInput: string) => {
|
|
91
|
+
updateInput(nextInput)
|
|
92
|
+
}}
|
|
93
|
+
class="h-40 overflow-y-auto @2xl:h-56"
|
|
94
|
+
errorMessageID={lastErr ? uid : undefined}
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div
|
|
99
|
+
class="flex shrink-0 items-center justify-center border-y px-4 py-2 @2xl:border-x @2xl:border-y-0 @2xl:py-0"
|
|
100
|
+
>
|
|
101
|
+
<Button onclick={execute}>Execute</Button>
|
|
102
|
+
</div>
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
<div class="flex min-w-0 flex-col gap-2 py-2 @2xl:flex-1">
|
|
105
|
+
<div class="flex flex-row items-center">
|
|
106
|
+
<span class="text-gray-9 px-4 text-sm font-medium">Output</span>
|
|
107
|
+
{#if doCommandMutation.isPending}
|
|
108
|
+
<Progress
|
|
109
|
+
size="medium"
|
|
110
|
+
variant="dark"
|
|
111
|
+
/>
|
|
112
|
+
{/if}
|
|
113
|
+
</div>
|
|
114
|
+
{#if !lastErr}
|
|
115
|
+
<CodeEditor
|
|
116
|
+
label="output"
|
|
117
|
+
language="json"
|
|
118
|
+
value={output}
|
|
119
|
+
readonly
|
|
120
|
+
class="h-40 overflow-y-auto @2xl:h-56"
|
|
121
|
+
/>
|
|
122
|
+
{:else}
|
|
123
|
+
<ErrorDisplay
|
|
124
|
+
id={uid}
|
|
125
|
+
class="h-40 px-4 @2xl:h-56"
|
|
126
|
+
lastError={lastErr}
|
|
109
127
|
/>
|
|
110
128
|
{/if}
|
|
111
129
|
</div>
|
|
112
|
-
{#if !lastErr}
|
|
113
|
-
<CodeEditor
|
|
114
|
-
label="output"
|
|
115
|
-
language="json"
|
|
116
|
-
value={output}
|
|
117
|
-
readonly
|
|
118
|
-
class="h-56 overflow-y-auto"
|
|
119
|
-
/>
|
|
120
|
-
{:else}
|
|
121
|
-
<ErrorDisplay
|
|
122
|
-
id={uid}
|
|
123
|
-
class="h-56 px-4"
|
|
124
|
-
lastError={lastErr}
|
|
125
|
-
/>
|
|
126
|
-
{/if}
|
|
127
130
|
</div>
|
|
128
131
|
</div>
|
|
129
132
|
{:else}
|
|
@@ -29,51 +29,53 @@
|
|
|
29
29
|
|
|
30
30
|
<ConnectionStatus {partID}>
|
|
31
31
|
{#snippet connected()}
|
|
32
|
-
<div class="
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
<div class="@container">
|
|
33
|
+
<div class="flex flex-col divide-y @lg:flex-row @lg:divide-x @lg:divide-y-0">
|
|
34
|
+
<span class="flex grow flex-wrap gap-4">
|
|
35
|
+
<ApiSection
|
|
36
|
+
title="Open"
|
|
37
|
+
api="rdk:component:gripper"
|
|
38
|
+
class="grow-0 gap-3 @xs:pr-0"
|
|
39
|
+
>
|
|
40
|
+
<Open
|
|
41
|
+
{partID}
|
|
42
|
+
{resourceName}
|
|
43
|
+
/>
|
|
44
|
+
</ApiSection>
|
|
45
|
+
<ApiSection
|
|
46
|
+
title="Grab"
|
|
47
|
+
api="rdk:component:gripper"
|
|
48
|
+
class="grow-0 gap-3 @xs:pl-0"
|
|
49
|
+
>
|
|
50
|
+
<Grab
|
|
51
|
+
{partID}
|
|
52
|
+
{resourceName}
|
|
53
|
+
/>
|
|
54
|
+
</ApiSection>
|
|
55
|
+
</span>
|
|
56
|
+
<div class="flex flex-col divide-y">
|
|
57
|
+
<ApiSection
|
|
58
|
+
title="Stop"
|
|
59
|
+
api="rdk:component:gripper"
|
|
60
|
+
>
|
|
61
|
+
<StopButton
|
|
62
|
+
error={stopMutation.error}
|
|
63
|
+
onStop={() => {
|
|
64
|
+
stopMutation.mutate([])
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
</ApiSection>
|
|
68
|
+
<IsMoving
|
|
69
|
+
client={GripperClient}
|
|
70
|
+
api="rdk:component:gripper"
|
|
40
71
|
{partID}
|
|
41
72
|
{resourceName}
|
|
42
73
|
/>
|
|
43
|
-
|
|
44
|
-
<ApiSection
|
|
45
|
-
title="Grab"
|
|
46
|
-
api="rdk:component:gripper"
|
|
47
|
-
class="grow-0 gap-3 pl-0"
|
|
48
|
-
>
|
|
49
|
-
<Grab
|
|
74
|
+
<IsHoldingSomething
|
|
50
75
|
{partID}
|
|
51
76
|
{resourceName}
|
|
52
77
|
/>
|
|
53
|
-
</
|
|
54
|
-
</span>
|
|
55
|
-
<div class="flex flex-col divide-y">
|
|
56
|
-
<ApiSection
|
|
57
|
-
title="Stop"
|
|
58
|
-
api="rdk:component:gripper"
|
|
59
|
-
>
|
|
60
|
-
<StopButton
|
|
61
|
-
error={stopMutation.error}
|
|
62
|
-
onStop={() => {
|
|
63
|
-
stopMutation.mutate([])
|
|
64
|
-
}}
|
|
65
|
-
/>
|
|
66
|
-
</ApiSection>
|
|
67
|
-
<IsMoving
|
|
68
|
-
client={GripperClient}
|
|
69
|
-
api="rdk:component:gripper"
|
|
70
|
-
{partID}
|
|
71
|
-
{resourceName}
|
|
72
|
-
/>
|
|
73
|
-
<IsHoldingSomething
|
|
74
|
-
{partID}
|
|
75
|
-
{resourceName}
|
|
76
|
-
/>
|
|
78
|
+
</div>
|
|
77
79
|
</div>
|
|
78
80
|
</div>
|
|
79
81
|
{/snippet}
|
|
@@ -24,22 +24,24 @@
|
|
|
24
24
|
}
|
|
25
25
|
</script>
|
|
26
26
|
|
|
27
|
-
<div class="
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
<div class="@container">
|
|
28
|
+
<div class="flex flex-col gap-4 @2xl:h-120 @2xl:flex-row">
|
|
29
|
+
<Inputs
|
|
30
|
+
{pointSize}
|
|
31
|
+
{up}
|
|
32
|
+
{data}
|
|
33
|
+
onPointSizeChange={handlePointSizeChange}
|
|
34
|
+
onUpChange={handleUpChange}
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
<div class="relative h-80 overflow-hidden border @2xl:h-full @2xl:w-2/3">
|
|
38
|
+
<Canvas>
|
|
39
|
+
<Scene
|
|
40
|
+
{data}
|
|
41
|
+
{up}
|
|
42
|
+
{pointSize}
|
|
43
|
+
/>
|
|
44
|
+
</Canvas>
|
|
45
|
+
</div>
|
|
44
46
|
</div>
|
|
45
47
|
</div>
|
|
@@ -48,71 +48,76 @@
|
|
|
48
48
|
|
|
49
49
|
<ConnectionStatus {partID}>
|
|
50
50
|
{#snippet connected()}
|
|
51
|
-
<div class="
|
|
52
|
-
<div class="
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
>
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
51
|
+
<div class="@container">
|
|
52
|
+
<div class="flex flex-col divide-y @4xl:flex-row @4xl:divide-x @4xl:divide-y-0">
|
|
53
|
+
<div class="@container grow">
|
|
54
|
+
<div class="grid grid-cols-1 divide-y @2xl:grid-cols-3 @2xl:divide-x @2xl:divide-y-0">
|
|
55
|
+
<ApiSection
|
|
56
|
+
title="GetPosition"
|
|
57
|
+
api="rdk:component:servo"
|
|
58
|
+
bottomText="Updates automatically"
|
|
59
|
+
>
|
|
60
|
+
<Query query={positionQuery}>
|
|
61
|
+
{#if positionQuery.data !== undefined}
|
|
62
|
+
<!-- span required to get unit closer to position reading -->
|
|
63
|
+
<span class="flex flex-row gap-1">
|
|
64
|
+
<span class="font-roboto-mono font-normal"
|
|
65
|
+
>{formatNumeric(positionQuery.data)}</span
|
|
66
|
+
>
|
|
67
|
+
<abbr class="text-subtle-2">º</abbr>
|
|
68
|
+
</span>
|
|
69
|
+
{/if}
|
|
70
|
+
</Query>
|
|
71
|
+
</ApiSection>
|
|
72
|
+
<ApiSection
|
|
73
|
+
title="Move"
|
|
74
|
+
api="rdk:component:servo"
|
|
75
|
+
>
|
|
76
|
+
<Query query={positionQuery}>
|
|
77
|
+
{#if positionQuery.data !== undefined}
|
|
78
|
+
<Move
|
|
79
|
+
currentPosition={positionQuery.data}
|
|
80
|
+
{moveTo}
|
|
81
|
+
lastError={moveMutation.error}
|
|
82
|
+
/>
|
|
83
|
+
{/if}
|
|
84
|
+
</Query>
|
|
85
|
+
</ApiSection>
|
|
86
|
+
<ApiSection
|
|
87
|
+
title="Quick move"
|
|
88
|
+
bottomText="Press a button to execute"
|
|
89
|
+
>
|
|
90
|
+
<Query query={positionQuery}>
|
|
91
|
+
{#if positionQuery.data !== undefined}
|
|
92
|
+
<QuickMove
|
|
93
|
+
currentPosition={positionQuery.data}
|
|
94
|
+
moveTo={quickMoveTo}
|
|
95
|
+
lastError={quickMoveMutation.error}
|
|
96
|
+
/>
|
|
97
|
+
{/if}
|
|
98
|
+
</Query>
|
|
99
|
+
</ApiSection>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="flex flex-col divide-y @4xl:ml-auto @4xl:w-full @4xl:max-w-40">
|
|
103
|
+
<ApiSection
|
|
104
|
+
title="Stop"
|
|
105
|
+
api="rdk:component:servo"
|
|
106
|
+
>
|
|
107
|
+
<StopButton
|
|
108
|
+
error={stopMutation.error}
|
|
109
|
+
onStop={() => {
|
|
110
|
+
stopMutation.mutate([])
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
</ApiSection>
|
|
114
|
+
<IsMoving
|
|
115
|
+
client={ServoClient}
|
|
116
|
+
api="rdk:component:servo"
|
|
117
|
+
{partID}
|
|
118
|
+
{resourceName}
|
|
108
119
|
/>
|
|
109
|
-
</
|
|
110
|
-
<IsMoving
|
|
111
|
-
client={ServoClient}
|
|
112
|
-
api="rdk:component:servo"
|
|
113
|
-
{partID}
|
|
114
|
-
{resourceName}
|
|
115
|
-
/>
|
|
120
|
+
</div>
|
|
116
121
|
</div>
|
|
117
122
|
</div>
|
|
118
123
|
{/snippet}
|
|
@@ -70,6 +70,9 @@
|
|
|
70
70
|
|
|
71
71
|
let container = $state<HTMLElement>()
|
|
72
72
|
let size = $state<Size>()
|
|
73
|
+
let isStacked = $state(false)
|
|
74
|
+
|
|
75
|
+
const STACK_WIDTH_PX = 672
|
|
73
76
|
|
|
74
77
|
useResizeObserver(
|
|
75
78
|
() => container,
|
|
@@ -80,6 +83,7 @@
|
|
|
80
83
|
|
|
81
84
|
const setSize = () => {
|
|
82
85
|
if (container) {
|
|
86
|
+
isStacked = container.clientWidth < STACK_WIDTH_PX
|
|
83
87
|
size = getImageSize(img, container)
|
|
84
88
|
}
|
|
85
89
|
}
|
|
@@ -101,7 +105,10 @@
|
|
|
101
105
|
</script>
|
|
102
106
|
|
|
103
107
|
<div
|
|
104
|
-
class=
|
|
108
|
+
class={[
|
|
109
|
+
'flex min-h-0 w-full min-w-0 gap-2 py-2 pl-2',
|
|
110
|
+
isStacked ? 'flex-col' : 'h-full flex-row',
|
|
111
|
+
]}
|
|
105
112
|
bind:this={container}
|
|
106
113
|
>
|
|
107
114
|
{#if !size}
|
|
@@ -129,8 +136,8 @@
|
|
|
129
136
|
</Canvas>
|
|
130
137
|
</div>
|
|
131
138
|
<div
|
|
132
|
-
class=
|
|
133
|
-
style:height={`${size.height.toString()}px`}
|
|
139
|
+
class={['flex grow flex-col pr-2', isStacked && 'min-h-40']}
|
|
140
|
+
style:height={isStacked ? undefined : `${size.height.toString()}px`}
|
|
134
141
|
>
|
|
135
142
|
<Legend
|
|
136
143
|
classifications={data?.classifications}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
</script>
|
|
62
62
|
|
|
63
63
|
<div class="relative h-[600px] max-h-[80vh] bg-white">
|
|
64
|
-
<div class="relative z-10 h-full overflow-y-scroll p-4">
|
|
64
|
+
<div class="relative z-10 h-full overflow-x-auto overflow-y-scroll p-4">
|
|
65
65
|
<div class="grid grid-cols-[repeat(auto-fit,320px)] justify-center gap-4">
|
|
66
66
|
{#each items as item (item.id)}
|
|
67
67
|
<div class="w-[320px] shadow-sm">
|
|
@@ -122,8 +122,8 @@
|
|
|
122
122
|
<ConnectionStatus {partID}>
|
|
123
123
|
{#snippet connected()}
|
|
124
124
|
<div class="flex flex-col gap-2 px-4 pt-4 pb-3">
|
|
125
|
-
<div class="flex flex-
|
|
126
|
-
<div class="w-50">
|
|
125
|
+
<div class="flex flex-wrap gap-4">
|
|
126
|
+
<div class="w-50 max-w-full">
|
|
127
127
|
<Label position="top">
|
|
128
128
|
Camera
|
|
129
129
|
<Select
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
|
|
161
161
|
<h6 class="text-subtle-1 font-semibold">Detections/Classifications</h6>
|
|
162
162
|
|
|
163
|
-
<div class="flex gap-4">
|
|
163
|
+
<div class="flex flex-wrap gap-4">
|
|
164
164
|
<RefetchController
|
|
165
165
|
allowLive
|
|
166
166
|
{refetchInterval}
|
|
@@ -218,8 +218,8 @@
|
|
|
218
218
|
</Queries>
|
|
219
219
|
|
|
220
220
|
<h6 class="text-subtle-1 mt-4 font-semibold">Object point clouds</h6>
|
|
221
|
-
<div class="flex items-center gap-4">
|
|
222
|
-
<div class="w-50">
|
|
221
|
+
<div class="flex flex-wrap items-center gap-4">
|
|
222
|
+
<div class="w-50 max-w-full">
|
|
223
223
|
<Label position="left">
|
|
224
224
|
Show object point clouds
|
|
225
225
|
<Switch
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viamrobotics/test-widgets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"wireit": {
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
"@playwright/test": "^1.59.1",
|
|
220
220
|
"@sentry/svelte": "^10.50.0",
|
|
221
221
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
222
|
-
"@sveltejs/kit": "^2.
|
|
222
|
+
"@sveltejs/kit": "^2.69.1",
|
|
223
223
|
"@sveltejs/package": "^2.5.7",
|
|
224
224
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
225
225
|
"@tailwindcss/postcss": "^4.2.4",
|