@principal-ai/subsystems-react 0.28.1 → 0.28.3
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/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts +7 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +7 -201
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/WalkthroughsPanel.d.ts +53 -0
- package/dist/subsystem/WalkthroughsPanel.d.ts.map +1 -0
- package/dist/subsystem/WalkthroughsPanel.js +371 -0
- package/dist/subsystem/WalkthroughsPanel.js.map +1 -0
- package/dist/subsystem/model.d.ts +15 -0
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js +28 -0
- package/dist/subsystem/model.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/stories/Subsystem/ComponentGraph/ProposedWalkthroughs.stories.tsx +165 -0
- package/src/stories/Subsystem/ComponentGraph/Reorder.stories.tsx +204 -0
- package/src/subsystem/SubsystemComponentGraph.tsx +36 -319
- package/src/subsystem/WalkthroughsPanel.tsx +628 -0
- package/src/subsystem/model.test.ts +76 -1
- package/src/subsystem/model.ts +31 -0
|
@@ -29,8 +29,10 @@ import {
|
|
|
29
29
|
packageColor,
|
|
30
30
|
subsystemGraphLayoutKey,
|
|
31
31
|
describeConstructBreakdown,
|
|
32
|
+
reorderWalkthroughs,
|
|
33
|
+
reorderTargetIndex,
|
|
32
34
|
} from './model';
|
|
33
|
-
import type { SubsystemComponent, SubsystemComponentEdge } from './model';
|
|
35
|
+
import type { SubsystemComponent, SubsystemComponentEdge, SubsystemWalkthrough } from './model';
|
|
34
36
|
|
|
35
37
|
const comps: SubsystemComponent[] = [
|
|
36
38
|
{ alias: 'reader', name: 'SessionReader', construct: 'class', file: 'SessionReader.ts', purl: 'pkg:github/principal-ai/agent-monitoring' },
|
|
@@ -793,3 +795,76 @@ describe('module badge labels', () => {
|
|
|
793
795
|
expect(moduleBadgeWidth('src/…/nodes.tsx')).toBeLessThan(moduleBadgeWidth('packages/…/nodes.tsx'));
|
|
794
796
|
});
|
|
795
797
|
});
|
|
798
|
+
|
|
799
|
+
describe('reorderWalkthroughs', () => {
|
|
800
|
+
const wts: SubsystemWalkthrough[] = [
|
|
801
|
+
{ id: 'a', title: 'A', steps: [] },
|
|
802
|
+
{ id: 'b', title: 'B', steps: [] },
|
|
803
|
+
{ id: 'c', title: 'C', steps: [] },
|
|
804
|
+
];
|
|
805
|
+
const ids = (list: SubsystemWalkthrough[]) => list.map((w) => w.id);
|
|
806
|
+
|
|
807
|
+
test('moves an item forward to the target index', () => {
|
|
808
|
+
expect(ids(reorderWalkthroughs(wts, 0, 2))).toEqual(['b', 'c', 'a']);
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
test('moves an item backward to the target index', () => {
|
|
812
|
+
expect(ids(reorderWalkthroughs(wts, 2, 0))).toEqual(['c', 'a', 'b']);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
test('returns a new array and leaves the input untouched', () => {
|
|
816
|
+
const next = reorderWalkthroughs(wts, 1, 2);
|
|
817
|
+
expect(next).not.toBe(wts);
|
|
818
|
+
expect(ids(wts)).toEqual(['a', 'b', 'c']);
|
|
819
|
+
expect(ids(next)).toEqual(['a', 'c', 'b']);
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
test('no-op when source and target match', () => {
|
|
823
|
+
expect(ids(reorderWalkthroughs(wts, 1, 1))).toEqual(['a', 'b', 'c']);
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
test('out-of-range source returns a shallow copy unchanged', () => {
|
|
827
|
+
const next = reorderWalkthroughs(wts, 5, 0);
|
|
828
|
+
expect(next).not.toBe(wts);
|
|
829
|
+
expect(ids(next)).toEqual(['a', 'b', 'c']);
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
test('clamps a target beyond the end to the last slot', () => {
|
|
833
|
+
expect(ids(reorderWalkthroughs(wts, 0, 99))).toEqual(['b', 'c', 'a']);
|
|
834
|
+
});
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
describe('reorderTargetIndex', () => {
|
|
838
|
+
// Boundaries are the n+1 gaps between rows: 0 is above row 0, n is below
|
|
839
|
+
// the last row. Dragging row `from` to boundary `b` lands it at b, minus one
|
|
840
|
+
// when b is past from (removing the row shifts later gaps down).
|
|
841
|
+
test('dragging down past a row lands after it', () => {
|
|
842
|
+
expect(reorderTargetIndex(2, 0)).toBe(1);
|
|
843
|
+
expect(reorderTargetIndex(3, 0)).toBe(2);
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
test('dragging up lands at the boundary', () => {
|
|
847
|
+
expect(reorderTargetIndex(0, 2)).toBe(0);
|
|
848
|
+
expect(reorderTargetIndex(1, 2)).toBe(1);
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
test('the boundaries around the dragged row are no-ops', () => {
|
|
852
|
+
expect(reorderTargetIndex(1, 1)).toBe(1);
|
|
853
|
+
expect(reorderTargetIndex(2, 1)).toBe(1);
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
test('dropping the first row above itself is a no-op', () => {
|
|
857
|
+
expect(reorderTargetIndex(0, 0)).toBe(0);
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
test('composes with reorderWalkthroughs to match the indicator', () => {
|
|
861
|
+
const wts: SubsystemWalkthrough[] = [
|
|
862
|
+
{ id: 'a', title: 'A', steps: [] },
|
|
863
|
+
{ id: 'b', title: 'B', steps: [] },
|
|
864
|
+
{ id: 'c', title: 'C', steps: [] },
|
|
865
|
+
];
|
|
866
|
+
// Drag A onto the gap below B (boundary 2) → A lands between B and C.
|
|
867
|
+
const target = reorderTargetIndex(2, 0);
|
|
868
|
+
expect(reorderWalkthroughs(wts, 0, target).map((w) => w.id)).toEqual(['b', 'a', 'c']);
|
|
869
|
+
});
|
|
870
|
+
});
|
package/src/subsystem/model.ts
CHANGED
|
@@ -349,6 +349,37 @@ export function walkthroughStepGraphEdgeId(
|
|
|
349
349
|
return derivedGraphEdgeId(step.from, step.to, step.mechanism);
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Move one walkthrough from `from` to `to`, returning a new array. Used by the
|
|
354
|
+
* flows panel's drag-to-reorder: the array order is the walkthroughs' display
|
|
355
|
+
* order, so a reorder is just an array splice. Out-of-range `from` returns a
|
|
356
|
+
* shallow copy unchanged; `to` is clamped into range.
|
|
357
|
+
*/
|
|
358
|
+
export function reorderWalkthroughs(
|
|
359
|
+
walkthroughs: readonly SubsystemWalkthrough[],
|
|
360
|
+
from: number,
|
|
361
|
+
to: number,
|
|
362
|
+
): SubsystemWalkthrough[] {
|
|
363
|
+
const next = [...walkthroughs];
|
|
364
|
+
if (!Number.isInteger(from) || from < 0 || from >= next.length) return next;
|
|
365
|
+
const target = Math.max(0, Math.min(to, next.length - 1));
|
|
366
|
+
if (target === from) return next;
|
|
367
|
+
const [moved] = next.splice(from, 1);
|
|
368
|
+
if (moved) next.splice(target, 0, moved);
|
|
369
|
+
return next;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Final index for a drag-reorder given the insertion `boundary` (one of the
|
|
374
|
+
* `n + 1` gaps between rows) and the dragged row's `from` index. Removing the
|
|
375
|
+
* dragged row shifts every boundary after it down one, so a boundary past
|
|
376
|
+
* `from` maps to `boundary - 1`. Feed the result to `reorderWalkthroughs` as
|
|
377
|
+
* `to`; a result equal to `from` is a no-op.
|
|
378
|
+
*/
|
|
379
|
+
export function reorderTargetIndex(boundary: number, from: number): number {
|
|
380
|
+
return boundary - (boundary > from ? 1 : 0);
|
|
381
|
+
}
|
|
382
|
+
|
|
352
383
|
export function deriveGraphEdges(doc: {
|
|
353
384
|
relations?: readonly SubsystemRelation[];
|
|
354
385
|
walkthroughs?: readonly SubsystemWalkthrough[];
|