@xeplr/ui-factory 1.6.0 → 1.7.1
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/README.md +7 -0
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/pages.jsx +51 -1
package/README.md
CHANGED
|
@@ -382,6 +382,13 @@ const flows = createFlowsApi({ fetch: authFetch, base: '/api/workflow' })
|
|
|
382
382
|
- Approvals (another person's turn, with an assignee and a timeout) are not
|
|
383
383
|
part of this designer.
|
|
384
384
|
|
|
385
|
+
An app page needs only its two API clients — the flow and the forms are
|
|
386
|
+
loaded for it:
|
|
387
|
+
|
|
388
|
+
```jsx
|
|
389
|
+
<FlowDesignerPage factory={factory} flows={flows} flowKey={key} urlKey="flow" />
|
|
390
|
+
```
|
|
391
|
+
|
|
385
392
|
Controllers, for a design of your own: `useFlowBuilder` (the flow, plus
|
|
386
393
|
`navigationOf` / `setNavigation`), `useScreenEvents` (one screen's events,
|
|
387
394
|
`adopt` to share its draft with a builder), `useFunctionCatalog` (the app's
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xeplr/ui-factory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Design data-entry screens on @xeplr/ui-canvas, save them as JSON, run them as auto-saving forms with lists of saved records — built for Claude to draft and people to refine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/index.js
CHANGED
|
@@ -31,4 +31,4 @@ export { BuilderSample, ScreenSample, ListView, ScreenModal, FlowRunnerSample, F
|
|
|
31
31
|
export { FactoryHooks } from './hooks.js'
|
|
32
32
|
|
|
33
33
|
// Ready-made
|
|
34
|
-
export { FactoryBuilder, FactoryScreen, FlowRunner, FlowBuilder, FlowDesigner } from './pages.jsx'
|
|
34
|
+
export { FactoryBuilder, FactoryScreen, FlowRunner, FlowBuilder, FlowDesigner, FlowDesignerPage } from './pages.jsx'
|
package/src/pages.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef } from 'react'
|
|
1
|
+
import { useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { useFactoryBuilder } from './useFactoryBuilder.js'
|
|
3
3
|
import { useFactoryScreen } from './useFactoryScreen.js'
|
|
4
4
|
import { useFlowRun } from './useFlowRun.js'
|
|
@@ -6,6 +6,7 @@ import { useFlowBuilder } from './useFlowBuilder.js'
|
|
|
6
6
|
import { useScreenEvents } from './useScreenEvents.js'
|
|
7
7
|
import { useFunctionCatalog } from './useFunctionCatalog.js'
|
|
8
8
|
import { useUrlTab } from './useUrlPlaces.js'
|
|
9
|
+
import { loadScreens } from './screenSource.js'
|
|
9
10
|
import { BuilderSample, ScreenSample, ScreenModal, FlowRunnerSample, FlowBuilderSample, FlowDesignerSample } from './designs/index.js'
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -269,3 +270,52 @@ export function FlowDesigner(props) {
|
|
|
269
270
|
/>
|
|
270
271
|
)
|
|
271
272
|
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* <FlowDesigner>, wired to an app's two API clients — what an app's
|
|
276
|
+
* /configure/flows/:key page renders, so the wiring lives here and not, copied
|
|
277
|
+
* and drifting, in every generated app.
|
|
278
|
+
*
|
|
279
|
+
* Loads the flow and the app's FORMS (screens with fields of their own — a
|
|
280
|
+
* step shows one to be filled in) and hands everything else straight on.
|
|
281
|
+
*
|
|
282
|
+
* @prop factory createFactoryApi(…) — screens, drafts, publish, the app's functions
|
|
283
|
+
* @prop flows createFlowsApi(…) — load, save, publish the flow
|
|
284
|
+
* @prop flowKey the flow to open
|
|
285
|
+
* @prop urlKey keep the selected step and tab in the URL
|
|
286
|
+
*/
|
|
287
|
+
export function FlowDesignerPage({ factory, flows, flowKey, urlKey, className, style }) {
|
|
288
|
+
const [flow, setFlow] = useState(null)
|
|
289
|
+
const [screens, setScreens] = useState(null)
|
|
290
|
+
const [error, setError] = useState(null)
|
|
291
|
+
useEffect(() => {
|
|
292
|
+
let gone = false
|
|
293
|
+
setFlow(null); setError(null)
|
|
294
|
+
Promise.all([flows.loadFlow(flowKey), loadScreens(factory)]).then(([f, list]) => {
|
|
295
|
+
if (gone) return
|
|
296
|
+
setFlow(f)
|
|
297
|
+
setScreens(list.filter((s) => s.fields && s.fields.length).map((s) => ({ id: s.key, name: s.name })))
|
|
298
|
+
}, (e) => { if (!gone) setError(e.message || `Could not open "${flowKey}"`) })
|
|
299
|
+
return () => { gone = true }
|
|
300
|
+
}, [factory, flows, flowKey])
|
|
301
|
+
|
|
302
|
+
if (error) return <div className="xeplr-factory-invalid" role="alert">{error}</div>
|
|
303
|
+
if (!flow || !screens) return <div className="xeplr-factory-hint">Opening the flow…</div>
|
|
304
|
+
return (
|
|
305
|
+
<FlowDesigner
|
|
306
|
+
flow={flow}
|
|
307
|
+
screens={screens}
|
|
308
|
+
loadScreen={factory.loadScreen}
|
|
309
|
+
onSave={flows.saveFlow}
|
|
310
|
+
onPublish={flows.publishFlow}
|
|
311
|
+
listFunctions={factory.listFunctions}
|
|
312
|
+
loadDraft={factory.loadDraft}
|
|
313
|
+
saveDraft={factory.saveDraft}
|
|
314
|
+
publishScreen={factory.publish}
|
|
315
|
+
builderProps={factory.builderProps}
|
|
316
|
+
urlKey={urlKey}
|
|
317
|
+
className={className}
|
|
318
|
+
style={style}
|
|
319
|
+
/>
|
|
320
|
+
)
|
|
321
|
+
}
|