@nice2dev/ui-diagrams 1.3.16 → 1.3.17

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/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @nice2dev/ui-diagrams — Changelog
2
2
 
3
+ ## 1.3.17
4
+
5
+ ### Patch Changes
6
+
7
+ - 8ae6e97: NiceWorkflowDesigner moves to `@nice2dev/ui-diagrams` (showcase feedback round 41):
8
+
9
+ - **Moved** (breaking for imports): `import { NiceWorkflowDesigner } from '@nice2dev/ui-diagrams'`. The data types
10
+ (`NiceWorkflowDefinition`, `NiceWorkflowState`, `NiceWorkflowTransition`…) stay in `@nice2dev/ui`;
11
+ `NiceWorkflowState.type` also takes ids of your own step kinds.
12
+ - Rebuilt on the diagram canvas: **arrows** between the steps, **automatic layered layout** (left to right, or
13
+ `layoutDirection="TB"`), the whole flow **fitted to the canvas at start**, zoom − / % / + and Fit in the toolbar,
14
+ wheel zoom, pan by dragging the empty canvas.
15
+ - **Step kinds**: `stepTypes` (default start, state, approval, end, error) and `loadStepTypes` (loaded at mount,
16
+ merged by id); "Add step" offers them all.
17
+ - A new step gets a **unique name** and comes **connected from the selected step** (the duplicated "New state"
18
+ dead-end / orphan pair is gone); transitions are drawn from a step's port onto another step or edited in the
19
+ properties panel (name, target, add, delete); a selected transition has its own panel; a problem message selects
20
+ its step.
21
+ - The designer keeps the workflow itself; `onChange` reports every change with the laid-out positions.
22
+
23
+ NiceDiagramEditor, more configurable (backward compatible): `document` (controlled), `nodeTypes` (a palette),
24
+ `autoLayout`, `fitOnMount`, `readOnly`; connections drawn from the ports (`onEdgeCreate` was declared but never
25
+ called); `onChange` fires for every change (only undo / redo reached it — the editor hook memoised on a document the
26
+ model edits in place, which also froze the viewport and the undo state) and no longer during render; `lang` follows
27
+ the app's language by default. DiagramCanvas: `autoFit` / `fitKey` / `refitKey`, `resizable`, `panOnDrag`,
28
+ `onResize`, `ariaLabel`, per-instance arrow markers, curves that leave and enter along their ports' sides, labels on
29
+ the curve's middle. The `dagre` layout is a real layered layout now (cycle breaking, longest-path ranks, barycenter
30
+ ordering, top-left positions, `ranks` in the result); `fitViewport` / `diagramBounds` exported; a layout is one undo
31
+ step.
32
+
33
+ ui-forms: the studio's workflow screen uses the designer from `@nice2dev/ui-diagrams` (new peer dependency).
34
+
3
35
  ## 1.3.16
4
36
 
5
37
  No changes in this release.
