@dfosco/storyboard-core 2.3.0 → 2.5.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/package.json
CHANGED
|
@@ -550,11 +550,11 @@
|
|
|
550
550
|
display: flex;
|
|
551
551
|
flex-direction: column;
|
|
552
552
|
gap: var(--base-size-8);
|
|
553
|
+
}
|
|
553
554
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
555
|
+
.protoGroup > .listItem {
|
|
556
|
+
border: 1px solid var(--borderColor-muted, #30363d);
|
|
557
|
+
border-radius: var(--base-size-6);
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
.folderGroup {
|
|
@@ -644,7 +644,7 @@
|
|
|
644
644
|
|
|
645
645
|
.protoHeader[aria-expanded="true"] .cardBody {
|
|
646
646
|
background-color: var(--bgColor-muted);
|
|
647
|
-
border-radius: var(--base-size-
|
|
647
|
+
border-radius: var(--base-size-6);
|
|
648
648
|
}
|
|
649
649
|
|
|
650
650
|
.cardBody {
|
|
@@ -653,7 +653,7 @@
|
|
|
653
653
|
|
|
654
654
|
.cardBody:hover {
|
|
655
655
|
background-color: var(--bgColor-muted);
|
|
656
|
-
border-radius: var(--base-size-
|
|
656
|
+
border-radius: var(--base-size-6);
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
.protoName {
|
|
@@ -736,7 +736,6 @@
|
|
|
736
736
|
flex-direction: column;
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
-
.folderGroup .listItem,
|
|
740
739
|
.flowItem {
|
|
741
740
|
border: 1px solid var(--borderColor-muted);
|
|
742
741
|
padding: 0;
|
|
@@ -750,14 +749,12 @@
|
|
|
750
749
|
border-top-left-radius: var(--base-size-6);
|
|
751
750
|
border-top-right-radius: var(--base-size-6);
|
|
752
751
|
}
|
|
753
|
-
|
|
754
|
-
.folderGroup .listItem:last-child,
|
|
752
|
+
|
|
755
753
|
.flowItem:last-child {
|
|
756
754
|
border-bottom-left-radius: var(--base-size-6);
|
|
757
755
|
border-bottom-right-radius: var(--base-size-6);
|
|
758
756
|
}
|
|
759
757
|
|
|
760
|
-
.folderGroup .listItem:only-child,
|
|
761
758
|
.flowItem:only-child {
|
|
762
759
|
border-radius: var(--base-size-6);
|
|
763
760
|
}
|
package/src/viewfinder.js
CHANGED
|
@@ -16,13 +16,17 @@ export function hash(str) {
|
|
|
16
16
|
/**
|
|
17
17
|
* Resolve the target route path for a flow.
|
|
18
18
|
*
|
|
19
|
+
* Priority:
|
|
19
20
|
* 1. If flow name matches a known route (case-insensitive), use that route
|
|
20
|
-
* 2. If flow data has
|
|
21
|
-
* 3.
|
|
21
|
+
* 2. If flow data has an explicit top-level `route`, or `meta.route` / `flowMeta.route`, use that
|
|
22
|
+
* 3. If flow data has `_route` (inferred from file path by Vite plugin), use that
|
|
23
|
+
* 4. Fall back to root "/"
|
|
24
|
+
*
|
|
25
|
+
* Flows with `meta.default: true` targeting a route omit the `?flow=` param.
|
|
22
26
|
*
|
|
23
27
|
* @param {string} flowName
|
|
24
28
|
* @param {string[]} knownRoutes - Array of route names (e.g. ["Dashboard", "Repositories"])
|
|
25
|
-
* @returns {string} Full path with ?flow= param
|
|
29
|
+
* @returns {string} Full path with optional ?flow= param
|
|
26
30
|
*/
|
|
27
31
|
export function resolveFlowRoute(flowName, knownRoutes = []) {
|
|
28
32
|
// Case-insensitive match against known routes
|
|
@@ -34,14 +38,22 @@ export function resolveFlowRoute(flowName, knownRoutes = []) {
|
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
// Check for explicit route: top-level `route`, then meta.route, then legacy sceneMeta.route
|
|
38
41
|
try {
|
|
39
42
|
const data = loadFlow(flowName)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
|
|
44
|
+
// Check for explicit route: top-level `route`, then meta.route, then legacy sceneMeta.route
|
|
45
|
+
const explicitRoute = data?.route || data?.meta?.route || data?.flowMeta?.route || data?.sceneMeta?.route
|
|
46
|
+
if (explicitRoute) {
|
|
47
|
+
const normalized = explicitRoute.startsWith('/') ? explicitRoute : `/${explicitRoute}`
|
|
48
|
+
if (data?.meta?.default === true) return normalized
|
|
43
49
|
return `${normalized}?flow=${encodeURIComponent(flowName)}`
|
|
44
50
|
}
|
|
51
|
+
|
|
52
|
+
// Use inferred route from file path (injected by Vite data plugin)
|
|
53
|
+
if (data?._route) {
|
|
54
|
+
if (data?.meta?.default === true) return data._route
|
|
55
|
+
return `${data._route}?flow=${encodeURIComponent(flowName)}`
|
|
56
|
+
}
|
|
45
57
|
} catch {
|
|
46
58
|
// ignore load errors
|
|
47
59
|
}
|
|
@@ -101,7 +113,7 @@ export function buildPrototypeIndex(knownRoutes = []) {
|
|
|
101
113
|
icon: meta.icon || null,
|
|
102
114
|
team: meta.team || null,
|
|
103
115
|
tags: meta.tags || null,
|
|
104
|
-
hideFlows: meta.hideFlows
|
|
116
|
+
hideFlows: meta.hideFlows ?? raw?.hideFlows ?? false,
|
|
105
117
|
folder: raw?.folder || null,
|
|
106
118
|
flows: [],
|
|
107
119
|
}
|
package/src/viewfinder.test.js
CHANGED
|
@@ -12,6 +12,9 @@ const makeIndex = () => ({
|
|
|
12
12
|
'meta-author': { flowMeta: { author: 'dfosco' }, title: 'With Author' },
|
|
13
13
|
'meta-authors': { flowMeta: { author: ['dfosco', 'heyamie', 'branonconor'] }, title: 'Multi Author' },
|
|
14
14
|
'meta-both': { flowMeta: { route: '/Overview', author: 'octocat' }, title: 'Both' },
|
|
15
|
+
'inferred-route': { _route: '/Dashboard', title: 'Inferred' },
|
|
16
|
+
'inferred-default': { _route: '/Settings', meta: { default: true }, title: 'Default Flow' },
|
|
17
|
+
'explicit-wins': { route: '/Forms', _route: '/Dashboard', title: 'Explicit Wins' },
|
|
15
18
|
},
|
|
16
19
|
objects: {},
|
|
17
20
|
records: {},
|
|
@@ -105,6 +108,31 @@ describe('resolveFlowRoute', () => {
|
|
|
105
108
|
})
|
|
106
109
|
expect(resolveFlowRoute('conflict', [])).toBe('/Forms?flow=conflict')
|
|
107
110
|
})
|
|
111
|
+
|
|
112
|
+
it('uses _route when no explicit route exists', () => {
|
|
113
|
+
expect(resolveFlowRoute('inferred-route', routes)).toBe('/Dashboard?flow=inferred-route')
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('prefers explicit route over _route', () => {
|
|
117
|
+
expect(resolveFlowRoute('explicit-wins', routes)).toBe('/Forms?flow=explicit-wins')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('omits ?flow= when meta.default is true (inferred route)', () => {
|
|
121
|
+
expect(resolveFlowRoute('inferred-default', routes)).toBe('/Settings')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('omits ?flow= when meta.default is true (explicit route)', () => {
|
|
125
|
+
init({
|
|
126
|
+
flows: { 'default-explicit': { route: '/Overview', meta: { default: true } } },
|
|
127
|
+
objects: {},
|
|
128
|
+
records: {},
|
|
129
|
+
})
|
|
130
|
+
expect(resolveFlowRoute('default-explicit', [])).toBe('/Overview')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('still appends ?flow= when meta.default is absent even with _route', () => {
|
|
134
|
+
expect(resolveFlowRoute('inferred-route', [])).toBe('/Dashboard?flow=inferred-route')
|
|
135
|
+
})
|
|
108
136
|
})
|
|
109
137
|
|
|
110
138
|
describe('getFlowMeta', () => {
|
|
@@ -183,6 +211,20 @@ describe('buildPrototypeIndex', () => {
|
|
|
183
211
|
expect(proto.hideFlows).toBe(false)
|
|
184
212
|
})
|
|
185
213
|
|
|
214
|
+
it('reads hideFlows from top-level prototype metadata (outside meta key)', () => {
|
|
215
|
+
init({
|
|
216
|
+
flows: { 'TopLevel/only-flow': { meta: { title: 'Only Flow' } } },
|
|
217
|
+
objects: {},
|
|
218
|
+
records: {},
|
|
219
|
+
prototypes: {
|
|
220
|
+
TopLevel: { meta: { title: 'Top Level' }, hideFlows: true },
|
|
221
|
+
},
|
|
222
|
+
})
|
|
223
|
+
const { prototypes } = buildPrototypeIndex([])
|
|
224
|
+
const proto = prototypes.find(p => p.dirName === 'TopLevel')
|
|
225
|
+
expect(proto.hideFlows).toBe(true)
|
|
226
|
+
})
|
|
227
|
+
|
|
186
228
|
it('groups prototypes into folders when folder field is set', () => {
|
|
187
229
|
init({
|
|
188
230
|
flows: {
|