@anlyx/ui 0.1.2 → 0.1.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/components/AnalysisEvidenceList.d.ts +5 -0
- package/dist/components/AnalysisEvidenceList.js +61 -0
- package/dist/components/AnlyxAppShell.d.ts +1 -1
- package/dist/components/AnlyxAppShell.js +16 -7
- package/dist/components/ApiCallList.d.ts +3 -2
- package/dist/components/ApiCallList.js +12 -2
- package/dist/components/EndpointMapCanvas.js +1 -1
- package/dist/components/FlowStoryView.d.ts +22 -0
- package/dist/components/FlowStoryView.js +117 -0
- package/dist/components/InspectorPanel.d.ts +1 -1
- package/dist/components/InspectorPanel.js +20 -1
- package/dist/components/PageStoryboardView.js +9 -1
- package/dist/components/ProcessFlowView.js +8 -1
- package/dist/components/ReplayControls.d.ts +2 -1
- package/dist/components/ReplayControls.js +29 -2
- package/dist/components/Sidebar.d.ts +2 -2
- package/dist/components/Sidebar.js +15 -3
- package/dist/mock-data.js +50 -4
- package/dist/overlay/AnlyxFlowEdge.d.ts +2 -0
- package/dist/overlay/AnlyxFlowEdge.js +15 -0
- package/dist/overlay/AnlyxFlowNode.d.ts +13 -0
- package/dist/overlay/AnlyxFlowNode.js +28 -0
- package/dist/overlay/FlowDrawer.d.ts +2 -0
- package/dist/overlay/FlowDrawer.js +59 -0
- package/dist/overlay/MainFlowCanvas.d.ts +20 -0
- package/dist/overlay/MainFlowCanvas.js +285 -0
- package/dist/overlay/RecentApiEventsTable.d.ts +5 -0
- package/dist/overlay/RecentApiEventsTable.js +19 -0
- package/dist/overlay/overlay-entry.d.ts +8 -0
- package/dist/overlay/overlay-entry.js +14 -0
- package/dist/overlay/overlay-ui.css +2 -0
- package/dist/overlay/overlay-ui.js +14 -0
- package/dist/overlay/types.d.ts +38 -0
- package/dist/overlay/types.js +1 -0
- package/dist/overlay/ui.d.ts +18 -0
- package/dist/overlay/ui.js +13 -0
- package/dist/readme-demo/ReadmeDemoApp.d.ts +4 -0
- package/dist/readme-demo/ReadmeDemoApp.js +126 -0
- package/dist/readme-demo/readme-demo-entry.d.ts +1 -0
- package/dist/readme-demo/readme-demo-entry.js +8 -0
- package/dist/styles.css +1134 -20
- package/dist/viewer/ViewerApp.js +13 -6
- package/package.json +3 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Endpoint, EndpointFlow, PageStoryboard } from "@anlyx/core";
|
|
2
|
+
export type OverlayAction = {
|
|
3
|
+
id?: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
selector?: string;
|
|
7
|
+
};
|
|
8
|
+
export type OverlayApiEvent = {
|
|
9
|
+
id: string;
|
|
10
|
+
method: string;
|
|
11
|
+
path: string;
|
|
12
|
+
status: string | number;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
count?: number;
|
|
15
|
+
lastSeenAt?: number;
|
|
16
|
+
source?: "action" | "background" | "health";
|
|
17
|
+
triggeredBy?: OverlayAction | null;
|
|
18
|
+
matchedEndpoint?: Endpoint | null;
|
|
19
|
+
matchedFlow?: EndpointFlow | null;
|
|
20
|
+
matchedPages?: PageStoryboard[];
|
|
21
|
+
};
|
|
22
|
+
export type OverlayScannedHint = {
|
|
23
|
+
pageRoute: string;
|
|
24
|
+
pageFilePath?: string;
|
|
25
|
+
method: string;
|
|
26
|
+
path: string;
|
|
27
|
+
endpointId?: string;
|
|
28
|
+
endpointLabel?: string;
|
|
29
|
+
evidence: "scanned-page" | "capture";
|
|
30
|
+
};
|
|
31
|
+
export type FlowDrawerProps = {
|
|
32
|
+
selectedEvent: OverlayApiEvent | null;
|
|
33
|
+
events: OverlayApiEvent[];
|
|
34
|
+
latestAction?: OverlayAction | null;
|
|
35
|
+
scannedHints?: OverlayScannedHint[];
|
|
36
|
+
loadError?: string | null;
|
|
37
|
+
runtimeBaseUrl?: string;
|
|
38
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export declare function Card({ children, className }: {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
export declare function Badge({ children, tone, className }: {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
tone?: "blue" | "green" | "amber" | "violet" | "gray" | "neutral";
|
|
9
|
+
className?: string;
|
|
10
|
+
}): JSX.Element;
|
|
11
|
+
export declare function Tooltip({ children, content }: {
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
content: string;
|
|
14
|
+
}): JSX.Element;
|
|
15
|
+
export declare function Table({ children, className }: {
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
className?: string;
|
|
18
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export function Card({ children, className = "" }) {
|
|
3
|
+
return _jsx("div", { className: `anlyx-ov-card ${className}`.trim(), children: children });
|
|
4
|
+
}
|
|
5
|
+
export function Badge({ children, tone = "neutral", className = "" }) {
|
|
6
|
+
return (_jsx("span", { className: `anlyx-ov-badge anlyx-ov-badge--${tone} ${className}`.trim(), children: children }));
|
|
7
|
+
}
|
|
8
|
+
export function Tooltip({ children, content }) {
|
|
9
|
+
return _jsx("span", { title: content, children: children });
|
|
10
|
+
}
|
|
11
|
+
export function Table({ children, className = "" }) {
|
|
12
|
+
return _jsx("table", { className: `anlyx-ov-table ${className}`.trim(), children: children });
|
|
13
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "@xyflow/react/dist/style.css";
|
|
3
|
+
import "../overlay/overlay.css";
|
|
4
|
+
import "./readme-demo.css";
|
|
5
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
import { FlowDrawer } from "../overlay/FlowDrawer.js";
|
|
7
|
+
const demoOrder = ["search", "detail", "save", "admin"];
|
|
8
|
+
const flows = {
|
|
9
|
+
search: makeFlow("GET", "/api/public/search", [
|
|
10
|
+
["endpoint:search", "endpoint", "GET /api/public/search"],
|
|
11
|
+
["controller:search", "controller", "PublicViewController#search"],
|
|
12
|
+
["service:search", "service", "SearchIndexService#find"],
|
|
13
|
+
["repository:search", "repository", "BenefitSearchRepository#query"],
|
|
14
|
+
["database:search", "database", "benefits_search_index"]
|
|
15
|
+
]),
|
|
16
|
+
detail: makeFlow("GET", "/api/public/benefits/{id}", [
|
|
17
|
+
["endpoint:detail", "endpoint", "GET /api/public/benefits/{id}"],
|
|
18
|
+
["controller:detail", "controller", "PublicBenefitController#getDetail"],
|
|
19
|
+
["service:detail", "service", "PublicBenefitService#getDetail"],
|
|
20
|
+
["repository:detail", "repository", "BenefitRepository#findById"],
|
|
21
|
+
["database:detail", "database", "benefits"]
|
|
22
|
+
]),
|
|
23
|
+
save: makeFlow("POST", "/api/account/saved-benefits", [
|
|
24
|
+
["endpoint:save", "endpoint", "POST /api/account/saved-benefits"],
|
|
25
|
+
["controller:save", "controller", "SavedBenefitController#create"],
|
|
26
|
+
["service:save", "service", "SavedBenefitService#save"],
|
|
27
|
+
["repository:save", "repository", "SavedBenefitRepository#insert"],
|
|
28
|
+
["database:save", "database", "saved_benefit"]
|
|
29
|
+
]),
|
|
30
|
+
admin: makeFlow("POST", "/api/admin/benefits", [
|
|
31
|
+
["endpoint:admin", "endpoint", "POST /api/admin/benefits"],
|
|
32
|
+
["controller:admin", "controller", "AdminBenefitController#create"],
|
|
33
|
+
["policy:admin", "validator", "AdminRolePolicy#check"],
|
|
34
|
+
["service:admin", "service", "AdminBenefitService#create"],
|
|
35
|
+
["repository:admin", "repository", "BenefitRepository#save"]
|
|
36
|
+
])
|
|
37
|
+
};
|
|
38
|
+
const endpoints = {
|
|
39
|
+
search: endpoint("GET", "/api/public/search", "PublicViewController#search"),
|
|
40
|
+
detail: endpoint("GET", "/api/public/benefits/{id}", "PublicBenefitController#getDetail"),
|
|
41
|
+
save: endpoint("POST", "/api/account/saved-benefits", "SavedBenefitController#create"),
|
|
42
|
+
admin: endpoint("POST", "/api/admin/benefits", "AdminBenefitController#create")
|
|
43
|
+
};
|
|
44
|
+
const events = {
|
|
45
|
+
search: event("search", "GET", "/api/public/search", 200, 28, "Clicked Search benefits"),
|
|
46
|
+
detail: event("detail", "GET", "/api/public/benefits/123", 200, 34, "Opened benefit detail"),
|
|
47
|
+
save: event("save", "POST", "/api/account/saved-benefits", 401, 31, "Clicked Save to my box"),
|
|
48
|
+
admin: event("admin", "POST", "/api/admin/benefits", 403, 42, "Clicked Try admin action")
|
|
49
|
+
};
|
|
50
|
+
Object.entries(events).forEach(([key, value]) => {
|
|
51
|
+
const demoKey = key;
|
|
52
|
+
value.matchedEndpoint = endpoints[demoKey];
|
|
53
|
+
value.matchedFlow = flows[demoKey];
|
|
54
|
+
});
|
|
55
|
+
export function ReadmeDemoApp() {
|
|
56
|
+
const [selectedKey, setSelectedKey] = useState("save");
|
|
57
|
+
const selectedEvent = events[selectedKey];
|
|
58
|
+
const eventList = useMemo(() => [
|
|
59
|
+
selectedEvent,
|
|
60
|
+
{
|
|
61
|
+
id: "background-account",
|
|
62
|
+
method: "GET",
|
|
63
|
+
path: "/api/account/me",
|
|
64
|
+
status: 401,
|
|
65
|
+
durationMs: 19,
|
|
66
|
+
count: 3,
|
|
67
|
+
source: "background",
|
|
68
|
+
matchedEndpoint: endpoint("GET", "/api/account/me", "AccountController#me"),
|
|
69
|
+
matchedFlow: null
|
|
70
|
+
},
|
|
71
|
+
...demoOrder.filter((key) => key !== selectedKey).map((key) => events[key])
|
|
72
|
+
], [selectedEvent, selectedKey]);
|
|
73
|
+
return (_jsxs("main", { className: "anlyx-readme-demo", children: [_jsxs("section", { className: "anlyx-readme-demo__control", children: [_jsx("div", { className: "anlyx-readme-demo__logo-card", children: _jsx("img", { src: "/docs/assets/brand/anlyx-logo-card.png", alt: "Anlyx" }) }), _jsxs("div", { children: [_jsx("p", { className: "anlyx-readme-demo__eyebrow", children: "Real Anlyx UI demo" }), _jsx("h1", { children: "Click an action. Watch the drawer remap the backend flow." }), _jsxs("p", { children: ["This README animation renders the actual Anlyx Flow Drawer component from", _jsx("code", { children: "@anlyx/ui" }), "."] })] }), _jsxs("div", { className: "anlyx-readme-demo__actions", "aria-label": "Demo actions", children: [_jsx(DemoButton, { active: selectedKey === "search", label: "Search benefits", meta: "GET /api/public/search", onClick: () => setSelectedKey("search"), demoKey: "search" }), _jsx(DemoButton, { active: selectedKey === "detail", label: "Open benefit detail", meta: "GET /api/public/benefits/{id}", onClick: () => setSelectedKey("detail"), demoKey: "detail" }), _jsx(DemoButton, { active: selectedKey === "save", label: "Save to my box", meta: "POST /api/account/saved-benefits", onClick: () => setSelectedKey("save"), demoKey: "save" }), _jsx(DemoButton, { active: selectedKey === "admin", label: "Try admin action", meta: "POST /api/admin/benefits", onClick: () => setSelectedKey("admin"), demoKey: "admin" })] })] }), _jsxs("section", { className: "anlyx-readme-demo__drawer-shell", "aria-label": "Anlyx Flow Drawer", children: [_jsxs("header", { className: "anlyx-readme-demo__drawer-head", children: [_jsxs("div", { className: "anlyx-readme-demo__drawer-brand", children: [_jsx("img", { src: "/docs/assets/brand/anlyx-icon-card.png", alt: "" }), _jsxs("div", { children: [_jsx("strong", { children: "Anlyx Flow Drawer" }), _jsx("span", { children: "Actual component preview" })] })] }), _jsxs("div", { className: "anlyx-readme-demo__drawer-tools", children: [_jsx("span", { children: "Live" }), _jsx("span", { children: "matched" })] })] }), _jsx(FlowDrawer, { events: eventList, latestAction: selectedEvent.triggeredBy ?? null, scannedHints: [], selectedEvent: selectedEvent })] })] }));
|
|
74
|
+
}
|
|
75
|
+
function DemoButton({ active, label, meta, onClick, demoKey }) {
|
|
76
|
+
return (_jsxs("button", { "aria-pressed": active, className: "anlyx-readme-demo__action", "data-demo": demoKey, type: "button", onClick: onClick, children: [_jsx("strong", { children: label }), _jsx("span", { children: meta })] }));
|
|
77
|
+
}
|
|
78
|
+
function makeFlow(method, path, nodes) {
|
|
79
|
+
const mainPath = nodes.map(([id]) => id);
|
|
80
|
+
return {
|
|
81
|
+
endpointId: `${method}:${path}`,
|
|
82
|
+
nodes: nodes.map(([id, type, label]) => ({
|
|
83
|
+
id,
|
|
84
|
+
type,
|
|
85
|
+
label,
|
|
86
|
+
confidence: "high"
|
|
87
|
+
})),
|
|
88
|
+
edges: mainPath.slice(1).map((to, index) => ({
|
|
89
|
+
id: `edge:${mainPath[index]}:${to}`,
|
|
90
|
+
from: mainPath[index] ?? "",
|
|
91
|
+
to,
|
|
92
|
+
kind: "main",
|
|
93
|
+
confidence: "high"
|
|
94
|
+
})),
|
|
95
|
+
mainPath,
|
|
96
|
+
subFlows: []
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function endpoint(method, path, handler) {
|
|
100
|
+
return {
|
|
101
|
+
id: `${method}:${path}`,
|
|
102
|
+
method,
|
|
103
|
+
path,
|
|
104
|
+
supportLevel: "deep",
|
|
105
|
+
handler,
|
|
106
|
+
confidence: "high"
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function event(id, method, path, status, durationMs, label) {
|
|
110
|
+
return {
|
|
111
|
+
id,
|
|
112
|
+
method,
|
|
113
|
+
path,
|
|
114
|
+
status,
|
|
115
|
+
durationMs,
|
|
116
|
+
count: id === "save" ? 2 : 1,
|
|
117
|
+
source: "action",
|
|
118
|
+
triggeredBy: {
|
|
119
|
+
type: "Clicked",
|
|
120
|
+
label,
|
|
121
|
+
selector: `button[data-demo="${id}"]`
|
|
122
|
+
},
|
|
123
|
+
matchedEndpoint: null,
|
|
124
|
+
matchedFlow: null
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { ReadmeDemoApp } from "./ReadmeDemoApp.js";
|
|
4
|
+
const root = document.getElementById("root");
|
|
5
|
+
if (!root) {
|
|
6
|
+
throw new Error("Missing #root for Anlyx README demo");
|
|
7
|
+
}
|
|
8
|
+
createRoot(root).render(_jsx(ReadmeDemoApp, {}));
|