@picked/svelte 0.0.1-dev.1793776638554 → 0.0.1-dev.1793923852884
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/.tsbuildinfo +1 -1
- package/dist/experience/set-picked-context.js +1 -1
- package/dist/plugins/devtools/DevToolsExperience.svelte +155 -80
- package/dist/plugins/devtools/customTools.d.ts +2 -2
- package/dist/plugins/devtools/derive/answer-display/answer-display.d.ts +14 -0
- package/dist/plugins/devtools/derive/answer-display/answer-display.js +1 -1
- package/dist/plugins/devtools/derive/answer-display/index.d.ts +2 -2
- package/dist/plugins/devtools/derive/answer-display/index.js +1 -1
- package/dist/plugins/devtools/derive/guide-sections/guide-sections.js +1 -1
- package/dist/plugins/devtools/derive/index.d.ts +5 -5
- package/dist/plugins/devtools/derive/index.js +1 -1
- package/dist/plugins/devtools/derive/personas/index.d.ts +2 -2
- package/dist/plugins/devtools/derive/personas/index.js +1 -1
- package/dist/plugins/devtools/derive/personas/personas.d.ts +88 -7
- package/dist/plugins/devtools/derive/personas/personas.js +1 -1
- package/dist/plugins/devtools/derive/plain-language/index.d.ts +1 -1
- package/dist/plugins/devtools/derive/plain-language/index.js +1 -1
- package/dist/plugins/devtools/derive/plain-language/plain-language.d.ts +5 -5
- package/dist/plugins/devtools/derive/plain-language/plain-language.js +1 -1
- package/dist/plugins/devtools/index.d.ts +1 -1
- package/dist/plugins/devtools/launcher/Launcher.svelte +13 -4
- package/dist/plugins/devtools/options.d.ts +6 -4
- package/dist/plugins/devtools/options.js +1 -1
- package/dist/plugins/devtools/review/journey/ExperienceDetails.svelte +129 -0
- package/dist/plugins/devtools/review/journey/JourneyPanel.svelte +54 -8
- package/dist/plugins/devtools/review/personas/ChoiceButton.svelte +40 -6
- package/dist/plugins/devtools/review/personas/PersonaBuilder.svelte +69 -45
- package/dist/plugins/devtools/review/personas/PersonaCard.svelte +226 -43
- package/dist/plugins/devtools/review/personas/PersonasPanel.svelte +171 -74
- package/dist/plugins/devtools/review/personas/load-persona.d.ts +41 -20
- package/dist/plugins/devtools/review/personas/load-persona.js +1 -1
- package/dist/plugins/devtools/review/personas/persona-route.d.ts +87 -0
- package/dist/plugins/devtools/review/personas/persona-route.js +1 -0
- package/dist/plugins/devtools/review/personas/persona-session.d.ts +94 -0
- package/dist/plugins/devtools/review/personas/persona-session.js +1 -0
- package/dist/plugins/devtools/sidebar/Sidebar.svelte +14 -48
- package/dist/plugins/devtools/sidebar/SidebarRow.svelte +2 -2
- package/dist/plugins/devtools/sidebar/nav.d.ts +26 -39
- package/dist/plugins/devtools/sidebar/nav.js +1 -1
- package/package.json +2 -2
- package/dist/plugins/devtools/screens/experience-instances/ExperienceInstancesListScreen.svelte +0 -10
- package/dist/plugins/devtools/screens/experiences/ExperienceDetailsScreen.svelte +0 -44
- package/dist/plugins/devtools/screens/experiences/ExperienceExperienceInstancesListScreen.svelte +0 -13
- package/dist/plugins/devtools/screens/experiences/ExperienceScreen.svelte +0 -32
- package/dist/plugins/devtools/screens/experiences/ExperienceTreeScreen.svelte +0 -500
- package/dist/plugins/devtools/screens/experiences/ExperiencesListScreen.svelte +0 -22
- package/dist/plugins/devtools/screens/features/FeaturesListScreen.svelte +0 -239
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +0 -286
- package/dist/plugins/devtools/screens/responses/ResponsesListScreen.svelte +0 -12
- package/dist/plugins/devtools/screens/responses/ResponsesTable.svelte +0 -88
|
@@ -18,16 +18,14 @@
|
|
|
18
18
|
import Sidebar from './sidebar/Sidebar.svelte'
|
|
19
19
|
import SidebarFooter from './sidebar/SidebarFooter.svelte'
|
|
20
20
|
import {
|
|
21
|
-
|
|
21
|
+
ADVANCED_OPEN_STORAGE_KEY,
|
|
22
22
|
CUSTOM_TOOLS_TAB,
|
|
23
|
-
DEVELOPER_OPEN_STORAGE_KEY,
|
|
24
23
|
TAB_STORAGE_KEY,
|
|
25
24
|
buildNav,
|
|
26
|
-
|
|
27
|
-
isInCustomTools,
|
|
28
|
-
isInDeveloper,
|
|
25
|
+
isInAdvanced,
|
|
29
26
|
readStored,
|
|
30
27
|
resolveTab,
|
|
28
|
+
screenTabId,
|
|
31
29
|
toolTabId,
|
|
32
30
|
writeStored,
|
|
33
31
|
} from './sidebar/nav'
|
|
@@ -46,6 +44,7 @@
|
|
|
46
44
|
TAB_INTROS,
|
|
47
45
|
configSourceLabel,
|
|
48
46
|
derivePosture,
|
|
47
|
+
applyEdits,
|
|
49
48
|
guideFixes,
|
|
50
49
|
guideSections,
|
|
51
50
|
readSavedPersonas,
|
|
@@ -62,26 +61,31 @@
|
|
|
62
61
|
VariationsPanel,
|
|
63
62
|
} from './review'
|
|
64
63
|
import {
|
|
64
|
+
openPersonaJourney,
|
|
65
65
|
screenQuestions,
|
|
66
66
|
takePendingLoad,
|
|
67
67
|
walkNotice,
|
|
68
68
|
walkPersona,
|
|
69
|
+
type PendingLoad,
|
|
69
70
|
type WalkSettings,
|
|
70
71
|
} from './review/personas/load-persona'
|
|
72
|
+
import {
|
|
73
|
+
prefillPersona,
|
|
74
|
+
readActivePersona,
|
|
75
|
+
takePersonaLink,
|
|
76
|
+
writeActivePersona,
|
|
77
|
+
type Prefill,
|
|
78
|
+
} from './review/personas/persona-session'
|
|
71
79
|
import ProjectScreen from './screens/project/ProjectScreen.svelte'
|
|
72
80
|
import ComponentsListScreen from './screens/components/ComponentsListScreen.svelte'
|
|
73
81
|
import ConfigScreen from './screens/config/ConfigScreen.svelte'
|
|
74
82
|
import ContentListScreen from './screens/content/ContentListScreen.svelte'
|
|
75
83
|
import EventsListScreen from './screens/events/EventsListScreen.svelte'
|
|
76
|
-
import ExperienceInstancesListScreen from './screens/experience-instances/ExperienceInstancesListScreen.svelte'
|
|
77
|
-
import ExperiencesListScreen from './screens/experiences/ExperiencesListScreen.svelte'
|
|
78
|
-
import FeaturesListScreen from './screens/features/FeaturesListScreen.svelte'
|
|
79
84
|
import FieldsListScreen from './screens/fields/FieldsListScreen.svelte'
|
|
80
85
|
import FrameworksListScreen from './screens/frameworks/FrameworksListScreen.svelte'
|
|
81
86
|
import HistoryEntriesListScreen from './screens/history/HistoryEntriesListScreen.svelte'
|
|
82
87
|
import IdentityScreen from './screens/identity/IdentityScreen.svelte'
|
|
83
88
|
import PredicatesListScreen from './screens/predicates/PredicatesListScreen.svelte'
|
|
84
|
-
import ResponsesListScreen from './screens/responses/ResponsesListScreen.svelte'
|
|
85
89
|
import CustomToolsScreen from './screens/custom-tools/CustomToolsScreen.svelte'
|
|
86
90
|
|
|
87
91
|
const experience = getExperience()
|
|
@@ -118,22 +122,18 @@
|
|
|
118
122
|
const sessionStorageOf = (): Storage => window.sessionStorage
|
|
119
123
|
const localStorageOf = (): Storage => window.localStorage
|
|
120
124
|
|
|
121
|
-
/** The
|
|
122
|
-
const
|
|
123
|
-
[
|
|
124
|
-
[
|
|
125
|
-
[
|
|
126
|
-
[
|
|
127
|
-
[
|
|
128
|
-
[
|
|
129
|
-
[
|
|
130
|
-
[
|
|
131
|
-
[
|
|
132
|
-
[
|
|
133
|
-
[developerTabId('history')]: HistoryEntriesListScreen,
|
|
134
|
-
[developerTabId('identity')]: IdentityScreen,
|
|
135
|
-
[developerTabId('predicates')]: PredicatesListScreen,
|
|
136
|
-
[developerTabId('responses')]: ResponsesListScreen,
|
|
125
|
+
/** The SDK's own screens, keyed by their sidebar id. */
|
|
126
|
+
const SCREEN_COMPONENTS: Record<string, Component> = {
|
|
127
|
+
[screenTabId('project')]: ProjectScreen,
|
|
128
|
+
[screenTabId('components')]: ComponentsListScreen,
|
|
129
|
+
[screenTabId('config')]: ConfigScreen,
|
|
130
|
+
[screenTabId('content')]: ContentListScreen,
|
|
131
|
+
[screenTabId('events')]: EventsListScreen,
|
|
132
|
+
[screenTabId('fields')]: FieldsListScreen,
|
|
133
|
+
[screenTabId('frameworks')]: FrameworksListScreen,
|
|
134
|
+
[screenTabId('history')]: HistoryEntriesListScreen,
|
|
135
|
+
[screenTabId('identity')]: IdentityScreen,
|
|
136
|
+
[screenTabId('predicates')]: PredicatesListScreen,
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
// ── The session record ───────────────────────────────────────────────────────────────────────
|
|
@@ -169,26 +169,24 @@
|
|
|
169
169
|
)
|
|
170
170
|
const storedTab = readStored(sessionStorageOf, TAB_STORAGE_KEY)
|
|
171
171
|
let tab = $state(storedTab ?? 'guide')
|
|
172
|
-
let
|
|
173
|
-
let customOpen = $state(readStored(sessionStorageOf, CUSTOM_TOOLS_OPEN_STORAGE_KEY) !== 'false')
|
|
172
|
+
let advancedOpen = $state(readStored(sessionStorageOf, ADVANCED_OPEN_STORAGE_KEY) === 'true')
|
|
174
173
|
let drawerOpen = $state(false)
|
|
175
174
|
|
|
176
175
|
// A tab can disappear under the viewer (Feature flags once the feature list is empty), and a
|
|
177
|
-
// stored
|
|
176
|
+
// stored Advanced screen opens its group.
|
|
178
177
|
$effect(() => {
|
|
179
178
|
const resolved = resolveTab(tab, nav)
|
|
180
179
|
if (resolved !== tab) tab = resolved
|
|
181
|
-
if (
|
|
182
|
-
if (isInCustomTools(tab, nav) && !customOpen) customOpen = true
|
|
180
|
+
if (isInAdvanced(tab, nav) && !advancedOpen) advancedOpen = true
|
|
183
181
|
})
|
|
184
182
|
|
|
185
183
|
const selectedItem = $derived(
|
|
186
|
-
[...nav.primary, ...nav.
|
|
184
|
+
[...nav.primary, ...nav.advanced, ...nav.footer].find((item) => item.id === tab),
|
|
187
185
|
)
|
|
188
186
|
const selectedTool = $derived(
|
|
189
187
|
[...tools, ...customTools, ...footer].find((tool) => toolTabId(tool.id) === tab),
|
|
190
188
|
)
|
|
191
|
-
const
|
|
189
|
+
const sdkScreen = $derived(SCREEN_COMPONENTS[tab])
|
|
192
190
|
|
|
193
191
|
/**
|
|
194
192
|
* Narrows a tab id to one of the review tabs.
|
|
@@ -214,23 +212,13 @@
|
|
|
214
212
|
}
|
|
215
213
|
|
|
216
214
|
/**
|
|
217
|
-
* Opens or folds the
|
|
215
|
+
* Opens or folds the Advanced group, and remembers it.
|
|
218
216
|
*
|
|
219
|
-
* @example
|
|
217
|
+
* @example toggleAdvanced()
|
|
220
218
|
*/
|
|
221
|
-
function
|
|
222
|
-
|
|
223
|
-
writeStored(sessionStorageOf,
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Opens or folds the Developer group, and remembers it.
|
|
228
|
-
*
|
|
229
|
-
* @example toggleDeveloper()
|
|
230
|
-
*/
|
|
231
|
-
function toggleDeveloper(): void {
|
|
232
|
-
developerOpen = !developerOpen
|
|
233
|
-
writeStored(sessionStorageOf, DEVELOPER_OPEN_STORAGE_KEY, String(developerOpen))
|
|
219
|
+
function toggleAdvanced(): void {
|
|
220
|
+
advancedOpen = !advancedOpen
|
|
221
|
+
writeStored(sessionStorageOf, ADVANCED_OPEN_STORAGE_KEY, String(advancedOpen))
|
|
234
222
|
}
|
|
235
223
|
|
|
236
224
|
// ── How to use ───────────────────────────────────────────────────────────────────────────────
|
|
@@ -262,7 +250,7 @@
|
|
|
262
250
|
sections: guideSections(available, { lead, tools: toolSections }),
|
|
263
251
|
fixes: guideFixes(available, options.guide.fixes),
|
|
264
252
|
tabLabels: Object.fromEntries(
|
|
265
|
-
[...nav.primary, ...nav.
|
|
253
|
+
[...nav.primary, ...nav.footer].map((item) => [item.id, item.label]),
|
|
266
254
|
),
|
|
267
255
|
}
|
|
268
256
|
})
|
|
@@ -285,14 +273,22 @@
|
|
|
285
273
|
writeAutoHide(localStorageOf, value)
|
|
286
274
|
}
|
|
287
275
|
|
|
288
|
-
// ── A persona
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
//
|
|
276
|
+
// ── A persona session, carried across reloads ──────────────────────────────────────────────
|
|
277
|
+
// Walk through and Jump to step reload the page clean, so the session starts here, as the
|
|
278
|
+
// devtools mount on the new page, and again on every later page of the tab until Stop. Each
|
|
279
|
+
// start runs the persona's setup and pre-fills every step with its responses. A jump walks to
|
|
280
|
+
// its step first, with the panel shut so the reviewer watches the journey move, and opens on the
|
|
281
|
+
// Personas tab when the walk stops short. A shared link starts a walk-through on the page it
|
|
282
|
+
// opens.
|
|
292
283
|
let personaWalkNotice = $state<{
|
|
293
284
|
status: 'info' | 'success' | 'warning' | 'error'
|
|
294
285
|
text: string
|
|
295
286
|
} | null>(null)
|
|
287
|
+
/** The site's personas, once the option has loaded them. */
|
|
288
|
+
let sitePersonaList = $state.raw<Persona[]>([])
|
|
289
|
+
/** The persona this tab walks through as. */
|
|
290
|
+
let activePersona = $state.raw<Persona | null>(null)
|
|
291
|
+
let prefill: Prefill | null = null
|
|
296
292
|
|
|
297
293
|
const walkSettings: WalkSettings = {
|
|
298
294
|
exclude: options.hiddenExperienceKeys,
|
|
@@ -304,30 +300,108 @@
|
|
|
304
300
|
}
|
|
305
301
|
|
|
306
302
|
/**
|
|
307
|
-
*
|
|
303
|
+
* A persona by id, among the site's as this browser edited them and this browser's own.
|
|
304
|
+
*
|
|
305
|
+
* @param {string} id - The persona's id.
|
|
306
|
+
* @param {readonly Persona[]} site - The site's personas.
|
|
307
|
+
* @returns {Persona | undefined} The persona, or `undefined` when none has the id.
|
|
308
|
+
* @example findPersona('mover', sitePersonaList)
|
|
309
|
+
*/
|
|
310
|
+
function findPersona(id: string, site: readonly Persona[]): Persona | undefined {
|
|
311
|
+
const listed = applyEdits(site, readSavedPersonas(localStorageOf, client.projectId))
|
|
312
|
+
return [...listed.site, ...listed.own].find((persona) => persona.id === id)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Walks a jump to its step, then says how it went, opening the panel when it stopped short.
|
|
317
|
+
*
|
|
318
|
+
* @param {Persona} persona - The persona.
|
|
319
|
+
* @param {PendingLoad} pending - The jump.
|
|
320
|
+
* @returns {Promise<void>} Settles once the walk ends.
|
|
321
|
+
* @example await jump(persona, pending)
|
|
322
|
+
*/
|
|
323
|
+
async function jump(persona: Persona, pending: PendingLoad): Promise<void> {
|
|
324
|
+
const stepName = pending.stop?.stepName ?? pending.stop?.stepKey ?? ''
|
|
325
|
+
personaWalkNotice = { status: 'info', text: `Jumping to “${stepName}” as ${persona.name}…` }
|
|
326
|
+
const outcome = await walkPersona(
|
|
327
|
+
client,
|
|
328
|
+
{ ...persona, landing: pending.stop, passed: pending.passed },
|
|
329
|
+
walkSettings,
|
|
330
|
+
)
|
|
331
|
+
const notice = walkNotice(persona, outcome)
|
|
332
|
+
personaWalkNotice = notice
|
|
333
|
+
if (notice.status === 'success') return
|
|
334
|
+
selectTab('personas')
|
|
335
|
+
experience.open()
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Starts or resumes this tab's persona session: a reload's start, a shared link, or the session
|
|
340
|
+
* a reload carried on.
|
|
308
341
|
*
|
|
309
|
-
* @returns {
|
|
310
|
-
* @example
|
|
342
|
+
* @returns {Promise<void>} Settles once the persona is set up and any jump has walked.
|
|
343
|
+
* @example await startPersonaSession()
|
|
311
344
|
*/
|
|
312
|
-
function
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const walking = pendingPersona()
|
|
320
|
-
if (walking !== undefined) {
|
|
321
|
-
personaWalkNotice = { status: 'info', text: `Loading ${walking.name}…` }
|
|
322
|
-
void walkPersona(client, walking, walkSettings).then((outcome) => {
|
|
323
|
-
const notice = walkNotice(walking, outcome)
|
|
324
|
-
personaWalkNotice = notice
|
|
325
|
-
if (notice.status === 'success') return
|
|
326
|
-
selectTab('personas')
|
|
327
|
-
experience.open()
|
|
345
|
+
async function startPersonaSession(): Promise<void> {
|
|
346
|
+
const storage = sessionStorageOf()
|
|
347
|
+
const pending = takePendingLoad(storage)
|
|
348
|
+
const linked = takePersonaLink(window.location, (url) => {
|
|
349
|
+
window.history.replaceState(window.history.state, '', url)
|
|
328
350
|
})
|
|
351
|
+
const site = await options.personas()
|
|
352
|
+
sitePersonaList = site
|
|
353
|
+
const id = pending?.id ?? linked ?? readActivePersona(storage)
|
|
354
|
+
if (id === null || !posture.canEditAnswers) return
|
|
355
|
+
const persona = findPersona(id, site)
|
|
356
|
+
if (persona === undefined || (pending === null && linked !== null && persona.source !== 'site')) {
|
|
357
|
+
writeActivePersona(storage, null)
|
|
358
|
+
return
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
writeActivePersona(storage, persona.id)
|
|
362
|
+
activePersona = persona
|
|
363
|
+
try {
|
|
364
|
+
await persona.setup?.(client)
|
|
365
|
+
} catch (error) {
|
|
366
|
+
const detail = error instanceof Error ? ` ${error.message}` : ''
|
|
367
|
+
personaWalkNotice = { status: 'error', text: `${persona.name}’s setup failed.${detail}` }
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
prefill = prefillPersona(
|
|
371
|
+
client,
|
|
372
|
+
{ ...persona.responses, ...options.personaWalk.responses },
|
|
373
|
+
session.askedStore,
|
|
374
|
+
)
|
|
375
|
+
if (pending?.stop != null) await jump(persona, pending)
|
|
376
|
+
else if (pending !== null || linked !== null) {
|
|
377
|
+
await openPersonaJourney(client, persona, walkSettings)
|
|
378
|
+
}
|
|
329
379
|
}
|
|
330
380
|
|
|
381
|
+
/**
|
|
382
|
+
* Ends this tab's persona session: every field gets its own default back.
|
|
383
|
+
*
|
|
384
|
+
* @example stopPersonaSession()
|
|
385
|
+
*/
|
|
386
|
+
function stopPersonaSession(): void {
|
|
387
|
+
prefill?.stop()
|
|
388
|
+
prefill = null
|
|
389
|
+
writeActivePersona(sessionStorageOf(), null)
|
|
390
|
+
if (activePersona !== null) {
|
|
391
|
+
personaWalkNotice = {
|
|
392
|
+
status: 'success',
|
|
393
|
+
text: `Stopped walking through as ${activePersona.name}. Fields already filled in keep their values.`,
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
activePersona = null
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
void startPersonaSession()
|
|
401
|
+
$effect(() => () => {
|
|
402
|
+
prefill?.stop()
|
|
403
|
+
})
|
|
404
|
+
|
|
331
405
|
// ── Dialog behaviour ─────────────────────────────────────────────────────────────────────────
|
|
332
406
|
/** The open panel; Svelte sets it back to `null` when the panel unmounts. */
|
|
333
407
|
let panel: HTMLDivElement | null = $state(null)
|
|
@@ -456,11 +530,9 @@
|
|
|
456
530
|
<Sidebar
|
|
457
531
|
{nav}
|
|
458
532
|
selected={tab}
|
|
459
|
-
{
|
|
460
|
-
{customOpen}
|
|
533
|
+
{advancedOpen}
|
|
461
534
|
onSelect={selectTab}
|
|
462
|
-
|
|
463
|
-
onToggleCustom={toggleCustom}
|
|
535
|
+
onToggleAdvanced={toggleAdvanced}
|
|
464
536
|
/>
|
|
465
537
|
<SidebarFooter
|
|
466
538
|
tools={nav.footer}
|
|
@@ -472,9 +544,9 @@
|
|
|
472
544
|
</div>
|
|
473
545
|
|
|
474
546
|
<section class="pane" aria-label={selectedItem?.label} data-testid="devtools-pane">
|
|
475
|
-
{#if
|
|
476
|
-
{@const Screen =
|
|
477
|
-
<div class="
|
|
547
|
+
{#if sdkScreen}
|
|
548
|
+
{@const Screen = sdkScreen}
|
|
549
|
+
<div class="screen-body">
|
|
478
550
|
<Screen />
|
|
479
551
|
</div>
|
|
480
552
|
{:else if tab === CUSTOM_TOOLS_TAB}
|
|
@@ -533,13 +605,15 @@
|
|
|
533
605
|
{client}
|
|
534
606
|
{posture}
|
|
535
607
|
journey={$journey}
|
|
536
|
-
personas={
|
|
608
|
+
personas={sitePersonaList}
|
|
537
609
|
asked={$asked}
|
|
538
610
|
route={$route}
|
|
539
611
|
hiddenKeys={options.hiddenExperienceKeys}
|
|
540
612
|
codeOwned={options.codeOwnedFields}
|
|
541
613
|
personaWalk={options.personaWalk}
|
|
542
614
|
tools={personaTools}
|
|
615
|
+
{activePersona}
|
|
616
|
+
onStop={stopPersonaSession}
|
|
543
617
|
walkNotice={personaWalkNotice}
|
|
544
618
|
onWalkNoticeDismiss={() => (personaWalkNotice = null)}
|
|
545
619
|
/>
|
|
@@ -557,6 +631,7 @@
|
|
|
557
631
|
position={options.launcher.position}
|
|
558
632
|
{autoHide}
|
|
559
633
|
{preview}
|
|
634
|
+
walkingAs={activePersona?.name ?? null}
|
|
560
635
|
onOpen={() => experience.open()}
|
|
561
636
|
/>
|
|
562
637
|
{/if}
|
|
@@ -824,7 +899,7 @@
|
|
|
824
899
|
display: grid;
|
|
825
900
|
}
|
|
826
901
|
|
|
827
|
-
.
|
|
902
|
+
.screen-body {
|
|
828
903
|
flex: 1 1 auto;
|
|
829
904
|
display: grid;
|
|
830
905
|
min-height: 0;
|
|
@@ -28,7 +28,7 @@ export interface CustomTool {
|
|
|
28
28
|
* `'review'` lists the tool as a tab of its own, beside the review tabs. `'personas'` shows it
|
|
29
29
|
* as a section of the Personas & Scenarios tab, under its label. `'footer'` shows it as an icon
|
|
30
30
|
* at the foot of the sidebar, beside the auto-hide switch, with its label as a tooltip.
|
|
31
|
-
* `'developer'` lists it as a row of its own
|
|
31
|
+
* `'developer'` lists it as a top-level row of its own, after the review-placed tools.
|
|
32
32
|
*
|
|
33
33
|
* @default 'developer'
|
|
34
34
|
*/
|
|
@@ -82,7 +82,7 @@ export declare function personasTools(tools: readonly CustomTool[]): CustomTool[
|
|
|
82
82
|
*/
|
|
83
83
|
export declare function footerTools(tools: readonly CustomTool[]): CustomTool[];
|
|
84
84
|
/**
|
|
85
|
-
* The tools listed
|
|
85
|
+
* The tools listed as top-level rows after the review-placed tools.
|
|
86
86
|
*
|
|
87
87
|
* @param {readonly CustomTool[]} tools - The registered tools.
|
|
88
88
|
* @returns {CustomTool[]} The unplaced tools and those placed `'developer'`, in registration order.
|
|
@@ -53,6 +53,20 @@ export declare function questionOf(field: AnswerField): string;
|
|
|
53
53
|
* kindOf({ key: 'quote', type: 'object', multiple: false }) // 'system'
|
|
54
54
|
*/
|
|
55
55
|
export declare function kindOf(field: AnswerField): AnswerKind;
|
|
56
|
+
/** How a question is drawn for a reviewer to answer, as a site draws it from the same config. */
|
|
57
|
+
export type InputStyle = 'tiles' | 'pills' | 'checkboxes' | 'yes-no' | 'number' | 'text' | 'system';
|
|
58
|
+
/**
|
|
59
|
+
* How a question is drawn, from its field's config alone: a single choice of up to eight options
|
|
60
|
+
* as tiles and of more as pills, a multiple choice as checkboxes, a yes-or-no question as two
|
|
61
|
+
* tiles, and anything else as its own input.
|
|
62
|
+
*
|
|
63
|
+
* @param {AnswerField} field - The field.
|
|
64
|
+
* @param {number} offered - How many of its options the step offers.
|
|
65
|
+
* @returns {InputStyle} The style to draw it in.
|
|
66
|
+
* @example
|
|
67
|
+
* inputStyleOf(coverLevel, 3) // 'tiles'
|
|
68
|
+
*/
|
|
69
|
+
export declare function inputStyleOf(field: AnswerField, offered: number): InputStyle;
|
|
56
70
|
/**
|
|
57
71
|
* Renders an answer for display. An object value is summarised rather than dumped; the panel
|
|
58
72
|
* offers Copy for the reviewer who wants the payload.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{deslug as e}from"../plain-language/plain-language.js";var t=`No response yet`,n=`Set on its step`;function r(t){let n=t.name?.trim();return n!==void 0&&n.length>0?n:e(t.key)}function i(e){let t=e.label?.trim();return t!==void 0&&t.length>0?t:r(e)}function a(e){return e.type===`object`?`system`:e.options!==null&&e.options!==void 0&&e.options.length>0?`options`:e.type===`boolean`?`boolean`:e.type===`number`?`number`:`text`}function o(e,n){let r=n.options?.find(t=>t.value===e);return r===void 0?e===!0?`Yes`:e===!1?`No`:e===null?t:typeof e==`string`?e:typeof e==`number`?String(e):JSON.stringify(e):r.label}function
|
|
1
|
+
import{deslug as e}from"../plain-language/plain-language.js";var t=`No response yet`,n=`Set on its step`;function r(t){let n=t.name?.trim();return n!==void 0&&n.length>0?n:e(t.key)}function i(e){let t=e.label?.trim();return t!==void 0&&t.length>0?t:r(e)}function a(e){return e.type===`object`?`system`:e.options!==null&&e.options!==void 0&&e.options.length>0?`options`:e.type===`boolean`?`boolean`:e.type===`number`?`number`:`text`}var o=8;function s(e,t){let n=a(e);return n===`options`?e.multiple?`checkboxes`:t<=o?`tiles`:`pills`:n===`boolean`?`yes-no`:n}function c(e,n){let r=n.options?.find(t=>t.value===e);return r===void 0?e===!0?`Yes`:e===!1?`No`:e===null?t:typeof e==`string`?e:typeof e==`number`?String(e):JSON.stringify(e):r.label}function l(e,t){return e==null||e===``?null:Array.isArray(e)?e.length===0?null:e.map(e=>c(e,t)).join(`, `):a(t)===`system`?n:c(e,t)}function u(e,t){let n=a(t),o=l(e,t);return{title:i(t),noun:r(t),kind:n,display:o,answered:o!==null,editable:n!==`system`}}function d(e,t,n=new Set){let r=new Set;for(let e of t)for(let t of e)t.type===`step`&&t.stepId!==void 0&&r.add(t.stepId);let i=new Set;for(let t of e)if(r.has(t.id))for(let e of t.fieldKeys)n.has(e)||i.add(e);return i}function f(e){return e===void 0?``:JSON.stringify(e,null,2)}export{d as askedFieldKeys,u as describeAnswer,s as inputStyleOf,a as kindOf,r as nounOf,i as questionOf,l as renderAnswer,f as systemPayload};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** @file Public entrypoint for how an answer is shown to a reviewer and whether it is editable. */
|
|
2
|
-
export { askedFieldKeys, describeAnswer, kindOf, nounOf, questionOf, renderAnswer, systemPayload, } from './answer-display';
|
|
3
|
-
export type { AnswerField, AnswerKind, AnswerView, AskedNode, AskedStep } from './answer-display';
|
|
2
|
+
export { askedFieldKeys, describeAnswer, inputStyleOf, kindOf, nounOf, questionOf, renderAnswer, systemPayload, } from './answer-display';
|
|
3
|
+
export type { AnswerField, AnswerKind, AnswerView, AskedNode, AskedStep, InputStyle, } from './answer-display';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{askedFieldKeys,describeAnswer,kindOf,nounOf,questionOf,renderAnswer,systemPayload}from"./answer-display.js";
|
|
1
|
+
export{askedFieldKeys,describeAnswer,inputStyleOf,kindOf,nounOf,questionOf,renderAnswer,systemPayload}from"./answer-display.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=[{id:`session`,title:`See where you are`,steps:[],notes:[`To see the step you are on and every response so far, open **This session**.`],tab:`session`},{id:`answers`,title:`Change a response`,steps:[`Open **Responses**.`,`Find the field. Use **With a response**, **No response** or **All** to narrow the list.`,`Click **Change**, or **Add** if it has no response yet.`,`Pick or type the new response, then click **Save**.`],notes:[`To remove one response, click **Clear** beside it.`,`To start the whole experience again, click **Start over**, then **Clear everything**.`,`If a field says **Change it on its step**, go back to that step and change it there.`],tab:`answers`},{id:`journey`,title:`Go back to an earlier step`,steps:[`Open **
|
|
1
|
+
var e=[{id:`session`,title:`See where you are`,steps:[],notes:[`To see the step you are on and every response so far, open **This session**.`],tab:`session`},{id:`answers`,title:`Change a response`,steps:[`Open **Responses**.`,`Find the field. Use **With a response**, **No response** or **All** to narrow the list.`,`Click **Change**, or **Add** if it has no response yet.`,`Pick or type the new response, then click **Save**.`],notes:[`To remove one response, click **Clear** beside it.`,`To start the whole experience again, click **Start over**, then **Clear everything**.`,`If a field says **Change it on its step**, go back to that step and change it there.`],tab:`answers`},{id:`journey`,title:`Go back to an earlier step`,steps:[`Open **Experiences**.`,`Find a step on your route. Your route is blue, and your step says **You are here**.`,`Click the step, then click **Go back to this step**.`],notes:[`You can only go back to steps you have already visited.`,`To change how the flow is drawn, pick **Map**, **Timeline** or **Outline** at the top.`,`To see where an experience shows and when it starts, pick **Details**.`,`To open an experience that is not on the page, pick it, then click **Launch experience**.`],tab:`journey`},{id:`personas`,title:`Try the experience as a visitor`,steps:[`Open **Personas & Scenarios**.`,`Click **Walk through** beside the visitor you want. The page starts again.`,`Go through the experience. Each step shows their responses. Click **Continue**, or change a response first.`,`When you are done, click **Stop** at the top of the tab.`],notes:[`To start further in, click **Jump to step**, then pick the step.`,`To change a persona, click **Edit**. Your change stays in this browser only.`,`To keep where you are for later, click **Create**, give it a name, then click **Save**.`,`To send a site persona to someone else, click its copy icon and share the link.`],tab:`personas`},{id:`variations`,title:`View a feature flag variant`,steps:[`Open **Feature flags**.`,`Find the feature flag and pick the variant you want.`,`Click **Show me this variant**. The page reloads showing it.`,`To share exactly what you saw, click **Copy link** and send it.`],notes:[`To go back to normal for that feature flag, click **Leave this one alone**.`],tab:`variations`}],t=[{tab:`journey`,entry:{problem:`I can't click a step in the Experiences tab`,fix:`Go back only to steps you have visited.`}}];function n(e,t){return e!==`variations`||t.variations}function r(t,r){return[...r?.lead??[],...e.filter(e=>n(e.tab,t)),...r?.tools??[]]}function i(e,r){return[...t.filter(t=>n(t.tab,e)).map(e=>e.entry),...r??[]]}function a(e){let t=e.split(`**`);return t.length%2==0?[{text:e,bold:!1}]:t.map((e,t)=>({text:e,bold:t%2==1})).filter(e=>e.text.length>0)}export{a as emphasis,i as guideFixes,r as guideSections};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @file Public entrypoint for the review tools' pure derivations. Every panel stays thin by pushing
|
|
3
3
|
* its thinking here, where it is tested off plain objects with no client, no DOM and no store.
|
|
4
4
|
*/
|
|
5
|
-
export { askedFieldKeys, describeAnswer, kindOf, nounOf, questionOf, renderAnswer, systemPayload, } from './answer-display';
|
|
6
|
-
export type { AnswerField, AnswerKind, AnswerView, AskedNode, AskedStep } from './answer-display';
|
|
5
|
+
export { askedFieldKeys, describeAnswer, inputStyleOf, kindOf, nounOf, questionOf, renderAnswer, systemPayload, } from './answer-display';
|
|
6
|
+
export type { AnswerField, AnswerKind, AnswerView, AskedNode, AskedStep, InputStyle, } from './answer-display';
|
|
7
7
|
export { isBlank, nextHistory, submittedAnswers } from './answer-history';
|
|
8
8
|
export type { HistoryAnswer, HistoryEntry, HistoryEvent } from './answer-history';
|
|
9
9
|
export { emphasis, guideFixes, guideSections } from './guide-sections';
|
|
@@ -16,12 +16,12 @@ export { COLOURS, LANE_WIDTH, ROW_HEIGHT, buildTimeline } from './journey-timeli
|
|
|
16
16
|
export type { TimelineEdge, TimelineLayout, TimelineNext, TimelineNode } from './journey-timeline';
|
|
17
17
|
export { BREADTH, DEPTH, buildTree } from './journey-tree';
|
|
18
18
|
export type { FlowEnd, TreeInput, TreeJump, TreeLayout, TreeLink, TreeNode, TreeNodeKind, } from './journey-tree';
|
|
19
|
-
export {
|
|
19
|
+
export { NODE_LABELS, TAB_INTROS, ADVANCED_LABEL, TAB_LABELS, configSourceLabel, deslug, screenName, } from './plain-language';
|
|
20
20
|
export type { ReviewTabId } from './plain-language';
|
|
21
21
|
export { builderGraph, responseKeysOf, walkDraft } from './persona-builder';
|
|
22
22
|
export type { BuilderCondition, BuilderEdge, BuilderField, BuilderInput, BuilderJourney, BuilderNode, BuilderRow, BuilderStep, BuilderWalk, GraphSource, } from './persona-builder';
|
|
23
|
-
export { PERSONA_STORAGE_PREFIX, buildPersona, customerAnswers, describeLanding, entryUrlOf, passedScreens, personaStorageKey, readAnswers, readEntryUrl, readSavedPersonas, sitePersonas, writeSavedPersonas, } from './personas';
|
|
24
|
-
export type { BuildPersonaResult, Persona, PersonaCapture, PersonaDefinition, PersonaDraft,
|
|
23
|
+
export { PERSONA_STORAGE_PREFIX, applyEdits, buildPersona, customerAnswers, describeLanding, entryUrlOf, groupPersonas, matchesSearch, passedScreens, personaStorageKey, readAnswers, readEntryUrl, readLanding, readPassed, readSavedPersonas, sitePersonas, startOf, writeSavedPersonas, } from './personas';
|
|
24
|
+
export type { BuildPersonaResult, EditedPersonas, Persona, PersonaCapture, PersonaDefinition, PersonaDraft, PersonaGroup, PersonaLanding, PersonaScreen, PersonaSetup, PersonaSource, PersonaStorageGetter, } from './personas';
|
|
25
25
|
export { UNDESCRIBABLE, describeRule, varKeyOf } from './plain-logic';
|
|
26
26
|
export type { FieldLookup, FieldSummary } from './plain-logic';
|
|
27
27
|
export { derivePosture } from './safety-posture';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isBlank as e,nextHistory as t,submittedAnswers as n}from"./answer-history/answer-history.js";import{
|
|
1
|
+
import{isBlank as e,nextHistory as t,submittedAnswers as n}from"./answer-history/answer-history.js";import{ADVANCED_LABEL as r,NODE_LABELS as i,TAB_INTROS as a,TAB_LABELS as o,configSourceLabel as s,deslug as c,screenName as l}from"./plain-language/plain-language.js";import{PERSONA_STORAGE_PREFIX as u,applyEdits as d,buildPersona as f,customerAnswers as p,describeLanding as m,entryUrlOf as h,groupPersonas as g,matchesSearch as _,passedScreens as v,personaStorageKey as y,readAnswers as b,readEntryUrl as x,readLanding as S,readPassed as C,readSavedPersonas as w,sitePersonas as T,startOf as E,writeSavedPersonas as D}from"./personas/personas.js";import{askedFieldKeys as O,describeAnswer as k,inputStyleOf as A,kindOf as j,nounOf as M,questionOf as N,renderAnswer as P,systemPayload as F}from"./answer-display/answer-display.js";import{emphasis as I,guideFixes as L,guideSections as R}from"./guide-sections/guide-sections.js";import{UNDESCRIBABLE as z,describeRule as B,varKeyOf as V}from"./plain-logic/plain-logic.js";import{buildOutline as H}from"./journey-outline/journey-outline.js";import{nextOpenOrder as U,pickJourney as W}from"./journey-pick/journey-pick.js";import{BREADTH as G,DEPTH as K,buildTree as q}from"./journey-tree/journey-tree.js";import"./journey-tree/index.js";import{COLOURS as J,LANE_WIDTH as Y,ROW_HEIGHT as X,buildTimeline as Z}from"./journey-timeline/journey-timeline.js";import"./journey-timeline/index.js";import{builderGraph as Q,responseKeysOf as $,walkDraft as ee}from"./persona-builder/persona-builder.js";import{derivePosture as te}from"./safety-posture/safety-posture.js";import{nextTrails as ne}from"./visited-steps/visited-steps.js";import{nextRoute as re}from"./walk-route/walk-route.js";export{r as ADVANCED_LABEL,G as BREADTH,J as COLOURS,K as DEPTH,Y as LANE_WIDTH,i as NODE_LABELS,u as PERSONA_STORAGE_PREFIX,X as ROW_HEIGHT,a as TAB_INTROS,o as TAB_LABELS,z as UNDESCRIBABLE,d as applyEdits,O as askedFieldKeys,H as buildOutline,f as buildPersona,Z as buildTimeline,q as buildTree,Q as builderGraph,s as configSourceLabel,p as customerAnswers,te as derivePosture,k as describeAnswer,m as describeLanding,B as describeRule,c as deslug,I as emphasis,h as entryUrlOf,g as groupPersonas,L as guideFixes,R as guideSections,A as inputStyleOf,e as isBlank,j as kindOf,_ as matchesSearch,t as nextHistory,U as nextOpenOrder,re as nextRoute,ne as nextTrails,M as nounOf,v as passedScreens,y as personaStorageKey,W as pickJourney,N as questionOf,b as readAnswers,x as readEntryUrl,S as readLanding,C as readPassed,w as readSavedPersonas,P as renderAnswer,$ as responseKeysOf,l as screenName,T as sitePersonas,E as startOf,n as submittedAnswers,F as systemPayload,V as varKeyOf,ee as walkDraft,D as writeSavedPersonas};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** @file Public entrypoint for personas: building, saving, reading and describing them. */
|
|
2
|
-
export { PERSONA_STORAGE_PREFIX, buildPersona, customerAnswers, describeLanding, entryUrlOf, passedScreens, personaStorageKey, readAnswers, readEntryUrl, readSavedPersonas, sitePersonas, writeSavedPersonas, } from './personas';
|
|
3
|
-
export type { BuildPersonaResult, Persona, PersonaCapture, PersonaDefinition, PersonaDraft,
|
|
2
|
+
export { PERSONA_STORAGE_PREFIX, applyEdits, buildPersona, customerAnswers, describeLanding, entryUrlOf, groupPersonas, matchesSearch, passedScreens, personaStorageKey, readAnswers, readEntryUrl, readLanding, readPassed, readSavedPersonas, sitePersonas, startOf, writeSavedPersonas, } from './personas';
|
|
3
|
+
export type { BuildPersonaResult, EditedPersonas, Persona, PersonaCapture, PersonaDefinition, PersonaDraft, PersonaGroup, PersonaLanding, PersonaScreen, PersonaSetup, PersonaSource, PersonaStorageGetter, } from './personas';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{PERSONA_STORAGE_PREFIX,buildPersona,customerAnswers,describeLanding,entryUrlOf,passedScreens,personaStorageKey,readAnswers,readEntryUrl,readSavedPersonas,sitePersonas,writeSavedPersonas}from"./personas.js";
|
|
1
|
+
export{PERSONA_STORAGE_PREFIX,applyEdits,buildPersona,customerAnswers,describeLanding,entryUrlOf,groupPersonas,matchesSearch,passedScreens,personaStorageKey,readAnswers,readEntryUrl,readLanding,readPassed,readSavedPersonas,sitePersonas,startOf,writeSavedPersonas}from"./personas.js";
|