@bpmnkit/plugins 0.0.16 → 0.0.18
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 +2 -0
- package/dist/ai-bridge/panel.js +29 -3
- package/dist/live-mode/css.d.ts +4 -0
- package/dist/live-mode/css.js +170 -0
- package/dist/live-mode/index.d.ts +42 -0
- package/dist/live-mode/index.js +479 -0
- package/dist/pattern-advisor/css.d.ts +4 -0
- package/dist/pattern-advisor/css.js +198 -0
- package/dist/pattern-advisor/index.d.ts +20 -0
- package/dist/pattern-advisor/index.js +233 -0
- package/dist/process-runner/css.js +128 -0
- package/dist/process-runner/index.d.ts +52 -0
- package/dist/process-runner/index.js +508 -19
- package/dist/storage/storage-api.d.ts +6 -0
- package/dist/storage/storage-api.js +12 -0
- package/dist/story-view/css.d.ts +4 -0
- package/dist/story-view/css.js +259 -0
- package/dist/story-view/index.d.ts +33 -0
- package/dist/story-view/index.js +294 -0
- package/dist/variable-flow/css.d.ts +2 -0
- package/dist/variable-flow/css.js +98 -0
- package/dist/variable-flow/index.d.ts +12 -0
- package/dist/variable-flow/index.js +226 -0
- package/package.json +21 -5
|
@@ -2,6 +2,12 @@ import type { FileRecord, FileType, ProjectRecord, WorkspaceRecord } from "./typ
|
|
|
2
2
|
export interface StorageApiOptions {
|
|
3
3
|
/** Called when the user opens a file from the menu. */
|
|
4
4
|
onOpenFile(file: FileRecord, content: string): void;
|
|
5
|
+
/**
|
|
6
|
+
* Called when a `.bpmn.tests.json` sidecar is found alongside an opened BPMN file.
|
|
7
|
+
* The `bpmnFileName` is the name of the BPMN file (e.g. `"my-process.bpmn"`).
|
|
8
|
+
* The `content` is the raw JSON string of the sidecar.
|
|
9
|
+
*/
|
|
10
|
+
onSidecarFile?: (bpmnFileName: string, content: string) => void;
|
|
5
11
|
}
|
|
6
12
|
export declare class StorageApi {
|
|
7
13
|
private readonly _options;
|
|
@@ -247,6 +247,18 @@ export class StorageApi {
|
|
|
247
247
|
return;
|
|
248
248
|
this._currentFileId = fileId;
|
|
249
249
|
this._options.onOpenFile(file, content);
|
|
250
|
+
// Auto-discover sidecar .tests.json alongside BPMN files
|
|
251
|
+
if (file.type === "bpmn" && this._options.onSidecarFile !== undefined) {
|
|
252
|
+
const sidecarName = `${file.name}.tests.json`;
|
|
253
|
+
const projectFiles = await db.files.where("projectId").equals(file.projectId).toArray();
|
|
254
|
+
const sidecarFile = projectFiles.find((f) => f.name === sidecarName);
|
|
255
|
+
if (sidecarFile !== undefined) {
|
|
256
|
+
const sidecarContent = await this.getFileContent(sidecarFile.id);
|
|
257
|
+
if (sidecarContent !== null) {
|
|
258
|
+
this._options.onSidecarFile(file.name, sidecarContent);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
250
262
|
this._notify();
|
|
251
263
|
}
|
|
252
264
|
getCurrentFileId() {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const STYLE_ID = "bpmnkit-story-view-v1";
|
|
2
|
+
export declare const CSS = "\n/* \u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--bpmnkit-bg, #0d0d16);\n color: var(--bpmnkit-fg, #cdd6f4);\n font-family: var(--bpmnkit-font, system-ui, -apple-system, sans-serif);\n font-size: 13px;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);\n flex-shrink: 0;\n}\n.bpmnkit-sv-title {\n font-size: 14px;\n font-weight: 700;\n color: var(--bpmnkit-fg, #cdd6f4);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.bpmnkit-sv-back {\n font-size: 11px;\n padding: 3px 10px;\n border-radius: 5px;\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n background: var(--bpmnkit-surface-2, #1e1e2e);\n color: var(--bpmnkit-fg-muted, #8888a8);\n cursor: pointer;\n font-weight: 600;\n white-space: nowrap;\n}\n.bpmnkit-sv-back:hover {\n color: var(--bpmnkit-accent, #6b9df7);\n border-color: var(--bpmnkit-accent, #6b9df7);\n}\n\n/* \u2500\u2500 Content \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* \u2500\u2500 Lane \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-lane {\n margin-bottom: 20px;\n}\n.bpmnkit-sv-lane-header {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--bpmnkit-fg-muted, #8888a8);\n padding: 4px 0 8px;\n border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);\n margin-bottom: 10px;\n}\n.bpmnkit-sv-lane-cards {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-start;\n gap: 6px;\n}\n\n/* \u2500\u2500 Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-card {\n background: var(--bpmnkit-surface, #161626);\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n border-radius: 8px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.2);\n padding: 10px 12px;\n min-width: 120px;\n max-width: 200px;\n flex-shrink: 0;\n}\n.bpmnkit-sv-card--start { border-left: 3px solid var(--bpmnkit-success, #22c55e); }\n.bpmnkit-sv-card--end { border-left: 3px solid var(--bpmnkit-fg-muted, #8888a8); }\n.bpmnkit-sv-card--service { border-left: 3px solid var(--bpmnkit-accent, #6b9df7); }\n.bpmnkit-sv-card--user { border-left: 3px solid var(--bpmnkit-teal, #2dd4bf); }\n.bpmnkit-sv-card--gateway { border-left: 3px solid var(--bpmnkit-warn, #f59e0b); }\n.bpmnkit-sv-card--parallel { border-left: 3px solid var(--bpmnkit-fg-muted, #8888a8); }\n.bpmnkit-sv-card--subprocess { border-left: 3px solid #a78bfa; }\n.bpmnkit-sv-card--event { border-left: 3px solid var(--bpmnkit-accent, #6b9df7); }\n.bpmnkit-sv-card--task { border-left: 3px solid var(--bpmnkit-border, #2a2a42); }\n\n.bpmnkit-sv-card-header {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--bpmnkit-fg-muted, #8888a8);\n margin-bottom: 3px;\n}\n.bpmnkit-sv-card-body {\n font-size: 12px;\n font-weight: 500;\n color: var(--bpmnkit-fg, #cdd6f4);\n word-break: break-word;\n min-height: 16px;\n}\n\n/* \u2500\u2500 Arrow connector \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-arrow {\n color: var(--bpmnkit-fg-muted, #8888a8);\n font-size: 18px;\n align-self: center;\n flex-shrink: 0;\n padding: 0 2px;\n margin-top: 12px;\n}\n\n/* \u2500\u2500 Comment button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-comment-btn {\n display: inline-block;\n margin-top: 6px;\n font-size: 10px;\n padding: 2px 7px;\n border-radius: 4px;\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n background: transparent;\n color: var(--bpmnkit-fg-muted, #8888a8);\n cursor: pointer;\n}\n.bpmnkit-sv-comment-btn:hover {\n border-color: var(--bpmnkit-accent, #6b9df7);\n color: var(--bpmnkit-accent, #6b9df7);\n}\n\n/* \u2500\u2500 Comment panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-comment-panel {\n margin-top: 8px;\n border-top: 1px solid var(--bpmnkit-border, #2a2a42);\n padding-top: 8px;\n}\n.bpmnkit-sv-comment-item {\n padding: 4px 0;\n border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);\n}\n.bpmnkit-sv-comment-item:last-child {\n border-bottom: none;\n}\n.bpmnkit-sv-comment-text {\n font-size: 11px;\n color: var(--bpmnkit-fg, #cdd6f4);\n line-height: 1.45;\n}\n.bpmnkit-sv-comment-meta {\n font-size: 10px;\n color: var(--bpmnkit-fg-muted, #8888a8);\n margin-top: 2px;\n}\n.bpmnkit-sv-comment-input {\n width: 100%;\n margin-top: 6px;\n padding: 5px 8px;\n border-radius: 5px;\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n background: var(--bpmnkit-surface-2, #1e1e2e);\n color: var(--bpmnkit-fg, #cdd6f4);\n font-family: var(--bpmnkit-font, system-ui, -apple-system, sans-serif);\n font-size: 11px;\n resize: vertical;\n min-height: 50px;\n}\n.bpmnkit-sv-comment-submit {\n margin-top: 5px;\n font-size: 11px;\n padding: 3px 10px;\n border-radius: 5px;\n border: 1px solid var(--bpmnkit-accent, #6b9df7);\n background: var(--bpmnkit-accent-subtle, rgba(107,157,247,0.15));\n color: var(--bpmnkit-accent, #6b9df7);\n cursor: pointer;\n font-weight: 600;\n}\n.bpmnkit-sv-comment-submit:hover {\n background: var(--bpmnkit-accent, #6b9df7);\n color: #fff;\n}\n\n/* \u2500\u2500 Light theme overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-container {\n background: var(--bpmnkit-bg, #f4f4f8);\n color: var(--bpmnkit-fg, #1a1a2e);\n}\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card {\n background: var(--bpmnkit-surface, #ffffff);\n}\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card--start { border-left-color: var(--bpmnkit-success, #16a34a); }\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card--service { border-left-color: var(--bpmnkit-accent, #1a56db); }\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card--user { border-left-color: var(--bpmnkit-teal, #0d9488); }\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card--gateway { border-left-color: var(--bpmnkit-warn, #d97706); }\n[data-bpmnkit-theme=\"light\"] .bpmnkit-sv-card--subprocess { border-left-color: #7c3aed; }\n\n/* \u2500\u2500 Share/download button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-share {\n font-size: 11px;\n padding: 3px 10px;\n border-radius: 5px;\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n background: var(--bpmnkit-surface-2, #1e1e2e);\n color: var(--bpmnkit-fg-muted, #8888a8);\n cursor: pointer;\n font-weight: 600;\n white-space: nowrap;\n margin-left: auto;\n}\n.bpmnkit-sv-share:hover {\n color: var(--bpmnkit-accent, #6b9df7);\n border-color: var(--bpmnkit-accent, #6b9df7);\n}\n\n/* \u2500\u2500 Resolve button \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sv-comment-resolve {\n font-size: 10px;\n padding: 2px 7px;\n border-radius: 4px;\n border: 1px solid var(--bpmnkit-border, #2a2a42);\n background: transparent;\n color: var(--bpmnkit-fg-muted, #8888a8);\n cursor: pointer;\n margin-top: 3px;\n}\n.bpmnkit-sv-comment-resolve:hover {\n border-color: var(--bpmnkit-success, #22c55e);\n color: var(--bpmnkit-success, #22c55e);\n}\n.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-text {\n text-decoration: line-through;\n opacity: 0.5;\n}\n.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-meta {\n opacity: 0.5;\n}\n.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-resolve {\n border-color: var(--bpmnkit-success, #22c55e);\n color: var(--bpmnkit-success, #22c55e);\n}\n";
|
|
3
|
+
export declare function injectStoryViewStyles(): void;
|
|
4
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
export const STYLE_ID = "bpmnkit-story-view-v1";
|
|
2
|
+
export const CSS = `
|
|
3
|
+
/* ── Container ──────────────────────────────────────────────────────────────── */
|
|
4
|
+
.bpmnkit-sv-container {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
height: 100%;
|
|
8
|
+
background: var(--bpmnkit-bg, #0d0d16);
|
|
9
|
+
color: var(--bpmnkit-fg, #cdd6f4);
|
|
10
|
+
font-family: var(--bpmnkit-font, system-ui, -apple-system, sans-serif);
|
|
11
|
+
font-size: 13px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* ── Header ─────────────────────────────────────────────────────────────────── */
|
|
15
|
+
.bpmnkit-sv-header {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 10px;
|
|
19
|
+
padding: 10px 14px;
|
|
20
|
+
border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
21
|
+
flex-shrink: 0;
|
|
22
|
+
}
|
|
23
|
+
.bpmnkit-sv-title {
|
|
24
|
+
font-size: 14px;
|
|
25
|
+
font-weight: 700;
|
|
26
|
+
color: var(--bpmnkit-fg, #cdd6f4);
|
|
27
|
+
flex: 1;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
text-overflow: ellipsis;
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
}
|
|
32
|
+
.bpmnkit-sv-back {
|
|
33
|
+
font-size: 11px;
|
|
34
|
+
padding: 3px 10px;
|
|
35
|
+
border-radius: 5px;
|
|
36
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
37
|
+
background: var(--bpmnkit-surface-2, #1e1e2e);
|
|
38
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
font-weight: 600;
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
}
|
|
43
|
+
.bpmnkit-sv-back:hover {
|
|
44
|
+
color: var(--bpmnkit-accent, #6b9df7);
|
|
45
|
+
border-color: var(--bpmnkit-accent, #6b9df7);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* ── Content ────────────────────────────────────────────────────────────────── */
|
|
49
|
+
.bpmnkit-sv-content {
|
|
50
|
+
flex: 1;
|
|
51
|
+
overflow-y: auto;
|
|
52
|
+
padding: 16px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ── Lane ────────────────────────────────────────────────────────────────────── */
|
|
56
|
+
.bpmnkit-sv-lane {
|
|
57
|
+
margin-bottom: 20px;
|
|
58
|
+
}
|
|
59
|
+
.bpmnkit-sv-lane-header {
|
|
60
|
+
font-size: 10px;
|
|
61
|
+
font-weight: 700;
|
|
62
|
+
text-transform: uppercase;
|
|
63
|
+
letter-spacing: 0.06em;
|
|
64
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
65
|
+
padding: 4px 0 8px;
|
|
66
|
+
border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
67
|
+
margin-bottom: 10px;
|
|
68
|
+
}
|
|
69
|
+
.bpmnkit-sv-lane-cards {
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-wrap: wrap;
|
|
72
|
+
align-items: flex-start;
|
|
73
|
+
gap: 6px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ── Cards ───────────────────────────────────────────────────────────────────── */
|
|
77
|
+
.bpmnkit-sv-card {
|
|
78
|
+
background: var(--bpmnkit-surface, #161626);
|
|
79
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
80
|
+
border-radius: 8px;
|
|
81
|
+
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
|
|
82
|
+
padding: 10px 12px;
|
|
83
|
+
min-width: 120px;
|
|
84
|
+
max-width: 200px;
|
|
85
|
+
flex-shrink: 0;
|
|
86
|
+
}
|
|
87
|
+
.bpmnkit-sv-card--start { border-left: 3px solid var(--bpmnkit-success, #22c55e); }
|
|
88
|
+
.bpmnkit-sv-card--end { border-left: 3px solid var(--bpmnkit-fg-muted, #8888a8); }
|
|
89
|
+
.bpmnkit-sv-card--service { border-left: 3px solid var(--bpmnkit-accent, #6b9df7); }
|
|
90
|
+
.bpmnkit-sv-card--user { border-left: 3px solid var(--bpmnkit-teal, #2dd4bf); }
|
|
91
|
+
.bpmnkit-sv-card--gateway { border-left: 3px solid var(--bpmnkit-warn, #f59e0b); }
|
|
92
|
+
.bpmnkit-sv-card--parallel { border-left: 3px solid var(--bpmnkit-fg-muted, #8888a8); }
|
|
93
|
+
.bpmnkit-sv-card--subprocess { border-left: 3px solid #a78bfa; }
|
|
94
|
+
.bpmnkit-sv-card--event { border-left: 3px solid var(--bpmnkit-accent, #6b9df7); }
|
|
95
|
+
.bpmnkit-sv-card--task { border-left: 3px solid var(--bpmnkit-border, #2a2a42); }
|
|
96
|
+
|
|
97
|
+
.bpmnkit-sv-card-header {
|
|
98
|
+
font-size: 10px;
|
|
99
|
+
font-weight: 700;
|
|
100
|
+
text-transform: uppercase;
|
|
101
|
+
letter-spacing: 0.05em;
|
|
102
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
103
|
+
margin-bottom: 3px;
|
|
104
|
+
}
|
|
105
|
+
.bpmnkit-sv-card-body {
|
|
106
|
+
font-size: 12px;
|
|
107
|
+
font-weight: 500;
|
|
108
|
+
color: var(--bpmnkit-fg, #cdd6f4);
|
|
109
|
+
word-break: break-word;
|
|
110
|
+
min-height: 16px;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ── Arrow connector ─────────────────────────────────────────────────────────── */
|
|
114
|
+
.bpmnkit-sv-arrow {
|
|
115
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
116
|
+
font-size: 18px;
|
|
117
|
+
align-self: center;
|
|
118
|
+
flex-shrink: 0;
|
|
119
|
+
padding: 0 2px;
|
|
120
|
+
margin-top: 12px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* ── Comment button ─────────────────────────────────────────────────────────── */
|
|
124
|
+
.bpmnkit-sv-comment-btn {
|
|
125
|
+
display: inline-block;
|
|
126
|
+
margin-top: 6px;
|
|
127
|
+
font-size: 10px;
|
|
128
|
+
padding: 2px 7px;
|
|
129
|
+
border-radius: 4px;
|
|
130
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
131
|
+
background: transparent;
|
|
132
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
133
|
+
cursor: pointer;
|
|
134
|
+
}
|
|
135
|
+
.bpmnkit-sv-comment-btn:hover {
|
|
136
|
+
border-color: var(--bpmnkit-accent, #6b9df7);
|
|
137
|
+
color: var(--bpmnkit-accent, #6b9df7);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* ── Comment panel ─────────────────────────────────────────────────────────── */
|
|
141
|
+
.bpmnkit-sv-comment-panel {
|
|
142
|
+
margin-top: 8px;
|
|
143
|
+
border-top: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
144
|
+
padding-top: 8px;
|
|
145
|
+
}
|
|
146
|
+
.bpmnkit-sv-comment-item {
|
|
147
|
+
padding: 4px 0;
|
|
148
|
+
border-bottom: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
149
|
+
}
|
|
150
|
+
.bpmnkit-sv-comment-item:last-child {
|
|
151
|
+
border-bottom: none;
|
|
152
|
+
}
|
|
153
|
+
.bpmnkit-sv-comment-text {
|
|
154
|
+
font-size: 11px;
|
|
155
|
+
color: var(--bpmnkit-fg, #cdd6f4);
|
|
156
|
+
line-height: 1.45;
|
|
157
|
+
}
|
|
158
|
+
.bpmnkit-sv-comment-meta {
|
|
159
|
+
font-size: 10px;
|
|
160
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
161
|
+
margin-top: 2px;
|
|
162
|
+
}
|
|
163
|
+
.bpmnkit-sv-comment-input {
|
|
164
|
+
width: 100%;
|
|
165
|
+
margin-top: 6px;
|
|
166
|
+
padding: 5px 8px;
|
|
167
|
+
border-radius: 5px;
|
|
168
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
169
|
+
background: var(--bpmnkit-surface-2, #1e1e2e);
|
|
170
|
+
color: var(--bpmnkit-fg, #cdd6f4);
|
|
171
|
+
font-family: var(--bpmnkit-font, system-ui, -apple-system, sans-serif);
|
|
172
|
+
font-size: 11px;
|
|
173
|
+
resize: vertical;
|
|
174
|
+
min-height: 50px;
|
|
175
|
+
}
|
|
176
|
+
.bpmnkit-sv-comment-submit {
|
|
177
|
+
margin-top: 5px;
|
|
178
|
+
font-size: 11px;
|
|
179
|
+
padding: 3px 10px;
|
|
180
|
+
border-radius: 5px;
|
|
181
|
+
border: 1px solid var(--bpmnkit-accent, #6b9df7);
|
|
182
|
+
background: var(--bpmnkit-accent-subtle, rgba(107,157,247,0.15));
|
|
183
|
+
color: var(--bpmnkit-accent, #6b9df7);
|
|
184
|
+
cursor: pointer;
|
|
185
|
+
font-weight: 600;
|
|
186
|
+
}
|
|
187
|
+
.bpmnkit-sv-comment-submit:hover {
|
|
188
|
+
background: var(--bpmnkit-accent, #6b9df7);
|
|
189
|
+
color: #fff;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* ── Light theme overrides ─────────────────────────────────────────────────── */
|
|
193
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-container {
|
|
194
|
+
background: var(--bpmnkit-bg, #f4f4f8);
|
|
195
|
+
color: var(--bpmnkit-fg, #1a1a2e);
|
|
196
|
+
}
|
|
197
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card {
|
|
198
|
+
background: var(--bpmnkit-surface, #ffffff);
|
|
199
|
+
}
|
|
200
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card--start { border-left-color: var(--bpmnkit-success, #16a34a); }
|
|
201
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card--service { border-left-color: var(--bpmnkit-accent, #1a56db); }
|
|
202
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card--user { border-left-color: var(--bpmnkit-teal, #0d9488); }
|
|
203
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card--gateway { border-left-color: var(--bpmnkit-warn, #d97706); }
|
|
204
|
+
[data-bpmnkit-theme="light"] .bpmnkit-sv-card--subprocess { border-left-color: #7c3aed; }
|
|
205
|
+
|
|
206
|
+
/* ── Share/download button ─────────────────────────────────────────────────── */
|
|
207
|
+
.bpmnkit-sv-share {
|
|
208
|
+
font-size: 11px;
|
|
209
|
+
padding: 3px 10px;
|
|
210
|
+
border-radius: 5px;
|
|
211
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
212
|
+
background: var(--bpmnkit-surface-2, #1e1e2e);
|
|
213
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
214
|
+
cursor: pointer;
|
|
215
|
+
font-weight: 600;
|
|
216
|
+
white-space: nowrap;
|
|
217
|
+
margin-left: auto;
|
|
218
|
+
}
|
|
219
|
+
.bpmnkit-sv-share:hover {
|
|
220
|
+
color: var(--bpmnkit-accent, #6b9df7);
|
|
221
|
+
border-color: var(--bpmnkit-accent, #6b9df7);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* ── Resolve button ─────────────────────────────────────────────────────────── */
|
|
225
|
+
.bpmnkit-sv-comment-resolve {
|
|
226
|
+
font-size: 10px;
|
|
227
|
+
padding: 2px 7px;
|
|
228
|
+
border-radius: 4px;
|
|
229
|
+
border: 1px solid var(--bpmnkit-border, #2a2a42);
|
|
230
|
+
background: transparent;
|
|
231
|
+
color: var(--bpmnkit-fg-muted, #8888a8);
|
|
232
|
+
cursor: pointer;
|
|
233
|
+
margin-top: 3px;
|
|
234
|
+
}
|
|
235
|
+
.bpmnkit-sv-comment-resolve:hover {
|
|
236
|
+
border-color: var(--bpmnkit-success, #22c55e);
|
|
237
|
+
color: var(--bpmnkit-success, #22c55e);
|
|
238
|
+
}
|
|
239
|
+
.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-text {
|
|
240
|
+
text-decoration: line-through;
|
|
241
|
+
opacity: 0.5;
|
|
242
|
+
}
|
|
243
|
+
.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-meta {
|
|
244
|
+
opacity: 0.5;
|
|
245
|
+
}
|
|
246
|
+
.bpmnkit-sv-comment-item--resolved .bpmnkit-sv-comment-resolve {
|
|
247
|
+
border-color: var(--bpmnkit-success, #22c55e);
|
|
248
|
+
color: var(--bpmnkit-success, #22c55e);
|
|
249
|
+
}
|
|
250
|
+
`;
|
|
251
|
+
export function injectStoryViewStyles() {
|
|
252
|
+
if (document.getElementById(STYLE_ID) !== null)
|
|
253
|
+
return;
|
|
254
|
+
const style = document.createElement("style");
|
|
255
|
+
style.id = STYLE_ID;
|
|
256
|
+
style.textContent = CSS;
|
|
257
|
+
document.head.appendChild(style);
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=css.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CanvasPlugin } from "@bpmnkit/canvas";
|
|
2
|
+
export interface StoryComment {
|
|
3
|
+
id: string;
|
|
4
|
+
text: string;
|
|
5
|
+
author: string;
|
|
6
|
+
createdAt: number;
|
|
7
|
+
resolved?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface StoryViewOptions {
|
|
10
|
+
/** Container element to mount the story view into. */
|
|
11
|
+
container?: HTMLElement;
|
|
12
|
+
/** Called when user clicks "← Edit" to return to edit mode. */
|
|
13
|
+
onEditMode?: () => void;
|
|
14
|
+
/** Optional: return a plain English summary of a FEEL condition. Cache per condition. */
|
|
15
|
+
summarizeCondition?: (condition: string) => Promise<string>;
|
|
16
|
+
/** Returns a unique key for the current file (for comment persistence). */
|
|
17
|
+
getFileKey?: () => string | null;
|
|
18
|
+
/** Theme passed to renderStoryHtml. */
|
|
19
|
+
getTheme?: () => "dark" | "light";
|
|
20
|
+
/** Returns the author name to use when adding comments. Defaults to "You". */
|
|
21
|
+
getAuthorName?: () => string;
|
|
22
|
+
}
|
|
23
|
+
export interface StoryViewPlugin extends CanvasPlugin {
|
|
24
|
+
readonly name: "story-view";
|
|
25
|
+
/** Toggle button that switches between Story and Edit mode. */
|
|
26
|
+
readonly toggle: HTMLButtonElement;
|
|
27
|
+
/** Enter story mode programmatically. */
|
|
28
|
+
enterStoryMode(): void;
|
|
29
|
+
/** Exit story mode programmatically. */
|
|
30
|
+
exitStoryMode(): void;
|
|
31
|
+
}
|
|
32
|
+
export declare function createStoryViewPlugin(options?: StoryViewOptions): StoryViewPlugin;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { renderStoryHtml } from "@bpmnkit/core";
|
|
2
|
+
import { injectStoryViewStyles } from "./css.js";
|
|
3
|
+
// ── IndexedDB helpers ─────────────────────────────────────────────────────────
|
|
4
|
+
const SV_DB_NAME = "bpmnkit-story-view-v1";
|
|
5
|
+
const SV_STORE = "comments";
|
|
6
|
+
function openSvDb() {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
const req = indexedDB.open(SV_DB_NAME, 1);
|
|
9
|
+
req.onupgradeneeded = () => {
|
|
10
|
+
req.result.createObjectStore(SV_STORE);
|
|
11
|
+
};
|
|
12
|
+
req.onsuccess = () => resolve(req.result);
|
|
13
|
+
req.onerror = () => reject(req.error);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function loadComments(key) {
|
|
17
|
+
try {
|
|
18
|
+
const db = await openSvDb();
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const tx = db.transaction(SV_STORE, "readonly");
|
|
21
|
+
const req = tx.objectStore(SV_STORE).get(key);
|
|
22
|
+
req.onsuccess = () => resolve(req.result ?? []);
|
|
23
|
+
req.onerror = () => reject(req.error);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function saveComments(key, comments) {
|
|
31
|
+
try {
|
|
32
|
+
const db = await openSvDb();
|
|
33
|
+
await new Promise((resolve, reject) => {
|
|
34
|
+
const tx = db.transaction(SV_STORE, "readwrite");
|
|
35
|
+
const req = tx.objectStore(SV_STORE).put(comments, key);
|
|
36
|
+
req.onsuccess = () => resolve();
|
|
37
|
+
req.onerror = () => reject(req.error);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// ignore
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ── Plugin factory ────────────────────────────────────────────────────────────
|
|
45
|
+
export function createStoryViewPlugin(options) {
|
|
46
|
+
let canvasApi = null;
|
|
47
|
+
let currentDefs = null;
|
|
48
|
+
let storyActive = false;
|
|
49
|
+
const unsubs = [];
|
|
50
|
+
const conditionCache = new Map();
|
|
51
|
+
// Mounted story root
|
|
52
|
+
let storyRoot = null;
|
|
53
|
+
// Toggle button
|
|
54
|
+
const toggleEl = document.createElement("button");
|
|
55
|
+
toggleEl.textContent = "📖 Story";
|
|
56
|
+
toggleEl.className = "bpmnkit-sv-toggle";
|
|
57
|
+
// ── Comment panel per card ────────────────────────────────────────────────
|
|
58
|
+
async function buildCommentPanel(elementId, container) {
|
|
59
|
+
const fileKey = options?.getFileKey?.() ?? "_";
|
|
60
|
+
const commentKey = `${fileKey}:${elementId}`;
|
|
61
|
+
let comments = await loadComments(commentKey);
|
|
62
|
+
function renderComments() {
|
|
63
|
+
// Clear existing comment items (keep input/submit)
|
|
64
|
+
const existing = container.querySelectorAll(".bpmnkit-sv-comment-item");
|
|
65
|
+
for (const el of existing)
|
|
66
|
+
el.remove();
|
|
67
|
+
const input = container.querySelector(".bpmnkit-sv-comment-input");
|
|
68
|
+
for (const c of comments) {
|
|
69
|
+
const item = document.createElement("div");
|
|
70
|
+
item.className = c.resolved
|
|
71
|
+
? "bpmnkit-sv-comment-item bpmnkit-sv-comment-item--resolved"
|
|
72
|
+
: "bpmnkit-sv-comment-item";
|
|
73
|
+
const textEl = document.createElement("div");
|
|
74
|
+
textEl.className = "bpmnkit-sv-comment-text";
|
|
75
|
+
textEl.textContent = c.text;
|
|
76
|
+
const meta = document.createElement("div");
|
|
77
|
+
meta.className = "bpmnkit-sv-comment-meta";
|
|
78
|
+
meta.textContent = `${c.author} · ${new Date(c.createdAt).toLocaleString()}`;
|
|
79
|
+
const resolveBtn = document.createElement("button");
|
|
80
|
+
resolveBtn.className = "bpmnkit-sv-comment-resolve";
|
|
81
|
+
resolveBtn.textContent = c.resolved ? "Unresolve" : "Resolve";
|
|
82
|
+
resolveBtn.addEventListener("click", async () => {
|
|
83
|
+
comments = comments.map((x) => (x.id === c.id ? { ...x, resolved: !x.resolved } : x));
|
|
84
|
+
await saveComments(commentKey, comments);
|
|
85
|
+
renderComments();
|
|
86
|
+
});
|
|
87
|
+
item.appendChild(textEl);
|
|
88
|
+
item.appendChild(meta);
|
|
89
|
+
item.appendChild(resolveBtn);
|
|
90
|
+
// Insert before the input
|
|
91
|
+
if (input !== null) {
|
|
92
|
+
container.insertBefore(item, input);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
container.appendChild(item);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const inputEl = document.createElement("textarea");
|
|
100
|
+
inputEl.className = "bpmnkit-sv-comment-input";
|
|
101
|
+
inputEl.placeholder = "Add a comment…";
|
|
102
|
+
const submitEl = document.createElement("button");
|
|
103
|
+
submitEl.className = "bpmnkit-sv-comment-submit";
|
|
104
|
+
submitEl.textContent = "Add";
|
|
105
|
+
submitEl.addEventListener("click", async () => {
|
|
106
|
+
const text = inputEl.value.trim();
|
|
107
|
+
if (!text)
|
|
108
|
+
return;
|
|
109
|
+
const comment = {
|
|
110
|
+
id: `c-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
|
|
111
|
+
text,
|
|
112
|
+
author: options?.getAuthorName?.() ?? "You",
|
|
113
|
+
createdAt: Date.now(),
|
|
114
|
+
};
|
|
115
|
+
comments = [...comments, comment];
|
|
116
|
+
await saveComments(commentKey, comments);
|
|
117
|
+
inputEl.value = "";
|
|
118
|
+
renderComments();
|
|
119
|
+
updateBadge();
|
|
120
|
+
});
|
|
121
|
+
container.appendChild(inputEl);
|
|
122
|
+
container.appendChild(submitEl);
|
|
123
|
+
renderComments();
|
|
124
|
+
function updateBadge() {
|
|
125
|
+
const btn = container.closest(".bpmnkit-sv-card")?.querySelector(".bpmnkit-sv-comment-btn");
|
|
126
|
+
if (btn !== null && btn !== undefined) {
|
|
127
|
+
btn.textContent = comments.length > 0 ? `💬 ${comments.length}` : "💬";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ── Wire comment buttons in story HTML ───────────────────────────────────
|
|
132
|
+
async function wireCommentButtons(root) {
|
|
133
|
+
const cards = root.querySelectorAll("[data-bpmnkit-id]");
|
|
134
|
+
for (const card of cards) {
|
|
135
|
+
const elementId = card.getAttribute("data-bpmnkit-id");
|
|
136
|
+
if (!elementId)
|
|
137
|
+
continue;
|
|
138
|
+
const fileKey = options?.getFileKey?.() ?? "_";
|
|
139
|
+
const commentKey = `${fileKey}:${elementId}`;
|
|
140
|
+
const comments = await loadComments(commentKey);
|
|
141
|
+
const btn = document.createElement("button");
|
|
142
|
+
btn.className = "bpmnkit-sv-comment-btn";
|
|
143
|
+
btn.textContent = comments.length > 0 ? `💬 ${comments.length}` : "💬";
|
|
144
|
+
let panelOpen = false;
|
|
145
|
+
let panelEl = null;
|
|
146
|
+
btn.addEventListener("click", async () => {
|
|
147
|
+
panelOpen = !panelOpen;
|
|
148
|
+
if (panelOpen) {
|
|
149
|
+
panelEl = document.createElement("div");
|
|
150
|
+
panelEl.className = "bpmnkit-sv-comment-panel";
|
|
151
|
+
await buildCommentPanel(elementId, panelEl);
|
|
152
|
+
card.appendChild(panelEl);
|
|
153
|
+
}
|
|
154
|
+
else if (panelEl !== null) {
|
|
155
|
+
panelEl.remove();
|
|
156
|
+
panelEl = null;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
card.appendChild(btn);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ── AI condition summarizer ──────────────────────────────────────────────
|
|
163
|
+
async function applyConditionSummaries(root) {
|
|
164
|
+
if (!options?.summarizeCondition)
|
|
165
|
+
return;
|
|
166
|
+
const conditionExprs = root.querySelectorAll(".bks-condition-expr");
|
|
167
|
+
for (const el of conditionExprs) {
|
|
168
|
+
const original = el.textContent ?? "";
|
|
169
|
+
if (!original)
|
|
170
|
+
continue;
|
|
171
|
+
const cached = conditionCache.get(original);
|
|
172
|
+
if (cached !== undefined) {
|
|
173
|
+
el.title = original;
|
|
174
|
+
el.textContent = cached;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
options
|
|
178
|
+
.summarizeCondition(original)
|
|
179
|
+
.then((summary) => {
|
|
180
|
+
conditionCache.set(original, summary);
|
|
181
|
+
el.title = original;
|
|
182
|
+
el.textContent = summary;
|
|
183
|
+
})
|
|
184
|
+
.catch(() => {
|
|
185
|
+
// leave as-is on error
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ── Enter / exit story mode ──────────────────────────────────────────────
|
|
190
|
+
function enterStoryMode() {
|
|
191
|
+
if (storyActive)
|
|
192
|
+
return;
|
|
193
|
+
storyActive = true;
|
|
194
|
+
toggleEl.classList.add("bpmnkit-sv-toggle--active");
|
|
195
|
+
const defs = currentDefs;
|
|
196
|
+
const theme = options?.getTheme?.() ?? "dark";
|
|
197
|
+
const container = options?.container ?? canvasApi?.container;
|
|
198
|
+
if (!container)
|
|
199
|
+
return;
|
|
200
|
+
const html = defs !== null ? renderStoryHtml(defs, { standalone: false, theme }) : "";
|
|
201
|
+
storyRoot = document.createElement("div");
|
|
202
|
+
storyRoot.className = "bpmnkit-sv-container";
|
|
203
|
+
if (theme === "light")
|
|
204
|
+
storyRoot.setAttribute("data-bpmnkit-theme", "light");
|
|
205
|
+
// Header
|
|
206
|
+
const header = document.createElement("div");
|
|
207
|
+
header.className = "bpmnkit-sv-header";
|
|
208
|
+
const title = document.createElement("div");
|
|
209
|
+
title.className = "bpmnkit-sv-title";
|
|
210
|
+
title.textContent = defs?.processes[0]?.name ?? "Process Story";
|
|
211
|
+
const backBtn = document.createElement("button");
|
|
212
|
+
backBtn.className = "bpmnkit-sv-back";
|
|
213
|
+
backBtn.textContent = "← Edit";
|
|
214
|
+
backBtn.addEventListener("click", () => exitStoryMode());
|
|
215
|
+
header.appendChild(backBtn);
|
|
216
|
+
header.appendChild(title);
|
|
217
|
+
const shareBtn = document.createElement("button");
|
|
218
|
+
shareBtn.className = "bpmnkit-sv-share";
|
|
219
|
+
shareBtn.textContent = "\u2193 Download";
|
|
220
|
+
shareBtn.addEventListener("click", () => {
|
|
221
|
+
if (defs === null)
|
|
222
|
+
return;
|
|
223
|
+
const storyHtml = renderStoryHtml(defs, { standalone: true, theme });
|
|
224
|
+
const blob = new Blob([storyHtml], { type: "text/html" });
|
|
225
|
+
const url = URL.createObjectURL(blob);
|
|
226
|
+
const a = document.createElement("a");
|
|
227
|
+
a.href = url;
|
|
228
|
+
a.download = `${defs.processes[0]?.name ?? "process"}-story.html`;
|
|
229
|
+
a.click();
|
|
230
|
+
URL.revokeObjectURL(url);
|
|
231
|
+
});
|
|
232
|
+
header.appendChild(shareBtn);
|
|
233
|
+
// Content
|
|
234
|
+
const content = document.createElement("div");
|
|
235
|
+
content.className = "bpmnkit-sv-content";
|
|
236
|
+
content.innerHTML = html;
|
|
237
|
+
storyRoot.appendChild(header);
|
|
238
|
+
storyRoot.appendChild(content);
|
|
239
|
+
container.appendChild(storyRoot);
|
|
240
|
+
wireCommentButtons(content).catch(() => undefined);
|
|
241
|
+
applyConditionSummaries(content).catch(() => undefined);
|
|
242
|
+
}
|
|
243
|
+
function exitStoryMode() {
|
|
244
|
+
if (!storyActive)
|
|
245
|
+
return;
|
|
246
|
+
storyActive = false;
|
|
247
|
+
toggleEl.classList.remove("bpmnkit-sv-toggle--active");
|
|
248
|
+
if (storyRoot !== null) {
|
|
249
|
+
storyRoot.remove();
|
|
250
|
+
storyRoot = null;
|
|
251
|
+
}
|
|
252
|
+
options?.onEditMode?.();
|
|
253
|
+
}
|
|
254
|
+
toggleEl.addEventListener("click", () => {
|
|
255
|
+
if (storyActive) {
|
|
256
|
+
exitStoryMode();
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
enterStoryMode();
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
name: "story-view",
|
|
264
|
+
toggle: toggleEl,
|
|
265
|
+
enterStoryMode,
|
|
266
|
+
exitStoryMode,
|
|
267
|
+
install(api) {
|
|
268
|
+
canvasApi = api;
|
|
269
|
+
injectStoryViewStyles();
|
|
270
|
+
const onAny = api.on;
|
|
271
|
+
unsubs.push(onAny("diagram:load", (arg) => {
|
|
272
|
+
const defs = arg?.definitions ?? null;
|
|
273
|
+
currentDefs = defs;
|
|
274
|
+
if (storyActive) {
|
|
275
|
+
exitStoryMode();
|
|
276
|
+
enterStoryMode();
|
|
277
|
+
}
|
|
278
|
+
}));
|
|
279
|
+
unsubs.push(onAny("diagram:change", (arg) => {
|
|
280
|
+
const defs = arg?.definitions ?? null;
|
|
281
|
+
if (defs !== null)
|
|
282
|
+
currentDefs = defs;
|
|
283
|
+
}));
|
|
284
|
+
},
|
|
285
|
+
uninstall() {
|
|
286
|
+
exitStoryMode();
|
|
287
|
+
for (const unsub of unsubs)
|
|
288
|
+
unsub();
|
|
289
|
+
unsubs.length = 0;
|
|
290
|
+
canvasApi = null;
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=index.js.map
|