@@ -20,8 +20,32 @@ export interface DiagramCanvasProps {
20
20
  onNodeDragEnd?: (nodeId: string, position: Point) => void;
21
21
  /** Node resize (editor only) */
22
22
  onNodeResize?: (nodeId: string, size: Size, position: Point) => void;
23
- /** Edge creation (editor only) */
24
- onEdgeCreate?: (sourceNodeId: string, targetNodeId: string) => void;
23
+ /**
24
+ * Edge creation (editor only): a drag from a node's port dropped on another node. With it the
25
+ * ports start connections; the ports are the ones dragged from and nearest to the drop.
26
+ */
27
+ onEdgeCreate?: (sourceNodeId: string, targetNodeId: string, sourcePortId?: string, targetPortId?: string) => void;
28
+ /**
29
+ * Fit the whole diagram in view (1.3.17): at mount, when the canvas resizes and when `fitKey`
30
+ * changes — until the user zooms or pans; a new `fitKey` after that waits for `refitKey`.
31
+ */
32
+ autoFit?: boolean;
33
+ /** Change it to fit again, e.g. after an automatic layout. */
34
+ fitKey?: string | number;
35
+ /** Change it to fit now, also after the user zoomed or panned (a "Fit" button). */
36
+ refitKey?: string | number;
37
+ /** Margin of the fit in screen pixels (default 40). */
38
+ fitPadding?: number;
39
+ /** Largest zoom of the fit (default 1.25). */
40
+ fitMaxZoom?: number;
41
+ /** Called with the canvas size in pixels whenever it changes. */
42
+ onResize?: (size: Size) => void;
43
+ /** Show resize handles on the selected node (default true). */
44
+ resizable?: boolean;
45
+ /** A left drag on the empty canvas pans it, instead of a selection rectangle (default false). */
46
+ panOnDrag?: boolean;
47
+ /** The canvas's accessible name. */
48
+ ariaLabel?: string;
25
49
  /** In-place text editing */
26
50
  onNodeLabelChange?: (nodeId: string, label: string) => void;
27
51
  /** Animation states (viewer only) */
@@ -1,17 +1,42 @@
1
1
  import { NiceComponentTutorial } from '@nice2dev/ui';
2
2
  import { default as React } from 'react';
3
- import { NiceDiagramDocument, DiagramType } from '../types/diagramTypes';
3
+ import { NiceDiagramDocument, NiceDiagramNodeType, DiagramType, LayoutOptions } from '../types/diagramTypes';
4
4
  export interface NiceDiagramEditorProps {
5
5
  /** Initial document (optional — empty diagram created if omitted) */
6
6
  initialDocument?: NiceDiagramDocument;
7
+ /**
8
+ * The document, controlled (1.3.17): a new one replaces what the editor shows. Every change
9
+ * still comes through `onChange` — pass back what it gives.
10
+ */
11
+ document?: NiceDiagramDocument;
12
+ /**
13
+ * The kinds of node to offer (1.3.17): a palette above the canvas, each entry adding a node with
14
+ * its label, shape, size, style, icon and ports (and `data.nodeType`).
15
+ */
16
+ nodeTypes?: NiceDiagramNodeType[];
17
+ /**
18
+ * Lay the nodes out after every structural change — a node or an edge added or removed
19
+ * (1.3.17). Dragging nodes is off then. `true`: layered, left to right.
20
+ */
21
+ autoLayout?: boolean | LayoutOptions;
22
+ /**
23
+ * Fit the whole diagram in view at mount, on resize and after each automatic layout, until the
24
+ * user zooms or pans (1.3.17). The toolbar's reset-zoom button fits again.
25
+ */
26
+ fitOnMount?: boolean;
27
+ /** View only (1.3.17): no toolbar, property panel, dragging or connecting. */
28
+ readOnly?: boolean;
7
29
  /** Diagram type when creating empty (default: flowchart) */
8
30
  diagramType?: DiagramType;
9
31
  /** Fires on every document change */
10
32
  onChange?: (doc: Readonly<NiceDiagramDocument>) => void;
11
33
  /** Export callback (called when user exports via toolbar) */
12
34
  onExport?: (format: string, content: string) => void;
13
- /** Language (default: en) */
14
- lang?: 'en' | 'pl';
35
+ /**
36
+ * Language of the editor's own texts. Default: the app's (its global NiceI18nProvider) — it
37
+ * was English whatever the app used, before 1.3.17.
38
+ */
39
+ lang?: string;
15
40
  /** Show/hide panels */
16
41
  showToolbar?: boolean;
17
42
  showPropertyPanel?: boolean;
@@ -0,0 +1,72 @@
1
+ import { NiceBaseProps, NiceComponentTutorial, NiceFieldDescriptor, NiceRoleInfo, NiceUserInfo, NiceWorkflowActionType, NiceWorkflowDefinition } from '@nice2dev/ui';
2
+ import { default as React } from 'react';
3
+ import { NodeShape } from '../types/diagramTypes';
4
+ /** What a kind of step means to the validation and the simulation. */
5
+ export type NiceWorkflowStepRole = 'initial' | 'step' | 'final' | 'error';
6
+ /** A kind of step of the {@link NiceWorkflowDesigner} — `state.type` holds its id. */
7
+ export interface NiceWorkflowStepType {
8
+ id: string;
9
+ /** The "Add step" entry, the new step's name and the caption under every step's name. */
10
+ label: string;
11
+ /** A NiceIcon name. */
12
+ icon?: string;
13
+ /** The step's border — any CSS colour, a theme variable best (`var(--nice-color-primary)`). */
14
+ color?: string;
15
+ shape?: NodeShape;
16
+ /**
17
+ * Default: `initial`, `final` and `error` for the ids of the same name, `step` otherwise. A
18
+ * workflow needs one initial and at least one final step; final and error steps may end it.
19
+ */
20
+ role?: NiceWorkflowStepRole;
21
+ /** Shown in the "Add step" menu. */
22
+ description?: string;
23
+ }
24
+ /** Props for {@link NiceWorkflowDesigner}. */
25
+ export interface NiceWorkflowDesignerProps extends NiceBaseProps {
26
+ workflow?: NiceWorkflowDefinition;
27
+ /** Convenience: flat node list mapped into `workflow.states` when `workflow` is omitted. */
28
+ nodes?: Array<{
29
+ id: string;
30
+ type?: string;
31
+ label?: string;
32
+ name?: string;
33
+ x?: number;
34
+ y?: number;
35
+ }>;
36
+ /** Convenience: flat edge list mapped into `workflow.transitions` when `workflow` is omitted. */
37
+ edges?: Array<{
38
+ id?: string;
39
+ from?: string;
40
+ to?: string;
41
+ source?: string;
42
+ target?: string;
43
+ fromStateId?: string;
44
+ toStateId?: string;
45
+ name?: string;
46
+ label?: string;
47
+ }>;
48
+ /**
49
+ * Every change. The designer keeps the workflow itself, so it works without this too; a
50
+ * `workflow` that differs from the last one it gave out replaces what it shows.
51
+ */
52
+ onChange?: (workflow: NiceWorkflowDefinition) => void;
53
+ entityFields?: NiceFieldDescriptor[];
54
+ availableActions?: NiceWorkflowActionType[];
55
+ availableUsers?: NiceUserInfo[];
56
+ availableRoles?: NiceRoleInfo[];
57
+ readOnly?: boolean;
58
+ showMinimap?: boolean;
59
+ showToolbar?: boolean;
60
+ showValidation?: boolean;
61
+ onTest?: (workflow: NiceWorkflowDefinition) => void;
62
+ onPublish?: (workflow: NiceWorkflowDefinition) => void;
63
+ /** Optional "?" guided tour. Off by default; `true` uses the built-in tour. */
64
+ tutorial?: NiceComponentTutorial;
65
+ /** The kinds of step (default: start, state, approval, end, error). */
66
+ stepTypes?: NiceWorkflowStepType[];
67
+ /** More kinds of step, loaded once at mount and merged by id over `stepTypes`. */
68
+ loadStepTypes?: () => Promise<NiceWorkflowStepType[]>;
69
+ /** Which way the flow runs (default `'LR'`, left to right). */
70
+ layoutDirection?: 'LR' | 'TB';
71
+ }
72
+ export declare const NiceWorkflowDesigner: React.FC<NiceWorkflowDesignerProps>;
@@ -24,6 +24,11 @@ export declare class DiagramModel {
24
24
  canRedo(): boolean;
25
25
  addNode(label: string, position: Point, shape?: NodeShape, size?: Size): DiagramNode;
26
26
  updateNode(id: string, patch: Partial<Omit<DiagramNode, 'id'>>): void;
27
+ /**
28
+ * Moves several nodes in one go (a layout) — one undo step, or none with `recordHistory: false`
29
+ * (an automatic layout that follows every change: undoing the change lays it out again).
30
+ */
31
+ moveNodes(positions: ReadonlyMap<string, Point>, recordHistory?: boolean): void;
27
32
  moveNode(id: string, position: Point): void;
28
33
  resizeNode(id: string, size: Size): void;
29
34
  removeNode(id: string): void;
@@ -1,6 +1,9 @@
1
1
  import { DiagramNode as _DiagramNode, DiagramEdge as _DiagramEdge, LayoutOptions, Point as _Point } from '../types/diagramTypes';
2
2
  export interface LayoutResult {
3
+ /** Top-left corner of each node. */
3
4
  positions: Map<string, _Point>;
5
+ /** The layered layouts (`dagre`, `tree`): the rank (layer) of each node, 0 first. */
6
+ ranks?: Map<string, number>;
4
7
  }
5
8
  /**
6
9
  * Apply an auto-layout algorithm and return computed positions.
@@ -0,0 +1,20 @@
1
+ import { DiagramNode, DiagramViewport, Size } from '../types/diagramTypes';
2
+ /** A rectangle in diagram coordinates. */
3
+ export interface DiagramBounds {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ }
9
+ /** The box around the nodes (hidden ones left out), `null` without any. */
10
+ export declare function diagramBounds(nodes: readonly DiagramNode[]): DiagramBounds | null;
11
+ export interface FitViewportOptions {
12
+ /** Margin around the content, in screen pixels (default 40). */
13
+ padding?: number;
14
+ /** Never zoom in further than this (default 1.25): a small diagram is not blown up. */
15
+ maxZoom?: number;
16
+ /** Never zoom out further than this (default 0.1). */
17
+ minZoom?: number;
18
+ }
19
+ /** The viewport that shows `bounds` whole and centred in a canvas of `size`. */
20
+ export declare function fitViewport(bounds: DiagramBounds | null, size: Size, options?: FitViewportOptions): DiagramViewport;
@@ -46,7 +46,10 @@ export interface UseDiagramEditorReturn {
46
46
  setViewMode: (mode: DiagramViewMode) => void;
47
47
  viewMode: DiagramViewMode;
48
48
  /** Layout */
49
- applyLayout: (options: LayoutOptions) => void;
49
+ /** Lays the nodes out — one undo step, or none with '{ history: false }'. */
50
+ applyLayout: (options: LayoutOptions, opts?: {
51
+ history?: boolean;
52
+ }) => void;
50
53
  /** Viewport */
51
54
  setViewport: (viewport: DiagramViewport) => void;
52
55
  /** Undo/redo */
@@ -58,5 +61,10 @@ export interface UseDiagramEditorReturn {
58
61
  loadDocument: (doc: NiceDiagramDocument) => void;
59
62
  /** Model ref */
60
63
  model: DiagramModel;
64
+ /**
65
+ * Grows with every change. The model edits its document in place, so the document keeps its
66
+ * identity: watch this to react to changes (1.3.17).
67
+ */
68
+ revision: number;
61
69
  }
62
70
  export declare function useDiagramEditor(initialDoc?: NiceDiagramDocument): UseDiagramEditorReturn;