@picked/svelte 0.0.44 → 0.0.45-next.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/dist/plugins/devtools/DevToolsExperience.svelte +61 -44
- package/dist/plugins/devtools/components/ExperienceInstanceListItem.svelte +2 -1
- package/dist/plugins/devtools/components/ExperienceInstancesTable.svelte +22 -20
- package/dist/plugins/devtools/components/Tabs.svelte +20 -7
- package/dist/plugins/devtools/experience.js +1 -1
- package/dist/plugins/devtools/screens/components/ComponentsListScreen.svelte +18 -18
- package/dist/plugins/devtools/screens/events/EventListItem.svelte +28 -42
- package/dist/plugins/devtools/screens/events/EventsListScreen.svelte +10 -11
- package/dist/plugins/devtools/screens/events/EventsTable.svelte +31 -33
- package/dist/plugins/devtools/screens/experiences/ExperienceDetailsScreen.svelte +13 -16
- package/dist/plugins/devtools/screens/experiences/ExperienceTreeScreen.svelte +20 -71
- package/dist/plugins/devtools/screens/features/FeaturesListScreen.svelte +96 -232
- package/dist/plugins/devtools/screens/frameworks/FrameworksListScreen.svelte +14 -16
- package/dist/plugins/devtools/screens/history/HistoryEntriesTable.svelte +18 -16
- package/dist/plugins/devtools/screens/predicates/PredicatesListScreen.svelte +14 -16
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +25 -63
- package/dist/plugins/devtools/screens/responses/ResponsesTable.svelte +43 -64
- package/dist/plugins/devtools/ui/actions/Button.svelte +171 -0
- package/dist/plugins/devtools/ui/actions/CopyButton.svelte +88 -0
- package/dist/plugins/devtools/ui/data/Badge.svelte +62 -0
- package/dist/plugins/devtools/ui/data/CodeBlock.svelte +38 -0
- package/dist/plugins/devtools/ui/data/DataTable.svelte +134 -0
- package/dist/plugins/devtools/ui/data/EmptyState.svelte +26 -0
- package/dist/plugins/devtools/ui/data/ExpandableRow.svelte +66 -0
- package/dist/plugins/devtools/ui/data/VisualizationContainer.svelte +55 -0
- package/dist/plugins/devtools/ui/feedback/Banner.svelte +116 -0
- package/dist/plugins/devtools/ui/feedback/Spinner.svelte +79 -0
- package/dist/plugins/devtools/ui/forms/Checkbox.svelte +139 -0
- package/dist/plugins/devtools/ui/forms/RadioGroup.svelte +218 -0
- package/dist/plugins/devtools/ui/forms/Select.svelte +137 -0
- package/dist/plugins/devtools/ui/forms/Switch.svelte +158 -0
- package/dist/plugins/devtools/ui/forms/TextField.svelte +125 -0
- package/dist/plugins/devtools/ui/index.d.ts +22 -0
- package/dist/plugins/devtools/ui/index.js +1 -0
- package/dist/plugins/devtools/ui/layout/Card.svelte +55 -0
- package/dist/plugins/devtools/ui/layout/Divider.svelte +34 -0
- package/dist/plugins/devtools/ui/layout/Spacer.svelte +11 -0
- package/dist/plugins/devtools/ui/layout/Stack.svelte +129 -0
- package/dist/plugins/devtools/ui/overlays/Tooltip.svelte +90 -0
- package/dist/plugins/devtools/ui/tokens.css +144 -0
- package/dist/plugins/devtools/ui/tokens.css.js +1 -0
- package/dist/plugins/devtools/ui/typography/Heading.svelte +55 -0
- package/dist/plugins/devtools/ui/typography/Text.svelte +93 -0
- package/package.json +17 -2
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
@paired-component apps/dashboard/src/shared/ui/layout/page.tsx
|
|
3
|
+
@design-parity The devtools modal layout mirrors the Dashboard Page component.
|
|
4
|
+
The toolbar, main area, padding, and border radius must stay visually identical
|
|
5
|
+
to the Dashboard's AppShell content area. When modifying this layout, replicate
|
|
6
|
+
the change in the paired React component to maintain visual and behavioral parity.
|
|
7
|
+
-->
|
|
1
8
|
<script lang="ts">
|
|
2
9
|
import { getExperience } from '../../hooks'
|
|
10
|
+
import { Button } from './ui'
|
|
3
11
|
import PickedLogo from './PickedLogo.svelte'
|
|
4
12
|
import Tabs from './components/Tabs.svelte'
|
|
5
13
|
import ExperiencesListScreen from './screens/experiences/ExperiencesListScreen.svelte'
|
|
@@ -91,9 +99,14 @@
|
|
|
91
99
|
>
|
|
92
100
|
<div class="backdrop"></div>
|
|
93
101
|
<div class="container">
|
|
94
|
-
<header class="
|
|
95
|
-
<
|
|
96
|
-
|
|
102
|
+
<header class="toolbar" id="devtools-header">
|
|
103
|
+
<div class="toolbar-left">
|
|
104
|
+
<PickedLogo width={80} height={28} />
|
|
105
|
+
</div>
|
|
106
|
+
<div class="toolbar-center"></div>
|
|
107
|
+
<div class="toolbar-right">
|
|
108
|
+
<Button variant="ghost" size="small" onclick={() => experience.close()}>Close</Button>
|
|
109
|
+
</div>
|
|
97
110
|
</header>
|
|
98
111
|
<section class="main">
|
|
99
112
|
<Tabs {tabs} initialTab={1} />
|
|
@@ -103,7 +116,7 @@
|
|
|
103
116
|
{:else}
|
|
104
117
|
<button
|
|
105
118
|
class="floating-button"
|
|
106
|
-
|
|
119
|
+
onclick={() => experience.open()}
|
|
107
120
|
aria-label="Open Picked Devtools"
|
|
108
121
|
title="Open Picked Devtools (or press .)"
|
|
109
122
|
>
|
|
@@ -114,71 +127,74 @@
|
|
|
114
127
|
<style>
|
|
115
128
|
*,
|
|
116
129
|
.devtools * {
|
|
117
|
-
box-sizing:
|
|
130
|
+
box-sizing: border-box;
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
.devtools {
|
|
121
134
|
position: fixed;
|
|
122
|
-
|
|
123
|
-
left: 0;
|
|
124
|
-
width: 100%;
|
|
125
|
-
height: 100%;
|
|
135
|
+
inset: 0;
|
|
126
136
|
z-index: 999999999;
|
|
127
|
-
padding:
|
|
137
|
+
padding: 48px;
|
|
128
138
|
display: grid;
|
|
129
139
|
place-items: center;
|
|
130
140
|
overflow: hidden;
|
|
131
|
-
font-size: 13px;
|
|
132
|
-
color: black;
|
|
133
|
-
line-height: 1;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.devtools button {
|
|
137
|
-
font-size: 13px;
|
|
138
|
-
color: black;
|
|
139
|
-
line-height: 1;
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
.backdrop {
|
|
143
144
|
position: fixed;
|
|
144
|
-
|
|
145
|
-
left: 0;
|
|
146
|
-
width: 100%;
|
|
147
|
-
height: 100%;
|
|
145
|
+
inset: 0;
|
|
148
146
|
background-color: rgba(0, 0, 0, 0.5);
|
|
149
147
|
z-index: 1;
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
.container {
|
|
153
|
-
background-color: white;
|
|
151
|
+
background-color: var(--color-white);
|
|
152
|
+
border-radius: var(--radius-xl);
|
|
153
|
+
box-shadow: var(--shadow-lg);
|
|
154
154
|
display: flex;
|
|
155
155
|
flex-direction: column;
|
|
156
|
-
|
|
157
|
-
border-radius: 4px;
|
|
158
|
-
box-shadow: 4px 4px 4px #00000029;
|
|
159
|
-
border: 1px solid lightgray;
|
|
156
|
+
overflow: hidden;
|
|
160
157
|
z-index: 2;
|
|
161
|
-
overflow: auto;
|
|
162
158
|
width: 100%;
|
|
163
159
|
height: 100%;
|
|
164
160
|
}
|
|
165
161
|
|
|
166
|
-
.
|
|
167
|
-
height:
|
|
168
|
-
|
|
162
|
+
.toolbar {
|
|
163
|
+
height: 40px;
|
|
164
|
+
background-color: var(--color-white);
|
|
165
|
+
border-bottom: 1px solid var(--color-gray-200);
|
|
166
|
+
padding: 0 var(--space-4);
|
|
169
167
|
display: flex;
|
|
170
168
|
align-items: center;
|
|
171
|
-
padding: 0.5em;
|
|
172
169
|
justify-content: space-between;
|
|
170
|
+
flex-shrink: 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.toolbar-left {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.toolbar-center {
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
justify-content: center;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.toolbar-right {
|
|
185
|
+
display: flex;
|
|
186
|
+
align-items: center;
|
|
173
187
|
}
|
|
174
188
|
|
|
175
189
|
.main {
|
|
176
|
-
flex: 1
|
|
177
|
-
|
|
190
|
+
flex: 1;
|
|
191
|
+
background-color: var(--color-gray-50);
|
|
192
|
+
overflow: auto;
|
|
193
|
+
display: flex;
|
|
178
194
|
flex-direction: column;
|
|
179
|
-
height: 100%;
|
|
180
195
|
}
|
|
181
196
|
|
|
197
|
+
/* Global table styles for screens that still use raw tables */
|
|
182
198
|
.devtools :global(table) {
|
|
183
199
|
width: 100%;
|
|
184
200
|
border-collapse: collapse;
|
|
@@ -186,15 +202,16 @@
|
|
|
186
202
|
|
|
187
203
|
.devtools :global(th),
|
|
188
204
|
.devtools :global(td) {
|
|
189
|
-
padding:
|
|
205
|
+
padding: var(--space-2);
|
|
190
206
|
text-align: left;
|
|
191
|
-
border-bottom: 1px solid
|
|
207
|
+
border-bottom: 1px solid var(--color-gray-200);
|
|
208
|
+
font-size: var(--text-sm);
|
|
209
|
+
color: var(--color-gray-900);
|
|
192
210
|
}
|
|
193
211
|
|
|
194
212
|
.devtools :global(th) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
background-color: #f0f0f0;
|
|
213
|
+
font-weight: var(--font-medium);
|
|
214
|
+
background-color: var(--color-gray-50);
|
|
198
215
|
}
|
|
199
216
|
|
|
200
217
|
.floating-button {
|
|
@@ -203,9 +220,9 @@
|
|
|
203
220
|
right: 1.5rem;
|
|
204
221
|
width: 4.5rem;
|
|
205
222
|
height: 4.5rem;
|
|
206
|
-
border-radius:
|
|
207
|
-
background-color: white;
|
|
208
|
-
border: 1px solid
|
|
223
|
+
border-radius: var(--radius-full);
|
|
224
|
+
background-color: var(--color-white);
|
|
225
|
+
border: 1px solid var(--color-gray-200);
|
|
209
226
|
box-shadow: 0 4px 12px rgba(21, 73, 255, 0.2);
|
|
210
227
|
display: flex;
|
|
211
228
|
align-items: center;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceInstance } from '@picked/client'
|
|
3
|
+
import { Button } from '../ui'
|
|
3
4
|
|
|
4
5
|
export let experienceInstance: ExperienceInstance
|
|
5
6
|
|
|
@@ -15,7 +16,7 @@
|
|
|
15
16
|
|
|
16
17
|
<tr>
|
|
17
18
|
<td>{experienceInstance.experienceId}</td>
|
|
18
|
-
<td><
|
|
19
|
+
<td><Button variant="ghost" size="small" onclick={() => experienceInstance.toggleOpen()}>{$isOpen}</Button></td>
|
|
19
20
|
<td>{$currentNode?.id || ''}</td>
|
|
20
21
|
<td>{$currentNode?.type || ''}</td>
|
|
21
22
|
<td>{$currentStep?.id || ''}</td>
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceInstance } from '@picked/client'
|
|
3
3
|
import ExperienceInstanceListItem from './ExperienceInstanceListItem.svelte'
|
|
4
|
+
import { DataTable, EmptyState } from '../ui'
|
|
4
5
|
|
|
5
6
|
export let experienceInstances: ExperienceInstance[]
|
|
7
|
+
|
|
8
|
+
const columns = [
|
|
9
|
+
{ key: 'experience', header: 'Experience' },
|
|
10
|
+
{ key: 'isOpen', header: 'Is Open' },
|
|
11
|
+
{ key: 'currentNodeId', header: 'Current node ID' },
|
|
12
|
+
{ key: 'currentNodeType', header: 'Current node Type' },
|
|
13
|
+
{ key: 'currentStepId', header: 'Current step ID' },
|
|
14
|
+
{ key: 'currentStepTitle', header: 'Current step Title' },
|
|
15
|
+
{ key: 'nextSteps', header: 'Next reachable steps amount' },
|
|
16
|
+
{ key: 'stepsToOrigin', header: 'Steps to origin' },
|
|
17
|
+
{ key: 'stepsToEnd', header: 'Steps to end' },
|
|
18
|
+
]
|
|
6
19
|
</script>
|
|
7
20
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<th>Next reachable steps amount</th>
|
|
18
|
-
<th>Steps to origin</th>
|
|
19
|
-
<th>Steps to end</th>
|
|
20
|
-
</tr>
|
|
21
|
-
</thead>
|
|
22
|
-
<tbody>
|
|
23
|
-
{#each experienceInstances as experienceInstance (experienceInstance.id)}
|
|
24
|
-
<ExperienceInstanceListItem {experienceInstance} />
|
|
25
|
-
{/each}
|
|
26
|
-
</tbody>
|
|
27
|
-
</table>
|
|
21
|
+
<DataTable columns={columns} rows={experienceInstances}>
|
|
22
|
+
{#snippet row(item)}
|
|
23
|
+
{@const experienceInstance = item}
|
|
24
|
+
<ExperienceInstanceListItem {experienceInstance} />
|
|
25
|
+
{/snippet}
|
|
26
|
+
{#snippet empty()}
|
|
27
|
+
<EmptyState message="No experience instances" />
|
|
28
|
+
{/snippet}
|
|
29
|
+
</DataTable>
|
|
@@ -82,37 +82,50 @@
|
|
|
82
82
|
width: 100%;
|
|
83
83
|
display: flex;
|
|
84
84
|
flex-direction: column;
|
|
85
|
+
flex: 1;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
.tab-list {
|
|
88
89
|
display: flex;
|
|
89
|
-
border-bottom: 1px solid
|
|
90
|
+
border-bottom: 1px solid var(--color-gray-200);
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
overflow-x: auto;
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
.tab-button {
|
|
93
|
-
padding:
|
|
96
|
+
padding: var(--space-2) var(--space-4);
|
|
94
97
|
border: none;
|
|
95
98
|
background: none;
|
|
96
99
|
cursor: pointer;
|
|
97
100
|
border-bottom: 2px solid transparent;
|
|
101
|
+
font-size: var(--text-sm);
|
|
102
|
+
color: var(--color-gray-600);
|
|
103
|
+
font-family: inherit;
|
|
104
|
+
white-space: nowrap;
|
|
105
|
+
transition: color 0.15s ease, border-color 0.15s ease;
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
.tab-button:hover {
|
|
101
|
-
background-color:
|
|
109
|
+
background-color: var(--color-gray-100);
|
|
110
|
+
color: var(--color-gray-900);
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
.tab-button.active {
|
|
105
|
-
border-bottom:
|
|
114
|
+
border-bottom-color: var(--color-gray-900);
|
|
115
|
+
color: var(--color-gray-900);
|
|
116
|
+
font-weight: var(--font-medium);
|
|
106
117
|
}
|
|
107
118
|
|
|
108
|
-
.tab-button:focus {
|
|
109
|
-
outline:
|
|
110
|
-
outline-offset: -
|
|
119
|
+
.tab-button:focus-visible {
|
|
120
|
+
outline: var(--ring-width) solid var(--ring-color);
|
|
121
|
+
outline-offset: calc(-1 * var(--ring-width));
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
.tab-panel {
|
|
114
125
|
flex: 1 1 auto;
|
|
115
126
|
display: grid;
|
|
127
|
+
align-content: start;
|
|
128
|
+
overflow: auto;
|
|
116
129
|
}
|
|
117
130
|
|
|
118
131
|
.tab-panel:not(.active) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createExperience as e}from"@picked/client/plugins/create-experience";import{adaptSvelteComponent as o}from"../../component.js";import t from"./DevToolsExperience.svelte";const
|
|
1
|
+
import{createExperience as e}from"@picked/client/plugins/create-experience";import{adaptSvelteComponent as o}from"../../component.js";import t from"./DevToolsExperience.svelte";import p from"./ui/tokens.css.js";const r=e({id:"svelte-devtools",name:"Picked Devtools",decide:{},targets:[{selector:"body",placement:"append"}],component:o(t,{css:[p]})});r.addStep({label:"Tools"});export{r as devtoolsExperience};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getPicked } from '../../../../hooks'
|
|
3
|
+
import { DataTable, EmptyState } from '../../ui'
|
|
3
4
|
|
|
4
5
|
const client = getPicked()
|
|
5
6
|
|
|
6
7
|
$: components = client.components.listStore
|
|
8
|
+
|
|
9
|
+
const columns = [
|
|
10
|
+
{ key: 'name', header: 'Name' },
|
|
11
|
+
{ key: 'framework', header: 'Framework' },
|
|
12
|
+
]
|
|
7
13
|
</script>
|
|
8
14
|
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<td>{component.component.frameworkName}</td>
|
|
22
|
-
</tr>
|
|
23
|
-
{/each}
|
|
24
|
-
</tbody>
|
|
25
|
-
</table>
|
|
26
|
-
</div>
|
|
15
|
+
<DataTable columns={columns} rows={$components}>
|
|
16
|
+
{#snippet row(item)}
|
|
17
|
+
{@const component = item}
|
|
18
|
+
<tr>
|
|
19
|
+
<td>{component.name}</td>
|
|
20
|
+
<td>{component.component.frameworkName}</td>
|
|
21
|
+
</tr>
|
|
22
|
+
{/snippet}
|
|
23
|
+
{#snippet empty()}
|
|
24
|
+
<EmptyState message="No components" />
|
|
25
|
+
{/snippet}
|
|
26
|
+
</DataTable>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { EventBusPayload, EventHistoryEntry } from '@picked/client'
|
|
3
|
+
import { Badge, Card, CodeBlock, Stack, Text } from '../../ui'
|
|
3
4
|
|
|
4
5
|
export let event: EventHistoryEntry
|
|
5
6
|
export let isExpanded: boolean
|
|
@@ -23,15 +24,12 @@
|
|
|
23
24
|
function getPayloadFields(payload: EventBusPayload): PayloadField[] {
|
|
24
25
|
const fields: PayloadField[] = []
|
|
25
26
|
|
|
26
|
-
// Add type
|
|
27
27
|
fields.push({ label: 'Type', value: payload.type })
|
|
28
28
|
|
|
29
|
-
// Add optional value field if present
|
|
30
29
|
if ('value' in payload && payload.value !== undefined) {
|
|
31
30
|
fields.push({ label: 'Value', value: payload.value })
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
// Add experience identifiers if present
|
|
35
33
|
if ('experience' in payload && payload.experience) {
|
|
36
34
|
const exp = payload.experience
|
|
37
35
|
if (exp && typeof exp === 'object') {
|
|
@@ -44,7 +42,6 @@
|
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
// Add step information if present
|
|
48
45
|
if ('step' in payload && payload.step) {
|
|
49
46
|
const step = payload.step
|
|
50
47
|
if (step && typeof step === 'object') {
|
|
@@ -57,27 +54,22 @@
|
|
|
57
54
|
}
|
|
58
55
|
}
|
|
59
56
|
|
|
60
|
-
// Add form information if present
|
|
61
57
|
if ('form' in payload && payload.form) {
|
|
62
58
|
fields.push({ label: 'Form', value: JSON.stringify(payload.form) })
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
// Add feature information if present
|
|
66
61
|
if ('feature' in payload && payload.feature) {
|
|
67
62
|
fields.push({ label: 'Feature', value: JSON.stringify(payload.feature) })
|
|
68
63
|
}
|
|
69
64
|
|
|
70
|
-
// Add exception/validation errors if present
|
|
71
65
|
if ('exception' in payload && payload.exception) {
|
|
72
66
|
fields.push({ label: 'Exception', value: JSON.stringify(payload.exception) })
|
|
73
67
|
}
|
|
74
68
|
|
|
75
|
-
// Add version if present
|
|
76
69
|
if ('version' in payload && payload.version) {
|
|
77
70
|
fields.push({ label: 'Version', value: payload.version })
|
|
78
71
|
}
|
|
79
72
|
|
|
80
|
-
// Add session id if present
|
|
81
73
|
if ('id' in payload && payload.id && payload.type === 'session') {
|
|
82
74
|
fields.push({ label: 'Session ID', value: payload.id })
|
|
83
75
|
}
|
|
@@ -94,49 +86,43 @@
|
|
|
94
86
|
}
|
|
95
87
|
</script>
|
|
96
88
|
|
|
97
|
-
<tr
|
|
98
|
-
<td
|
|
99
|
-
<span
|
|
89
|
+
<tr class="event-row" onclick={onToggle}>
|
|
90
|
+
<td>
|
|
91
|
+
<span class="expand-icon">
|
|
100
92
|
{isExpanded ? '▼' : '▶'}
|
|
101
93
|
</span>
|
|
102
|
-
{formatTime(event.at)}
|
|
94
|
+
<CodeBlock code={formatTime(event.at)} inline />
|
|
103
95
|
</td>
|
|
104
96
|
<td>
|
|
105
|
-
<
|
|
106
|
-
style="display: inline-block; padding: 0.25rem 0.5rem; background-color: #e8f4ff; border: 1px solid #b3d9ff; border-radius: 3px; font-size: 12px; color: #0066cc;"
|
|
107
|
-
>
|
|
108
|
-
{event.payload.type}
|
|
109
|
-
</code>
|
|
97
|
+
<Badge status="info">{event.payload.type}</Badge>
|
|
110
98
|
</td>
|
|
111
|
-
<td
|
|
112
|
-
|
|
99
|
+
<td>
|
|
100
|
+
<Text size="small">
|
|
101
|
+
{'experience' in event.payload && event.payload.experience ? event.payload.experience.experienceId : '-'}
|
|
102
|
+
</Text>
|
|
113
103
|
</td>
|
|
114
|
-
<td
|
|
115
|
-
|
|
104
|
+
<td>
|
|
105
|
+
<Text size="caption" color="subdued">
|
|
106
|
+
{isExpanded ? 'Click to collapse' : 'Click to expand payload'}
|
|
107
|
+
</Text>
|
|
116
108
|
</td>
|
|
117
109
|
</tr>
|
|
118
110
|
{#if isExpanded}
|
|
119
111
|
<tr>
|
|
120
|
-
<td colspan="4"
|
|
121
|
-
<
|
|
122
|
-
Event Payload
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
>
|
|
135
|
-
{formatValue(field.value)}
|
|
136
|
-
</code>
|
|
137
|
-
</div>
|
|
138
|
-
{/each}
|
|
139
|
-
</div>
|
|
112
|
+
<td colspan="4" class="details-cell">
|
|
113
|
+
<Stack direction="vertical" gap="small">
|
|
114
|
+
<Text size="small" weight="semibold">Event Payload</Text>
|
|
115
|
+
<Card>
|
|
116
|
+
<Stack direction="vertical" gap="small">
|
|
117
|
+
{#each getPayloadFields(event.payload) as field}
|
|
118
|
+
<Text size="caption" inline>
|
|
119
|
+
<Text size="caption" weight="semibold" color="subdued" inline>{field.label}:</Text>
|
|
120
|
+
<CodeBlock code={formatValue(field.value)} inline />
|
|
121
|
+
</Text>
|
|
122
|
+
{/each}
|
|
123
|
+
</Stack>
|
|
124
|
+
</Card>
|
|
125
|
+
</Stack>
|
|
140
126
|
</td>
|
|
141
127
|
</tr>
|
|
142
128
|
{/if}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getPicked } from '../../../../hooks'
|
|
3
3
|
import EventsTable from './EventsTable.svelte'
|
|
4
|
+
import { Divider, Spacer, Stack, Text } from '../../ui'
|
|
4
5
|
|
|
5
6
|
const { events } = getPicked()
|
|
6
7
|
</script>
|
|
7
8
|
|
|
8
|
-
<
|
|
9
|
+
<Stack direction="vertical" gap="none" fill>
|
|
9
10
|
<EventsTable />
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
>
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
11
|
+
<Spacer />
|
|
12
|
+
<Divider />
|
|
13
|
+
<Stack padding="small">
|
|
14
|
+
<Text size="caption" color="subdued">
|
|
15
|
+
{$events.length} events
|
|
16
|
+
</Text>
|
|
17
|
+
</Stack>
|
|
18
|
+
</Stack>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { combine, createStore, createEvent, sample } from 'effector'
|
|
3
3
|
import { getPicked } from '../../../../hooks'
|
|
4
4
|
import EventListItem from './EventListItem.svelte'
|
|
5
|
+
import { DataTable, EmptyState } from '../../ui'
|
|
5
6
|
import type { EventHistoryEntry } from '@picked/client'
|
|
6
7
|
|
|
7
8
|
const { events } = getPicked()
|
|
@@ -18,7 +19,6 @@
|
|
|
18
19
|
expandedRowIds = newSet
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
22
|
const sortDirectionStore = createStore<'asc' | 'desc'>('desc')
|
|
23
23
|
const toggleSortDirection = createEvent<void>()
|
|
24
24
|
const oppositeSortDirection: Record<'asc' | 'desc', 'asc' | 'desc'> = { asc: 'desc', desc: 'asc' }
|
|
@@ -38,37 +38,35 @@
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const sortedEvents = combine(events, sortDirectionStore, sortEvents)
|
|
41
|
+
|
|
42
|
+
const columns = [
|
|
43
|
+
{ key: 'time', header: 'Time', sortable: true },
|
|
44
|
+
{ key: 'eventType', header: 'Event Type' },
|
|
45
|
+
{ key: 'experience', header: 'Experience' },
|
|
46
|
+
{ key: 'actions', header: '' },
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
function handleSort() {
|
|
50
|
+
toggleSortDirection()
|
|
51
|
+
}
|
|
41
52
|
</script>
|
|
42
53
|
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
</td>
|
|
63
|
-
</tr>
|
|
64
|
-
{:else}
|
|
65
|
-
{#each $sortedEvents as event (event.at)}
|
|
66
|
-
<EventListItem
|
|
67
|
-
{event}
|
|
68
|
-
isExpanded={expandedRowIds.has(event.id)}
|
|
69
|
-
onToggle={() => toggleRow(event.id)}
|
|
70
|
-
/>
|
|
71
|
-
{/each}
|
|
72
|
-
{/if}
|
|
73
|
-
</tbody>
|
|
74
|
-
</table>
|
|
54
|
+
<DataTable
|
|
55
|
+
columns={columns}
|
|
56
|
+
rows={$sortedEvents}
|
|
57
|
+
sortKey="time"
|
|
58
|
+
sortDirection={$sortDirectionStore}
|
|
59
|
+
onSort={handleSort}
|
|
60
|
+
>
|
|
61
|
+
{#snippet row(item)}
|
|
62
|
+
{@const event = item}
|
|
63
|
+
<EventListItem
|
|
64
|
+
{event}
|
|
65
|
+
isExpanded={expandedRowIds.has(event.id)}
|
|
66
|
+
onToggle={() => toggleRow(event.id)}
|
|
67
|
+
/>
|
|
68
|
+
{/snippet}
|
|
69
|
+
{#snippet empty()}
|
|
70
|
+
<EmptyState message="No events yet. Interact with the page to see events." />
|
|
71
|
+
{/snippet}
|
|
72
|
+
</DataTable>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceStore } from '@picked/client'
|
|
3
3
|
import { getPicked } from '../../../../hooks'
|
|
4
|
+
import { Button, Text, CodeBlock, Stack } from '../../ui'
|
|
4
5
|
|
|
5
6
|
const client = getPicked()
|
|
6
7
|
export let experience: ExperienceStore
|
|
@@ -8,39 +9,35 @@
|
|
|
8
9
|
$: config = experience.configStore
|
|
9
10
|
</script>
|
|
10
11
|
|
|
11
|
-
<
|
|
12
|
+
<Stack direction="vertical" gap="medium" padding="medium">
|
|
12
13
|
<div>
|
|
13
|
-
<
|
|
14
|
+
<Button variant="primary" size="small" onclick={() => client.launchExperienceById(experience.id)}>
|
|
15
|
+
Launch experience
|
|
16
|
+
</Button>
|
|
14
17
|
</div>
|
|
15
18
|
|
|
16
19
|
<div>
|
|
17
|
-
<
|
|
18
|
-
<
|
|
20
|
+
<Text weight="semibold">Type</Text>
|
|
21
|
+
<Text>{$config.type}</Text>
|
|
19
22
|
</div>
|
|
20
23
|
|
|
21
24
|
<div>
|
|
22
|
-
<
|
|
25
|
+
<Text weight="semibold">Target selectors</Text>
|
|
23
26
|
<ul>
|
|
24
27
|
{#if $config.targetSelectors.length > 0}
|
|
25
28
|
{#each $config.targetSelectors as selector (selector)}
|
|
26
29
|
<li>
|
|
27
|
-
<
|
|
30
|
+
<CodeBlock code="{selector.selector} || {selector.placement}" />
|
|
28
31
|
</li>
|
|
29
32
|
{/each}
|
|
30
33
|
{:else}
|
|
31
|
-
<li>(none)</li>
|
|
34
|
+
<li><Text color="subdued">(none)</Text></li>
|
|
32
35
|
{/if}
|
|
33
36
|
</ul>
|
|
34
37
|
</div>
|
|
35
38
|
|
|
36
39
|
<div>
|
|
37
|
-
<
|
|
38
|
-
<
|
|
40
|
+
<Text weight="semibold">Decision logic</Text>
|
|
41
|
+
<CodeBlock code={JSON.stringify($config.decisionLogic, null, 2)} />
|
|
39
42
|
</div>
|
|
40
|
-
</
|
|
41
|
-
|
|
42
|
-
<style>
|
|
43
|
-
.container {
|
|
44
|
-
padding: 0.5em;
|
|
45
|
-
}
|
|
46
|
-
</style>
|
|
43
|
+
</Stack>
|