@notmrabhi/flowforge
v0.1.66
Published
Schema-driven form renderer and workflow engine for miniOrange IAM
Maintainers
Readme
@miniorange/flowforge
Schema-driven form renderer and workflow builder for miniOrange IAM. Provides a dynamic form engine (FlowForm) and a node-based workflow canvas (WorkflowCanvas) built on ReactFlow, with BPMN import/export.
📋 Form schema reference: FORM.md — field types, validation, conditions, ref API, common patterns.
Proprietary — © miniOrange. All rights reserved. Use is restricted to miniOrange products and authorized integrations.
Installation
npm install @miniorange/flowforgePeer dependencies
This package expects the host app to provide React, MUI, and a few UI libraries (so versions stay in sync with your app):
npm install react react-dom @mui/material @emotion/react @emotion/styled formik react-icons react-select reactflowSupported ranges: React ≥17, MUI ≥5, reactflow ≥11 (see peerDependencies in package.json).
Usage
import { FlowForgeCanvas } from '@miniorange/flowforge/canvas';
import { NodeTypeRegistry } from '@miniorange/flowforge/nodes';
import { TemplateRegistry } from '@miniorange/flowforge/templates';
import '@miniorange/flowforge/dist/style.css';
const nodeRegistry = new NodeTypeRegistry();
const templateRegistry = new TemplateRegistry();
// register node descriptors + templates...
export function Builder() {
return (
<FlowForgeCanvas
nodeRegistry={nodeRegistry}
templateRegistry={templateRegistry}
canvasOptions={{ branchLayout: 'vertical' }}
onSave={(workflow) => console.log(workflow)}
/>
);
}Loading templates from a backend
Instead of hardcoding templateRegistry.register({...}) calls, fetch templates
from your API and bulk-register them. The package accepts the backend wire
shape directly via registerFromApi:
import { templateRegistry } from '@miniorange/flowforge/templates';
import type { ApiWorkflowTemplate } from '@miniorange/flowforge/canvas';
async function loadTemplates() {
const res = await fetch('/api/v1/workflow-template');
const list: ApiWorkflowTemplate[] = await res.json();
templateRegistry.clear().registerFromApi(list);
}Expected payload shape per row (the backend's persistence model + a templateUI
JSON column for UI fields):
{
"key": "END_USER_CREATION",
"name": "New User Registration",
"description": "…",
"state": "PUBLISHED",
"allowedTasks": ["USER_CREATION", "USER_GROUP_ASSIGNMENT", "USER_ROLE_ASSIGNMENT"],
"allowedSources": ["SIGNUP_FLOW", "ADMIN_CREATION_FLOW"],
"configuration": { /* runtime BPMN — ignored by the canvas */ },
"templateUI": {
"triggerCategory": "event",
"icon": "user-plus",
"tags": ["onboarding"],
"category": "User Lifecycle",
"author": "miniOrange",
"popularity": 100,
"source": "system",
"product": "IAM",
"maxTasks": 10,
"taskLabels": { "USER_GROUP_ASSIGNMENT": "Assign Groups" },
"skeletonState": {
"slots": [ /* CanvasSlot[] — pre-seeded canvas chain */ ],
"branches": {}
}
}
}registerFromApi normalises allowedTasks → availableTasks automatically.
Bad rows (missing key) are skipped with a DEV-mode warning, so a single
malformed template doesn't blank the picker.
Entry points
| Import | Contents |
| --- | --- |
| @miniorange/flowforge | Everything (form + canvas + registries) |
| @miniorange/flowforge/form | FlowForm dynamic form renderer |
| @miniorange/flowforge/canvas | WorkflowCanvas builder |
| @miniorange/flowforge/nodes | NodeTypeRegistry + built-in node types |
| @miniorange/flowforge/templates | TemplateRegistry + skeletons |
| @miniorange/flowforge/core | Shared core types/utilities |
| @miniorange/flowforge/default-ui | Default drawer/picker UI |
Development
npm run demo # run the demo app (Vite)
npm run build # typecheck + build dist
npm run typecheck # tsc --noEmit
npm test # build + BPMN round-trip testsLicense
UNLICENSED — proprietary to miniOrange. Not for redistribution outside authorized use.
