@picked/svelte 0.0.1-dev.1773807602703 → 0.0.1-dev.1773878362211
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/form/create-form.js +1 -0
- package/dist/form/create-form.svelte.d.ts +24 -0
- package/dist/form/create-form.svelte.js +1 -0
- package/dist/form/get-form.d.ts +16 -0
- package/dist/form/get-form.js +1 -0
- package/dist/form/index.d.ts +2 -25
- package/dist/form/index.js +1 -1
- package/dist/hooks/field.d.ts +2 -3
- package/dist/hooks/field.js +1 -1
- package/dist/hooks/step.d.ts +8 -8
- package/dist/hooks/step.js +1 -1
- package/dist/plugins/devtools/components/ExperienceInstanceListItem.svelte +4 -17
- package/dist/plugins/devtools/components/ExperienceInstancesTable.svelte +1 -1
- package/dist/plugins/devtools/screens/events/EventListItem.svelte +47 -47
- package/dist/plugins/devtools/screens/experiences/ExperienceDetailsScreen.svelte +1 -1
- package/dist/plugins/devtools/screens/experiences/ExperienceTreeScreen.svelte +11 -10
- package/dist/plugins/devtools/screens/experiences/ExperiencesListScreen.svelte +1 -1
- package/dist/plugins/devtools/screens/history/HistoryEntryListItem.svelte +1 -6
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +11 -10
- package/dist/plugins/devtools/screens/responses/ResponsesTable.svelte +1 -1
- package/dist/router/Step.svelte +0 -1
- package/dist/router/StepRouter.svelte +1 -1
- package/package.json +2 -2
- package/dist/utils/get-step-fields.d.ts +0 -2
- package/dist/utils/get-step-fields.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as o from"svelte/internal/client";import{createForm as f}from"@picked/client/form";import{getExperience as n,getPicked as s}from"../hooks/client.js";function a(t,c,m){const e=f({client:s(),experienceInstance:n()},t,c,m);return{...e,form:{...e.form,onSubmit:r=>{o.user_effect(()=>e.form.onSubmit(r))},onSuccess:r=>{o.user_effect(()=>e.form.onSuccess(r))},onError:r=>{o.user_effect(()=>e.form.onError(r))}}}}export{a as createForm};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Store } from 'effector';
|
|
2
|
+
import { FormInstance as CoreFormInstance, ErrorCallback, SubmitCallback, SuccessCallback } from '@picked/client/form';
|
|
3
|
+
export type { FormField } from '@picked/client/form';
|
|
4
|
+
/**
|
|
5
|
+
* Svelte FormInstance — identical to core but callback registration returns void
|
|
6
|
+
* (cleanup is handled automatically via $effect, not by the consumer).
|
|
7
|
+
*/
|
|
8
|
+
export interface FormInstance<TFieldIds extends string = string> extends Omit<CoreFormInstance<TFieldIds>, 'form'> {
|
|
9
|
+
form: Omit<CoreFormInstance<TFieldIds>['form'], 'onSubmit' | 'onSuccess' | 'onError'> & {
|
|
10
|
+
onSubmit: (callback: SubmitCallback<TFieldIds>) => void;
|
|
11
|
+
onSuccess: (callback: SuccessCallback<TFieldIds>) => void;
|
|
12
|
+
onError: (callback: ErrorCallback) => void;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates a form instance with Svelte lifecycle management.
|
|
17
|
+
*
|
|
18
|
+
* Wraps the framework-agnostic createForm from @picked/client/form:
|
|
19
|
+
* - Injects client and experienceInstance from Svelte context
|
|
20
|
+
* - Auto-wires callback cleanup via $effect so consumers don't need to manage lifecycle
|
|
21
|
+
*
|
|
22
|
+
* Used internally by setStepContext — access via getStep() in components.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createForm(formId: string, title: Store<string>, fieldIds: Store<string[]>): FormInstance;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './create-form.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ValidationError } from '@picked/client';
|
|
2
|
+
interface GetFormOptions {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
onSuccess?: () => void | Promise<void>;
|
|
6
|
+
onError?: (errors: ValidationError[]) => void | Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
type SubmitEventWithCurrentTarget = SubmitEvent & {
|
|
9
|
+
currentTarget: EventTarget & HTMLFormElement;
|
|
10
|
+
};
|
|
11
|
+
export declare function getForm({ id: formId, title, onError, onSuccess }: GetFormOptions): {
|
|
12
|
+
form: {
|
|
13
|
+
onsubmit: import('effector').EventCallable<SubmitEventWithCurrentTarget>;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{buildResponsesFromFormData as g}from"@picked/client/form";import{createEvent as E,createEffect as c,attach as f,sample as u,split as F}from"effector";import{getPicked as S,getExperience as b}from"../hooks/client.js";import"@picked/client";import{getStep as h}from"../hooks/step.js";import"svelte";import"svelte/store";import"@picked/analytics";function T({id:i,title:n,onError:d,onSuccess:l}){const r=S(),v=h(),o=b(),{currentStepStore:s}=o,p=E(),a=c(e=>r.responses.commit(e)),x=f({source:{step:s},effect:c(({step:e})=>{r.eventBus({type:"form_submit_success",form:{id:i,title:n},experience:o,step:e??void 0}),l?.()})}),_=f({source:{step:s},mapParams:(e,t)=>({step:t.step,errors:e.errors}),effect:c(({step:e,errors:t})=>{r.eventBus({type:"form_submit_error",form:{id:i,title:n},exception:{reason:t},experience:o,step:e??void 0}),t.forEach(m=>{r.eventBus({type:"field_validation_error",exception:{reason:[m]},experience:o,step:e??void 0})}),d?.(t)})});return u({clock:p,source:{step:s},fn:({step:e})=>({formId:i,title:n,step:e}),target:c(({formId:e,title:t,step:m})=>{r.eventBus({type:"form_submit",form:{id:e,title:t},experience:o,step:m??void 0})})}),u({clock:p,source:{fields:r.fields.listStore,stepFields:v.fields,step:s},fn:({stepFields:e},t)=>(t.preventDefault(),g(e,new FormData(t.currentTarget))),target:a}),F({source:a.doneData,match:{hasErrors:({errors:e})=>e.length>0},cases:{hasErrors:_,__:x}}),{form:{onsubmit:p}}}export{T as getForm};
|
package/dist/form/index.d.ts
CHANGED
|
@@ -1,25 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
id: string;
|
|
4
|
-
title: string;
|
|
5
|
-
onSuccess?: () => void | Promise<void>;
|
|
6
|
-
onError?: (errors: ValidationError[]) => void | Promise<void>;
|
|
7
|
-
}
|
|
8
|
-
type SubmitEventWithCurrentTarget = SubmitEvent & {
|
|
9
|
-
currentTarget: EventTarget & HTMLFormElement;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @param root0
|
|
14
|
-
* @param root0.id
|
|
15
|
-
* @param root0.title
|
|
16
|
-
* @param root0.onError
|
|
17
|
-
* @param root0.onSuccess
|
|
18
|
-
* @example
|
|
19
|
-
*/
|
|
20
|
-
export declare function getForm({ id: formId, title, onError, onSuccess }: GetFormOptions): {
|
|
21
|
-
form: {
|
|
22
|
-
onsubmit: import('effector').EventCallable<SubmitEventWithCurrentTarget>;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
export {};
|
|
1
|
+
export type { FormField } from '@picked/client/form';
|
|
2
|
+
export { getForm } from './get-form';
|
package/dist/form/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{getForm as e}from"./get-form.js";export{e as getForm};
|
package/dist/hooks/field.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Field, FieldValue } from '@picked/client';
|
|
2
2
|
import { Store } from 'effector';
|
|
3
|
-
interface GetFieldResponse {
|
|
3
|
+
export interface GetFieldResponse {
|
|
4
4
|
value: Store<FieldValue>;
|
|
5
5
|
field: Store<Field | null>;
|
|
6
6
|
}
|
|
7
|
-
export declare function getField(
|
|
8
|
-
export {};
|
|
7
|
+
export declare function getField(id: string): GetFieldResponse;
|
package/dist/hooks/field.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getPicked as s}from"./client.js";function r(e){const t=s(),n=t.fields.
|
|
1
|
+
import{getPicked as s}from"./client.js";function r(e){const t=s(),n=t.fields.getById(e),o=t.responses.getByFieldId(e);return{field:n,value:o}}export{r as getField};
|
package/dist/hooks/step.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Store } from 'effector';
|
|
2
|
-
import { ExperienceStep
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
export interface StepContext {
|
|
2
|
+
import { ExperienceStep } from '@picked/client';
|
|
3
|
+
import { FormInstance, FormField } from '../form/create-form.svelte';
|
|
4
|
+
export interface StepContext extends FormInstance {
|
|
7
5
|
step: Store<ExperienceStep>;
|
|
8
|
-
fields
|
|
6
|
+
/** Directly accessible fields with current response values — usable without a form */
|
|
7
|
+
fields: Store<FormField[]>;
|
|
8
|
+
isActive: Store<boolean>;
|
|
9
|
+
/** @deprecated Use `isActive` instead */
|
|
9
10
|
isActiveStep: Store<boolean>;
|
|
10
11
|
}
|
|
11
|
-
export declare function getStep(): StepContext;
|
|
12
12
|
export declare function setStepContext(stepId: string): StepContext;
|
|
13
|
-
export
|
|
13
|
+
export declare function getStep(): StepContext;
|
package/dist/hooks/step.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getContext as
|
|
1
|
+
import{getContext as f,setContext as S}from"svelte";import{STEP_CONTEXT_KEY as s}from"../context.js";import{createForm as a}from"../form/create-form.svelte";import{getStepRouter as u}from"../router/context.js";import{getExperience as x}from"./client.js";function d(e){const t=x().treeStore.map(o=>{const c=o.steps.find(m=>m.id===e);if(!c)throw new Error(`Step with id "${e}" not found in the experience tree.`);return c}),r=t.map(o=>o.label),n=t.map(o=>o.fieldIds),i=a(e,r,n);return{stepStore:t,form:i}}function h(e){const{activeStep:p}=u(),t=p.map(i=>i?.id===e),{stepStore:r,form:n}=d(e);return S(s,{step:r,isActive:t,isActiveStep:t,...n})}function v(){return f(s)}export{v as getStep,h as setStepContext};
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExperienceInstance } from '@picked/client'
|
|
3
3
|
import { Button } from '../ui'
|
|
4
|
-
import { getPicked } from '../../../hooks'
|
|
5
4
|
|
|
6
5
|
export let experienceInstance: ExperienceInstance
|
|
7
6
|
|
|
8
|
-
const client = getPicked()
|
|
9
|
-
const experienceLookup = client.experiences.get(experienceInstance.experienceId)
|
|
10
|
-
|
|
11
7
|
const currentNode = experienceInstance.currentNodeStore
|
|
12
8
|
const currentStep = experienceInstance.currentStepStore
|
|
13
9
|
const nextStepNodes = experienceInstance.nextReachableStepNodesStore
|
|
@@ -16,24 +12,15 @@
|
|
|
16
12
|
const isOpen = experienceInstance.isOpenStore
|
|
17
13
|
|
|
18
14
|
$: totalNextStepNodes = $nextStepNodes.length
|
|
19
|
-
$: experienceName = $experienceLookup?.name ?? $experienceLookup?.key ?? experienceInstance.experienceId
|
|
20
|
-
$: currentNodeDisplay = $currentNode
|
|
21
|
-
? (('name' in $currentNode && $currentNode.name) ||
|
|
22
|
-
('stepKey' in $currentNode && $currentNode.stepKey) ||
|
|
23
|
-
$currentNode.id)
|
|
24
|
-
: ''
|
|
25
|
-
$: currentStepDisplay = $currentStep
|
|
26
|
-
? ($currentStep.name ?? $currentStep.key ?? $currentStep.id)
|
|
27
|
-
: ''
|
|
28
15
|
</script>
|
|
29
16
|
|
|
30
17
|
<tr>
|
|
31
|
-
<td>{
|
|
18
|
+
<td>{experienceInstance.experienceId}</td>
|
|
32
19
|
<td><Button variant="ghost" size="small" onclick={() => experienceInstance.toggleOpen()}>{$isOpen}</Button></td>
|
|
33
|
-
<td>{
|
|
20
|
+
<td>{$currentNode?.id || ''}</td>
|
|
34
21
|
<td>{$currentNode?.type || ''}</td>
|
|
35
|
-
<td>{
|
|
36
|
-
<td>{$currentStep?.
|
|
22
|
+
<td>{$currentStep?.id || ''}</td>
|
|
23
|
+
<td>{$currentStep?.label || ''}</td>
|
|
37
24
|
<td>{totalNextStepNodes}</td>
|
|
38
25
|
<td>{$stepsToOrigin[0]} - {$stepsToOrigin[1]}</td>
|
|
39
26
|
<td>{$stepsToLeaf[0]} - {$stepsToLeaf[1]}</td>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export let experienceInstances: ExperienceInstance[]
|
|
7
7
|
|
|
8
8
|
const columns = [
|
|
9
|
-
{ key: 'experience', header: '
|
|
9
|
+
{ key: 'experience', header: 'Experience' },
|
|
10
10
|
{ key: 'isOpen', header: 'Is Open' },
|
|
11
11
|
{ key: 'currentNodeId', header: 'Current node ID' },
|
|
12
12
|
{ key: 'currentNodeType', header: 'Current node Type' },
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { EventBusPayload, EventHistoryEntry } from '@picked/client'
|
|
3
3
|
import { Badge, Card, CodeBlock, Stack, Text } from '../../ui'
|
|
4
|
-
import { getPicked } from '../../../../hooks'
|
|
5
4
|
|
|
6
5
|
export let event: EventHistoryEntry
|
|
7
6
|
export let isExpanded: boolean
|
|
8
7
|
export let onToggle: () => void
|
|
9
8
|
|
|
10
|
-
const client = getPicked()
|
|
11
|
-
|
|
12
|
-
const eventExpId =
|
|
13
|
-
'experience' in event.payload && event.payload.experience
|
|
14
|
-
? event.payload.experience.experienceId
|
|
15
|
-
: undefined
|
|
16
|
-
const eventExpLookup = client.experiences.get(eventExpId ?? '')
|
|
17
|
-
$: eventExpName = eventExpId
|
|
18
|
-
? ($eventExpLookup?.name ?? $eventExpLookup?.key ?? eventExpId)
|
|
19
|
-
: '-'
|
|
20
|
-
|
|
21
9
|
function formatTime(date: Date): string {
|
|
22
10
|
return date.toLocaleTimeString('en-US', {
|
|
23
11
|
hour12: false,
|
|
@@ -33,49 +21,59 @@
|
|
|
33
21
|
value: unknown
|
|
34
22
|
}
|
|
35
23
|
|
|
36
|
-
function
|
|
37
|
-
if (!exp || typeof exp !== 'object') return []
|
|
24
|
+
function getPayloadFields(payload: EventBusPayload): PayloadField[] {
|
|
38
25
|
const fields: PayloadField[] = []
|
|
39
|
-
if ('id' in exp && exp.id) fields.push({ label: 'Experience ID', value: exp.id })
|
|
40
|
-
if ('experienceId' in exp && exp.experienceId)
|
|
41
|
-
fields.push({ label: 'Experience Type', value: exp.experienceId })
|
|
42
|
-
return fields
|
|
43
|
-
}
|
|
44
26
|
|
|
45
|
-
|
|
46
|
-
if (!step || typeof step !== 'object') return []
|
|
47
|
-
const fields: PayloadField[] = []
|
|
48
|
-
if ('id' in step && step.id) fields.push({ label: 'Step ID', value: step.id })
|
|
49
|
-
// eslint-disable-next-line sonarjs/deprecation -- backwards-compat fallback for label
|
|
50
|
-
const stepName = ('name' in step && step.name) || ('label' in step && step.label)
|
|
51
|
-
if (stepName) fields.push({ label: 'Step Name', value: stepName })
|
|
52
|
-
return fields
|
|
53
|
-
}
|
|
27
|
+
fields.push({ label: 'Type', value: payload.type })
|
|
54
28
|
|
|
55
|
-
|
|
56
|
-
const fields: PayloadField[] = []
|
|
57
|
-
if ('value' in payload && payload.value !== undefined)
|
|
29
|
+
if ('value' in payload && payload.value !== undefined) {
|
|
58
30
|
fields.push({ label: 'Value', value: payload.value })
|
|
59
|
-
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ('experience' in payload && payload.experience) {
|
|
34
|
+
const exp = payload.experience
|
|
35
|
+
if (exp && typeof exp === 'object') {
|
|
36
|
+
if ('id' in exp && exp.id) {
|
|
37
|
+
fields.push({ label: 'Experience ID', value: exp.id })
|
|
38
|
+
}
|
|
39
|
+
if ('experienceId' in exp && exp.experienceId) {
|
|
40
|
+
fields.push({ label: 'Experience Type', value: exp.experienceId })
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ('step' in payload && payload.step) {
|
|
46
|
+
const step = payload.step
|
|
47
|
+
if (step && typeof step === 'object') {
|
|
48
|
+
if ('id' in step && step.id) {
|
|
49
|
+
fields.push({ label: 'Step ID', value: step.id })
|
|
50
|
+
}
|
|
51
|
+
if ('label' in step && step.label) {
|
|
52
|
+
fields.push({ label: 'Step Label', value: step.label })
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if ('form' in payload && payload.form) {
|
|
60
58
|
fields.push({ label: 'Form', value: JSON.stringify(payload.form) })
|
|
61
|
-
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if ('feature' in payload && payload.feature) {
|
|
62
62
|
fields.push({ label: 'Feature', value: JSON.stringify(payload.feature) })
|
|
63
|
-
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if ('exception' in payload && payload.exception) {
|
|
64
66
|
fields.push({ label: 'Exception', value: JSON.stringify(payload.exception) })
|
|
65
|
-
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if ('version' in payload && payload.version) {
|
|
66
70
|
fields.push({ label: 'Version', value: payload.version })
|
|
67
|
-
|
|
68
|
-
}
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
const fields: PayloadField[] = [{ label: 'Type', value: payload.type }]
|
|
72
|
-
fields.push(...getScalarFields(payload))
|
|
73
|
-
if ('experience' in payload && payload.experience)
|
|
74
|
-
fields.push(...getExperienceFields(payload.experience))
|
|
75
|
-
if ('step' in payload && payload.step)
|
|
76
|
-
fields.push(...getStepFields(payload.step))
|
|
77
|
-
if ('id' in payload && payload.id && payload.type === 'session')
|
|
73
|
+
if ('id' in payload && payload.id && payload.type === 'session') {
|
|
78
74
|
fields.push({ label: 'Session ID', value: payload.id })
|
|
75
|
+
}
|
|
76
|
+
|
|
79
77
|
return fields
|
|
80
78
|
}
|
|
81
79
|
|
|
@@ -99,7 +97,9 @@
|
|
|
99
97
|
<Badge status="info">{event.payload.type}</Badge>
|
|
100
98
|
</td>
|
|
101
99
|
<td>
|
|
102
|
-
<Text size="small">
|
|
100
|
+
<Text size="small">
|
|
101
|
+
{'experience' in event.payload && event.payload.experience ? event.payload.experience.experienceId : '-'}
|
|
102
|
+
</Text>
|
|
103
103
|
</td>
|
|
104
104
|
<td>
|
|
105
105
|
<Text size="caption" color="subdued">
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
<Text size="small" weight="semibold">Event Payload</Text>
|
|
115
115
|
<Card>
|
|
116
116
|
<Stack direction="vertical" gap="small">
|
|
117
|
-
{#each getPayloadFields(event.payload) as field
|
|
117
|
+
{#each getPayloadFields(event.payload) as field}
|
|
118
118
|
<Text size="caption" inline>
|
|
119
119
|
<Text size="caption" weight="semibold" color="subdued" inline>{field.label}:</Text>
|
|
120
120
|
<CodeBlock code={formatValue(field.value)} inline />
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<Stack direction="vertical" gap="medium" padding="medium">
|
|
13
13
|
<Stack direction="horizontal" gap="small">
|
|
14
|
-
<Button variant="primary" size="small" onclick={() => client.
|
|
14
|
+
<Button variant="primary" size="small" onclick={() => client.launchExperienceById(experience.id)}>
|
|
15
15
|
Launch experience
|
|
16
16
|
</Button>
|
|
17
17
|
</Stack>
|
|
@@ -9,16 +9,17 @@
|
|
|
9
9
|
let zoom = 1
|
|
10
10
|
let selectedNode = null
|
|
11
11
|
let highlightedPath: string[][] = []
|
|
12
|
-
let error = null
|
|
12
|
+
let error: string | null = null
|
|
13
13
|
const loading = false
|
|
14
14
|
|
|
15
15
|
let treeRenderingDone = false
|
|
16
16
|
|
|
17
17
|
const tree = experience.treeStore
|
|
18
18
|
|
|
19
|
+
$: steps = $tree.steps
|
|
19
20
|
$: nodes = $tree.nodes
|
|
20
21
|
$: edges = $tree.edges
|
|
21
|
-
$:
|
|
22
|
+
$: conditionals = $tree.conditionals
|
|
22
23
|
|
|
23
24
|
let zoomBehavior: d3.ZoomBehavior<SVGSVGElement, unknown>
|
|
24
25
|
|
|
@@ -88,7 +89,8 @@
|
|
|
88
89
|
function renderGraph() {
|
|
89
90
|
d3.select(svgEl).selectAll('*').remove()
|
|
90
91
|
|
|
91
|
-
const
|
|
92
|
+
const stepsMap = new Map(steps.map((s) => [s.id, s]))
|
|
93
|
+
const conditionalsMap = new Map(conditionals.map((c) => [c.id, c]))
|
|
92
94
|
const outgoingEdges = new Map<string, ExperienceEdge[]>()
|
|
93
95
|
edges.forEach((e) => {
|
|
94
96
|
if (!outgoingEdges.has(e.sourceNodeId)) outgoingEdges.set(e.sourceNodeId, [])
|
|
@@ -97,13 +99,12 @@
|
|
|
97
99
|
|
|
98
100
|
const getNodeLabel = (node: ExperienceNode): string => {
|
|
99
101
|
if (node.type === 'origin') return 'Start'
|
|
100
|
-
if (node.type === 'step')
|
|
101
|
-
return
|
|
102
|
-
if (node.type === 'conditional') {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
if (conditionItem?.condition) return formatLogicRule(conditionItem.condition)
|
|
102
|
+
if (node.type === 'step' && node.stepId)
|
|
103
|
+
return stepsMap.get(node.stepId)?.label ?? 'Unknown Step'
|
|
104
|
+
if (node.type === 'conditional' && node.conditionalId) {
|
|
105
|
+
const conditional = conditionalsMap.get(node.conditionalId)
|
|
106
|
+
if (conditional?.label) return conditional.label
|
|
107
|
+
if (conditional?.condition) return formatLogicRule(conditional.condition)
|
|
107
108
|
return 'Condition'
|
|
108
109
|
}
|
|
109
110
|
return 'Unknown Node'
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { HistoryEntry } from '@picked/client'
|
|
3
|
-
import { getPicked } from '../../../../hooks'
|
|
4
3
|
|
|
5
4
|
export let historyEntry: HistoryEntry
|
|
6
|
-
|
|
7
|
-
const client = getPicked()
|
|
8
|
-
const experienceLookup = client.experiences.get(historyEntry.experienceId)
|
|
9
|
-
$: experienceName = $experienceLookup?.name ?? $experienceLookup?.key ?? historyEntry.experienceId
|
|
10
5
|
</script>
|
|
11
6
|
|
|
12
7
|
<tr>
|
|
13
8
|
<td>{historyEntry.id}</td>
|
|
14
|
-
<td>{
|
|
9
|
+
<td>{historyEntry.experienceId}</td>
|
|
15
10
|
<td>{historyEntry.node.id}</td>
|
|
16
11
|
<td>{historyEntry.node.type}</td>
|
|
17
12
|
<td>{historyEntry.at}</td>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { ResponseListItem, PrimitiveFieldValue, Field } from '@picked/client'
|
|
2
|
+
import type { ResponseListItem, PrimitiveFieldValue, Field, FieldValue } from '@picked/client'
|
|
3
3
|
import { getPicked } from '../../../../hooks'
|
|
4
4
|
import { Button, Text, CodeBlock, Banner, Stack } from '../../ui'
|
|
5
5
|
|
|
@@ -11,9 +11,10 @@
|
|
|
11
11
|
let isEditing = false
|
|
12
12
|
let editValue = ''
|
|
13
13
|
let editError = ''
|
|
14
|
-
let selectedOptions: Set<
|
|
14
|
+
let selectedOptions: Set<FieldValue> = new Set()
|
|
15
15
|
|
|
16
|
-
$: hasOptions = field?.options && field.options.length > 0
|
|
16
|
+
$: hasOptions = Array.isArray(field?.options) && field.options.length > 0
|
|
17
|
+
$: staticOptions = Array.isArray(field?.options) ? field.options : null
|
|
17
18
|
$: currentValue = response?.value ?? null
|
|
18
19
|
|
|
19
20
|
function formatValue(value: unknown): string {
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
selectedOptions = new Set()
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
function toggleOption(optionValue:
|
|
56
|
+
function toggleOption(optionValue: FieldValue) {
|
|
56
57
|
if (field?.multiple) {
|
|
57
58
|
if (selectedOptions.has(optionValue)) {
|
|
58
59
|
selectedOptions.delete(optionValue)
|
|
@@ -65,7 +66,7 @@
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
function parseValue(input: string):
|
|
69
|
+
function parseValue(input: string): FieldValue {
|
|
69
70
|
input = input.trim()
|
|
70
71
|
|
|
71
72
|
if (input === '' || input === '-') {
|
|
@@ -99,14 +100,14 @@
|
|
|
99
100
|
|
|
100
101
|
async function saveEdit() {
|
|
101
102
|
try {
|
|
102
|
-
let newValue:
|
|
103
|
+
let newValue: FieldValue
|
|
103
104
|
|
|
104
105
|
if (hasOptions) {
|
|
105
106
|
const values = Array.from(selectedOptions)
|
|
106
107
|
if (field?.multiple) {
|
|
107
108
|
newValue = values
|
|
108
109
|
} else {
|
|
109
|
-
newValue = values
|
|
110
|
+
newValue = values.at(0) ?? null
|
|
110
111
|
}
|
|
111
112
|
} else {
|
|
112
113
|
newValue = parseValue(editValue)
|
|
@@ -134,7 +135,7 @@
|
|
|
134
135
|
|
|
135
136
|
<tr>
|
|
136
137
|
<td>
|
|
137
|
-
<CodeBlock code={field.
|
|
138
|
+
<CodeBlock code={field.name} inline />
|
|
138
139
|
</td>
|
|
139
140
|
<td>
|
|
140
141
|
<Text size="small" weight="semibold">{field.label}</Text>
|
|
@@ -142,9 +143,9 @@
|
|
|
142
143
|
<td>
|
|
143
144
|
{#if isEditing}
|
|
144
145
|
<Stack direction="vertical" gap="small">
|
|
145
|
-
{#if hasOptions &&
|
|
146
|
+
{#if hasOptions && staticOptions}
|
|
146
147
|
<Stack direction="vertical" gap="small">
|
|
147
|
-
{#each
|
|
148
|
+
{#each staticOptions as option (option.id)}
|
|
148
149
|
<label class="option-label">
|
|
149
150
|
{#if field.multiple}
|
|
150
151
|
<input
|
package/dist/router/Step.svelte
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
sample({
|
|
53
53
|
source: { steps: stepsStore, currentStep: currentStepStore },
|
|
54
|
-
fn: ({ steps, currentStep }) => steps.find((s) => s.id ===
|
|
54
|
+
fn: ({ steps, currentStep }) => steps.find((s) => s.id === currentStep?.id) || null,
|
|
55
55
|
target: setActiveStepEvent,
|
|
56
56
|
})
|
|
57
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/svelte",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.1773878362211",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"d3": "^7.9.0"
|
|
6
6
|
},
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
},
|
|
89
89
|
"module": "./dist/index.js",
|
|
90
90
|
"peerDependencies": {
|
|
91
|
-
"@picked/client": "0.0.1-dev.
|
|
91
|
+
"@picked/client": "0.0.1-dev.1773878362211",
|
|
92
92
|
"effector": "^23.3.0",
|
|
93
93
|
"svelte": "^5.34.3"
|
|
94
94
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{evaluateRuleLogic as s}from"@picked/client";function u(o){return o.options?.some(n=>"condition"in n)??!1}function l(o){return o.some(n=>n.condition||n.conditionKey||u(n))}async function a(o,n){return n.conditionKey?o.conditions.getByKey(n.conditionKey).getState()?.condition??null:n.condition??null}async function g(o,n){return n.length===0||!l(n)?n:(await Promise.all(n.map(async t=>{const r=await a(o,t);if(!(r?await s(o,r):!0))return null;if(!t.options||!u(t))return t;const e=(await Promise.all(t.options.map(async i=>i.condition?await s(o,i.condition)?i:null:i))).filter(i=>i!==null);return e.length===t.options.length?t:e.length===0?null:{...t,options:e}}))).filter(t=>t!==null)}export{g as getStepFields};
|