@bpmnkit/operate 0.0.11 → 0.0.13
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 +3 -0
- package/dist/operate.js +18 -3
- package/dist/types.d.ts +5 -0
- package/dist/views/definition-detail.d.ts +1 -0
- package/dist/views/definition-detail.js +23 -4
- package/dist/views/incident-detail.d.ts +1 -0
- package/dist/views/incident-detail.js +20 -3
- package/dist/views/instance-detail.d.ts +1 -0
- package/dist/views/instance-detail.js +20 -3
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -113,6 +113,9 @@ interface OperateApi {
|
|
|
113
113
|
| [`@bpmnkit/connector-gen`](https://www.npmjs.com/package/@bpmnkit/connector-gen) | Generate connector templates from OpenAPI specs |
|
|
114
114
|
| [`@bpmnkit/cli`](https://www.npmjs.com/package/@bpmnkit/cli) | Camunda 8 command-line interface (casen) |
|
|
115
115
|
| [`@bpmnkit/proxy`](https://www.npmjs.com/package/@bpmnkit/proxy) | Local AI bridge and Camunda API proxy server |
|
|
116
|
+
| [`@bpmnkit/cli-sdk`](https://www.npmjs.com/package/@bpmnkit/cli-sdk) | Plugin authoring SDK for the casen CLI |
|
|
117
|
+
| [`@bpmnkit/create-casen-plugin`](https://www.npmjs.com/package/@bpmnkit/create-casen-plugin) | Scaffold a new casen CLI plugin in seconds |
|
|
118
|
+
| [`@bpmnkit/casen-report`](https://www.npmjs.com/package/@bpmnkit/casen-report) | HTML reports from Camunda 8 incident and SLA data |
|
|
116
119
|
|
|
117
120
|
## License
|
|
118
121
|
|
package/dist/operate.js
CHANGED
|
@@ -27,7 +27,7 @@ import { createTasksView } from "./views/tasks.js";
|
|
|
27
27
|
export function createOperate(options) {
|
|
28
28
|
injectUiStyles();
|
|
29
29
|
injectOperateStyles();
|
|
30
|
-
const { container, proxyUrl = "http://localhost:3033", pollInterval = 30_000, mock = false, } = options;
|
|
30
|
+
const { container, proxyUrl = "http://localhost:3033", pollInterval = 30_000, mock = false, onOpenInEditor, } = options;
|
|
31
31
|
let profile = options.profile ?? null;
|
|
32
32
|
const initialTheme = loadPersistedTheme() ?? options.theme ?? "neon";
|
|
33
33
|
// ── Root element ──────────────────────────────────────────────────────────
|
|
@@ -147,7 +147,14 @@ export function createOperate(options) {
|
|
|
147
147
|
};
|
|
148
148
|
header.setTitle("Process Definition");
|
|
149
149
|
nav.setActive("/definitions");
|
|
150
|
-
const { el: vEl, destroy, setTheme, } = createDefinitionDetailView(params.key ?? "", defStore, {
|
|
150
|
+
const { el: vEl, destroy, setTheme, } = createDefinitionDetailView(params.key ?? "", defStore, {
|
|
151
|
+
proxyUrl,
|
|
152
|
+
profile,
|
|
153
|
+
mock,
|
|
154
|
+
theme: getTheme(),
|
|
155
|
+
navigate: (path) => router.navigate(path),
|
|
156
|
+
onOpenInEditor,
|
|
157
|
+
}, () => router.navigate("/definitions"));
|
|
151
158
|
showView(vEl, destroy, setTheme);
|
|
152
159
|
});
|
|
153
160
|
router.on("/decisions", () => {
|
|
@@ -204,6 +211,7 @@ export function createOperate(options) {
|
|
|
204
211
|
mock,
|
|
205
212
|
theme: getTheme(),
|
|
206
213
|
navigate: (path) => router.navigate(path),
|
|
214
|
+
onOpenInEditor,
|
|
207
215
|
}, () => router.navigate("/instances"));
|
|
208
216
|
showView(vEl, destroy, setTheme);
|
|
209
217
|
});
|
|
@@ -229,7 +237,14 @@ export function createOperate(options) {
|
|
|
229
237
|
const incidentKey = params.key ?? "";
|
|
230
238
|
header.setTitle(`Incident ${incidentKey}`);
|
|
231
239
|
nav.setActive("/incidents");
|
|
232
|
-
const { el: vEl, destroy } = createIncidentDetailView(incidentKey, incStore, {
|
|
240
|
+
const { el: vEl, destroy } = createIncidentDetailView(incidentKey, incStore, {
|
|
241
|
+
proxyUrl,
|
|
242
|
+
profile,
|
|
243
|
+
mock,
|
|
244
|
+
theme: getTheme(),
|
|
245
|
+
navigate: (path) => router.navigate(path),
|
|
246
|
+
onOpenInEditor,
|
|
247
|
+
}, () => router.navigate("/incidents"));
|
|
233
248
|
showView(vEl, destroy);
|
|
234
249
|
});
|
|
235
250
|
router.on("/jobs", () => {
|
package/dist/types.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export interface OperateOptions {
|
|
|
12
12
|
pollInterval?: number;
|
|
13
13
|
/** Use mock/demo data instead of connecting to proxy. */
|
|
14
14
|
mock?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Called when the user clicks "Open in Editor" on a diagram view.
|
|
17
|
+
* Receives the raw BPMN XML and a suggested file name.
|
|
18
|
+
*/
|
|
19
|
+
onOpenInEditor?: (xml: string, name: string) => void;
|
|
15
20
|
}
|
|
16
21
|
export interface OperateApi {
|
|
17
22
|
readonly el: HTMLElement;
|
|
@@ -5,6 +5,7 @@ interface Config {
|
|
|
5
5
|
mock: boolean;
|
|
6
6
|
theme: "light" | "dark" | "neon";
|
|
7
7
|
navigate?: (path: string) => void;
|
|
8
|
+
onOpenInEditor?: (xml: string, name: string) => void;
|
|
8
9
|
}
|
|
9
10
|
export declare function createDefinitionDetailView(definitionKey: string, store: DefinitionsStore, cfg: Config, onBack: () => void): {
|
|
10
11
|
el: HTMLElement;
|
|
@@ -28,6 +28,19 @@ export function createDefinitionDetailView(definitionKey, store, cfg, onBack) {
|
|
|
28
28
|
backBtn.textContent = "← Processes";
|
|
29
29
|
backBtn.addEventListener("click", onBack);
|
|
30
30
|
breadcrumb.appendChild(backBtn);
|
|
31
|
+
let _openInEditorXml = null;
|
|
32
|
+
let _openInEditorName = "";
|
|
33
|
+
const openInEditorBtn = document.createElement("button");
|
|
34
|
+
openInEditorBtn.className = "op-action-btn";
|
|
35
|
+
openInEditorBtn.textContent = "Open in Editor ↗";
|
|
36
|
+
openInEditorBtn.style.marginLeft = "auto";
|
|
37
|
+
openInEditorBtn.style.display = "none";
|
|
38
|
+
openInEditorBtn.addEventListener("click", () => {
|
|
39
|
+
if (_openInEditorXml)
|
|
40
|
+
cfg.onOpenInEditor?.(_openInEditorXml, _openInEditorName);
|
|
41
|
+
});
|
|
42
|
+
if (cfg.onOpenInEditor)
|
|
43
|
+
breadcrumb.appendChild(openInEditorBtn);
|
|
31
44
|
el.appendChild(breadcrumb);
|
|
32
45
|
// Metadata row
|
|
33
46
|
const meta = document.createElement("div");
|
|
@@ -292,7 +305,10 @@ export function createDefinitionDetailView(definitionKey, store, cfg, onBack) {
|
|
|
292
305
|
el.appendChild(overlay);
|
|
293
306
|
setTimeout(() => bizInput.focus(), 0);
|
|
294
307
|
}
|
|
295
|
-
function loadCanvas(xml) {
|
|
308
|
+
function loadCanvas(xml, name) {
|
|
309
|
+
_openInEditorXml = xml;
|
|
310
|
+
_openInEditorName = name;
|
|
311
|
+
openInEditorBtn.style.display = "";
|
|
296
312
|
canvas?.destroy();
|
|
297
313
|
canvasWrap.innerHTML = "";
|
|
298
314
|
canvas = new BpmnCanvas({
|
|
@@ -303,12 +319,15 @@ export function createDefinitionDetailView(definitionKey, store, cfg, onBack) {
|
|
|
303
319
|
});
|
|
304
320
|
}
|
|
305
321
|
if (cfg.mock) {
|
|
306
|
-
|
|
307
|
-
|
|
322
|
+
const def = getDef();
|
|
323
|
+
renderMeta(def);
|
|
324
|
+
const mockName = def?.name ?? def?.processDefinitionId ?? "Process";
|
|
325
|
+
loadCanvas(MOCK_BPMN_XML, mockName);
|
|
308
326
|
}
|
|
309
327
|
else {
|
|
310
328
|
const def = getDef();
|
|
311
329
|
renderMeta(def);
|
|
330
|
+
const defName = def?.name ?? def?.processDefinitionId ?? "Process";
|
|
312
331
|
fetch(`${cfg.proxyUrl}/api/process-definitions/${definitionKey}/xml`, {
|
|
313
332
|
headers: {
|
|
314
333
|
accept: "text/xml",
|
|
@@ -316,7 +335,7 @@ export function createDefinitionDetailView(definitionKey, store, cfg, onBack) {
|
|
|
316
335
|
},
|
|
317
336
|
})
|
|
318
337
|
.then((r) => r.text())
|
|
319
|
-
.then((xml) => loadCanvas(xml))
|
|
338
|
+
.then((xml) => loadCanvas(xml, defName))
|
|
320
339
|
.catch(() => {
|
|
321
340
|
canvasWrap.innerHTML = `<div style="padding:24px;color:var(--bpmnkit-fg-muted)">Failed to load diagram</div>`;
|
|
322
341
|
});
|
|
@@ -5,6 +5,7 @@ interface Config {
|
|
|
5
5
|
mock: boolean;
|
|
6
6
|
theme: "light" | "dark" | "neon";
|
|
7
7
|
navigate?: (path: string) => void;
|
|
8
|
+
onOpenInEditor?: (xml: string, name: string) => void;
|
|
8
9
|
}
|
|
9
10
|
export declare function createIncidentDetailView(incidentKey: string, store: IncidentsStore, cfg: Config, onBack: () => void): {
|
|
10
11
|
el: HTMLElement;
|
|
@@ -44,6 +44,19 @@ export function createIncidentDetailView(incidentKey, store, cfg, onBack) {
|
|
|
44
44
|
backBtn.textContent = "← Incidents";
|
|
45
45
|
backBtn.addEventListener("click", onBack);
|
|
46
46
|
breadcrumb.appendChild(backBtn);
|
|
47
|
+
let _openInEditorXml = null;
|
|
48
|
+
let _openInEditorName = "";
|
|
49
|
+
const openInEditorBtn = document.createElement("button");
|
|
50
|
+
openInEditorBtn.className = "op-action-btn";
|
|
51
|
+
openInEditorBtn.textContent = "Open in Editor ↗";
|
|
52
|
+
openInEditorBtn.style.marginLeft = "auto";
|
|
53
|
+
openInEditorBtn.style.display = "none";
|
|
54
|
+
openInEditorBtn.addEventListener("click", () => {
|
|
55
|
+
if (_openInEditorXml)
|
|
56
|
+
cfg.onOpenInEditor?.(_openInEditorXml, _openInEditorName);
|
|
57
|
+
});
|
|
58
|
+
if (cfg.onOpenInEditor)
|
|
59
|
+
breadcrumb.appendChild(openInEditorBtn);
|
|
47
60
|
el.appendChild(breadcrumb);
|
|
48
61
|
// Process chain (shows Root / Parent / Current)
|
|
49
62
|
const processChainEl = document.createElement("div");
|
|
@@ -221,7 +234,10 @@ export function createIncidentDetailView(incidentKey, store, cfg, onBack) {
|
|
|
221
234
|
// Canvas
|
|
222
235
|
const tokenHighlight = createTokenHighlightPlugin();
|
|
223
236
|
let canvas = null;
|
|
224
|
-
function loadCanvas(xml) {
|
|
237
|
+
function loadCanvas(xml, name) {
|
|
238
|
+
_openInEditorXml = xml;
|
|
239
|
+
_openInEditorName = name;
|
|
240
|
+
openInEditorBtn.style.display = "";
|
|
225
241
|
canvas?.destroy();
|
|
226
242
|
canvasWrap.innerHTML = "";
|
|
227
243
|
canvas = new BpmnCanvas({
|
|
@@ -459,7 +475,7 @@ export function createIncidentDetailView(incidentKey, store, cfg, onBack) {
|
|
|
459
475
|
let storeUnsub;
|
|
460
476
|
if (cfg.mock) {
|
|
461
477
|
const mockInc = MOCK_INCIDENTS.find((i) => i.incidentKey === incidentKey) ?? null;
|
|
462
|
-
loadCanvas(MOCK_BPMN_XML);
|
|
478
|
+
loadCanvas(MOCK_BPMN_XML, mockInc?.processDefinitionId ?? "Process");
|
|
463
479
|
if (mockInc) {
|
|
464
480
|
renderMeta(mockInc);
|
|
465
481
|
renderDetails(mockInc);
|
|
@@ -488,6 +504,7 @@ export function createIncidentDetailView(incidentKey, store, cfg, onBack) {
|
|
|
488
504
|
renderDetails(inc);
|
|
489
505
|
fetchProcessChain(inc).catch(() => { });
|
|
490
506
|
const pdKey = inc.processDefinitionKey;
|
|
507
|
+
const incName = inc.processDefinitionId ?? "Process";
|
|
491
508
|
if (pdKey) {
|
|
492
509
|
fetch(`${cfg.proxyUrl}/api/process-definitions/${pdKey}/xml`, {
|
|
493
510
|
headers: {
|
|
@@ -497,7 +514,7 @@ export function createIncidentDetailView(incidentKey, store, cfg, onBack) {
|
|
|
497
514
|
})
|
|
498
515
|
.then((r) => r.text())
|
|
499
516
|
.then((xml) => {
|
|
500
|
-
loadCanvas(xml);
|
|
517
|
+
loadCanvas(xml, incName);
|
|
501
518
|
if (inc.elementId) {
|
|
502
519
|
tokenHighlight.api.setActive([inc.elementId]);
|
|
503
520
|
}
|
|
@@ -6,6 +6,7 @@ interface Config {
|
|
|
6
6
|
mock: boolean;
|
|
7
7
|
theme: "light" | "dark" | "neon";
|
|
8
8
|
navigate?: (path: string) => void;
|
|
9
|
+
onOpenInEditor?: (xml: string, name: string) => void;
|
|
9
10
|
}
|
|
10
11
|
export declare function createInstanceDetailView(instanceKey: string, instancesStore: InstancesStore, cfg: Config, onBack: () => void): {
|
|
11
12
|
el: HTMLElement;
|
|
@@ -139,6 +139,19 @@ export function createInstanceDetailView(instanceKey, instancesStore, cfg, onBac
|
|
|
139
139
|
backBtn.textContent = "← Instances";
|
|
140
140
|
backBtn.addEventListener("click", onBack);
|
|
141
141
|
breadcrumb.appendChild(backBtn);
|
|
142
|
+
let _openInEditorXml = null;
|
|
143
|
+
let _openInEditorName = "";
|
|
144
|
+
const openInEditorBtn = document.createElement("button");
|
|
145
|
+
openInEditorBtn.className = "op-action-btn";
|
|
146
|
+
openInEditorBtn.textContent = "Open in Editor ↗";
|
|
147
|
+
openInEditorBtn.style.marginLeft = "auto";
|
|
148
|
+
openInEditorBtn.style.display = "none";
|
|
149
|
+
openInEditorBtn.addEventListener("click", () => {
|
|
150
|
+
if (_openInEditorXml)
|
|
151
|
+
cfg.onOpenInEditor?.(_openInEditorXml, _openInEditorName);
|
|
152
|
+
});
|
|
153
|
+
if (cfg.onOpenInEditor)
|
|
154
|
+
breadcrumb.appendChild(openInEditorBtn);
|
|
142
155
|
el.appendChild(breadcrumb);
|
|
143
156
|
// Process hierarchy chain (shown for sub-process instances)
|
|
144
157
|
const processChainEl = document.createElement("div");
|
|
@@ -241,7 +254,10 @@ export function createInstanceDetailView(instanceKey, instancesStore, cfg, onBac
|
|
|
241
254
|
// Token-highlight plugin + canvas
|
|
242
255
|
const tokenHighlight = createTokenHighlightPlugin();
|
|
243
256
|
let canvas = null;
|
|
244
|
-
function loadCanvas(xml) {
|
|
257
|
+
function loadCanvas(xml, name) {
|
|
258
|
+
_openInEditorXml = xml;
|
|
259
|
+
_openInEditorName = name;
|
|
260
|
+
openInEditorBtn.style.display = "";
|
|
245
261
|
canvas?.destroy();
|
|
246
262
|
canvasWrap.innerHTML = "";
|
|
247
263
|
canvas = new BpmnCanvas({
|
|
@@ -618,7 +634,7 @@ export function createInstanceDetailView(instanceKey, instancesStore, cfg, onBac
|
|
|
618
634
|
// ── Instance data loading ────────────────────────────────────────────────
|
|
619
635
|
let instUnsub;
|
|
620
636
|
if (cfg.mock) {
|
|
621
|
-
loadCanvas(MOCK_BPMN_XML);
|
|
637
|
+
loadCanvas(MOCK_BPMN_XML, "Order Processing");
|
|
622
638
|
applyTokens(MOCK_ACTIVE_ELEMENTS, MOCK_VISITED_ELEMENTS);
|
|
623
639
|
renderVariables(MOCK_VARIABLES.filter((v) => v.processInstanceKey === instanceKey));
|
|
624
640
|
setTimeout(() => applyTokens(MOCK_ACTIVE_ELEMENTS, MOCK_VISITED_ELEMENTS), 100);
|
|
@@ -645,6 +661,7 @@ export function createInstanceDetailView(instanceKey, instancesStore, cfg, onBac
|
|
|
645
661
|
renderMeta(inst);
|
|
646
662
|
fetchProcessChain(inst.processInstanceKey).catch(() => { });
|
|
647
663
|
const pdKey = inst.processDefinitionKey;
|
|
664
|
+
const instName = inst.processDefinitionName ?? inst.processDefinitionId ?? "Process";
|
|
648
665
|
fetch(`${cfg.proxyUrl}/api/process-definitions/${pdKey}/xml`, {
|
|
649
666
|
headers: {
|
|
650
667
|
accept: "text/xml",
|
|
@@ -653,7 +670,7 @@ export function createInstanceDetailView(instanceKey, instancesStore, cfg, onBac
|
|
|
653
670
|
})
|
|
654
671
|
.then((r) => r.text())
|
|
655
672
|
.then((xml) => {
|
|
656
|
-
loadCanvas(xml);
|
|
673
|
+
loadCanvas(xml, instName);
|
|
657
674
|
return fetch(`${cfg.proxyUrl}/api/element-instances/search`, {
|
|
658
675
|
method: "POST",
|
|
659
676
|
headers: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bpmnkit/operate",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Monitoring and operations frontend for Camunda 8 clusters — real-time SSE, zero dependencies",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"dist/**/*.d.ts"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@bpmnkit/api": "0.0.
|
|
22
|
-
"@bpmnkit/canvas": "0.0.
|
|
23
|
-
"@bpmnkit/core": "0.0.
|
|
24
|
-
"@bpmnkit/plugins": "0.0.
|
|
25
|
-
"@bpmnkit/ui": "0.0.
|
|
21
|
+
"@bpmnkit/api": "0.0.13",
|
|
22
|
+
"@bpmnkit/canvas": "0.0.14",
|
|
23
|
+
"@bpmnkit/core": "0.0.14",
|
|
24
|
+
"@bpmnkit/plugins": "0.0.16",
|
|
25
|
+
"@bpmnkit/ui": "0.0.9"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
28
|
"bpmn",
|