@anyshift/backstage-plugin-anyshift 0.1.0-beta.1

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +176 -0
  3. package/README.md +9 -0
  4. package/dist/api/AnyshiftApi.esm.js +80 -0
  5. package/dist/api/AnyshiftApi.esm.js.map +1 -0
  6. package/dist/components/AnyshiftPermissionBoundary.esm.js +25 -0
  7. package/dist/components/AnyshiftPermissionBoundary.esm.js.map +1 -0
  8. package/dist/components/entity/AnyshiftEntityContent.esm.js +213 -0
  9. package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -0
  10. package/dist/components/entity/BriefSections.esm.js +218 -0
  11. package/dist/components/entity/BriefSections.esm.js.map +1 -0
  12. package/dist/components/entity/DatadogLiveSignal.esm.js +190 -0
  13. package/dist/components/entity/DatadogLiveSignal.esm.js.map +1 -0
  14. package/dist/components/entity/EvidenceDisclosure.esm.js +20 -0
  15. package/dist/components/entity/EvidenceDisclosure.esm.js.map +1 -0
  16. package/dist/components/entity/MermaidArchitecture.esm.js +89 -0
  17. package/dist/components/entity/MermaidArchitecture.esm.js.map +1 -0
  18. package/dist/components/entity/SectionPresenters.esm.js +341 -0
  19. package/dist/components/entity/SectionPresenters.esm.js.map +1 -0
  20. package/dist/components/entity/architectureDiagram.esm.js +236 -0
  21. package/dist/components/entity/architectureDiagram.esm.js.map +1 -0
  22. package/dist/components/entity/sectionData.esm.js +127 -0
  23. package/dist/components/entity/sectionData.esm.js.map +1 -0
  24. package/dist/components/explorer/AnyshiftExplorerPage.esm.js +193 -0
  25. package/dist/components/explorer/AnyshiftExplorerPage.esm.js.map +1 -0
  26. package/dist/components/explorer/DatadogOperationsRadar.esm.js +294 -0
  27. package/dist/components/explorer/DatadogOperationsRadar.esm.js.map +1 -0
  28. package/dist/index.d.ts +127 -0
  29. package/dist/index.esm.js +4 -0
  30. package/dist/index.esm.js.map +1 -0
  31. package/dist/package.json.esm.js +96 -0
  32. package/dist/package.json.esm.js.map +1 -0
  33. package/dist/plugin.esm.js +49 -0
  34. package/dist/plugin.esm.js.map +1 -0
  35. package/dist/routes.esm.js +6 -0
  36. package/dist/routes.esm.js.map +1 -0
  37. package/package.json +84 -0
@@ -0,0 +1,218 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { Box, Grid, Typography, Button, CircularProgress } from '@material-ui/core';
3
+ import { InfoCard } from '@backstage/core-components';
4
+ import { OverviewPresenter, ArchitecturePresenter, DependencyFootprintPresenter, OperationalPosturePresenter, LatestChangePresenter, SafeguardsPresenter, TimelinePresenter } from './SectionPresenters.esm.js';
5
+ import { DatadogSignalStripPresenter } from './DatadogLiveSignal.esm.js';
6
+
7
+ const OverviewSection = ({
8
+ section,
9
+ onRetry,
10
+ refreshing
11
+ }) => /* @__PURE__ */ jsx(InfoCard, { noPadding: true, children: /* @__PURE__ */ jsx(Box, { px: 2, py: 2, children: /* @__PURE__ */ jsx(
12
+ DataSection,
13
+ {
14
+ section,
15
+ onRetry: () => onRetry("overview"),
16
+ refreshing,
17
+ renderData: (data) => /* @__PURE__ */ jsx(OverviewPresenter, { data })
18
+ }
19
+ ) }) });
20
+ const DependencySection = ({
21
+ section,
22
+ onRetry,
23
+ refreshing
24
+ }) => /* @__PURE__ */ jsx(
25
+ SectionCard,
26
+ {
27
+ title: "Dependency footprint",
28
+ subheader: "Direct traffic and transitive reach",
29
+ children: /* @__PURE__ */ jsx(
30
+ DataSection,
31
+ {
32
+ section,
33
+ onRetry: () => onRetry("topology"),
34
+ refreshing,
35
+ renderData: (data) => /* @__PURE__ */ jsx(DependencyFootprintPresenter, { data })
36
+ }
37
+ )
38
+ }
39
+ );
40
+ const DatadogSignalSection = ({
41
+ section,
42
+ onRetry,
43
+ refreshing
44
+ }) => /* @__PURE__ */ jsx(InfoCard, { noPadding: true, children: section.state === "data" && section.data !== void 0 ? /* @__PURE__ */ jsx(
45
+ DataSection,
46
+ {
47
+ section,
48
+ onRetry: () => onRetry("observability"),
49
+ refreshing,
50
+ renderData: (data) => /* @__PURE__ */ jsx(DatadogSignalStripPresenter, { data })
51
+ }
52
+ ) : /* @__PURE__ */ jsx(Box, { px: 2, py: 1.5, children: /* @__PURE__ */ jsx(
53
+ DataSection,
54
+ {
55
+ section,
56
+ onRetry: () => onRetry("observability"),
57
+ refreshing,
58
+ renderData: (data) => /* @__PURE__ */ jsx(DatadogSignalStripPresenter, { data })
59
+ }
60
+ ) }) });
61
+ const BriefRail = ({
62
+ brief,
63
+ onRetry,
64
+ refreshing = /* @__PURE__ */ new Set()
65
+ }) => /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
66
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
67
+ CompactSection,
68
+ {
69
+ title: "Operational posture",
70
+ section: brief.impact,
71
+ onRetry: () => onRetry("impact"),
72
+ refreshing: refreshing.has("impact"),
73
+ renderData: (data) => /* @__PURE__ */ jsx(OperationalPosturePresenter, { data })
74
+ }
75
+ ) }),
76
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
77
+ CompactSection,
78
+ {
79
+ title: "Latest change",
80
+ section: brief.latestChange,
81
+ onRetry: () => onRetry("latestChange"),
82
+ refreshing: refreshing.has("latestChange"),
83
+ renderData: (data) => /* @__PURE__ */ jsx(LatestChangePresenter, { data })
84
+ }
85
+ ) }),
86
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
87
+ CompactSection,
88
+ {
89
+ title: "Runtime safeguards",
90
+ section: brief.safeguards,
91
+ onRetry: () => onRetry("safeguards"),
92
+ refreshing: refreshing.has("safeguards"),
93
+ renderData: (data) => /* @__PURE__ */ jsx(SafeguardsPresenter, { data })
94
+ }
95
+ ) })
96
+ ] });
97
+ const TimelineSection = ({
98
+ section,
99
+ onRetry,
100
+ refreshing
101
+ }) => /* @__PURE__ */ jsx(
102
+ SectionCard,
103
+ {
104
+ title: "Change intelligence",
105
+ subheader: "Runtime changes in the last 24 hours",
106
+ children: /* @__PURE__ */ jsx(
107
+ DataSection,
108
+ {
109
+ section,
110
+ onRetry: () => onRetry("timeline"),
111
+ refreshing,
112
+ renderData: (data) => /* @__PURE__ */ jsx(TimelinePresenter, { data })
113
+ }
114
+ )
115
+ }
116
+ );
117
+ const ArchitectureSection = ({
118
+ section,
119
+ onRetry,
120
+ refreshing
121
+ }) => /* @__PURE__ */ jsx(SectionCard, { title: "Service map", subheader: "Cross-layer C4 graph evidence", children: /* @__PURE__ */ jsx(
122
+ DataSection,
123
+ {
124
+ section,
125
+ onRetry: () => onRetry("architecture"),
126
+ refreshing,
127
+ renderData: (data) => /* @__PURE__ */ jsx(ArchitecturePresenter, { data })
128
+ }
129
+ ) });
130
+ const SectionCard = ({
131
+ title,
132
+ subheader,
133
+ children
134
+ }) => /* @__PURE__ */ jsx(
135
+ InfoCard,
136
+ {
137
+ title: /* @__PURE__ */ jsx(Typography, { component: "h2", variant: "h5", children: title }),
138
+ subheader,
139
+ children
140
+ }
141
+ );
142
+ const CompactSection = ({
143
+ title,
144
+ section,
145
+ onRetry,
146
+ refreshing,
147
+ renderData
148
+ }) => /* @__PURE__ */ jsx(
149
+ InfoCard,
150
+ {
151
+ title: /* @__PURE__ */ jsx(Typography, { component: "h2", variant: "h5", children: title }),
152
+ noPadding: true,
153
+ children: /* @__PURE__ */ jsx(Box, { p: 2, children: /* @__PURE__ */ jsx(
154
+ DataSection,
155
+ {
156
+ section,
157
+ onRetry,
158
+ refreshing,
159
+ renderData
160
+ }
161
+ ) })
162
+ }
163
+ );
164
+ const DataSection = ({
165
+ section,
166
+ onRetry,
167
+ refreshing,
168
+ renderData
169
+ }) => {
170
+ if (section.state === "data" && section.data !== void 0) {
171
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
172
+ renderData(section.data),
173
+ section.retryable && /* @__PURE__ */ jsx(RetryControl, { onRetry, refreshing })
174
+ ] });
175
+ }
176
+ return /* @__PURE__ */ jsx(
177
+ SectionStateContent,
178
+ {
179
+ section,
180
+ onRetry,
181
+ refreshing
182
+ }
183
+ );
184
+ };
185
+ const SectionStateContent = ({
186
+ section,
187
+ onRetry,
188
+ refreshing
189
+ }) => /* @__PURE__ */ jsxs(Fragment, { children: [
190
+ /* @__PURE__ */ jsx(
191
+ Typography,
192
+ {
193
+ color: section.state === "error" ? "error" : "textSecondary",
194
+ variant: "body2",
195
+ children: section.message || "No graph evidence is available."
196
+ }
197
+ ),
198
+ section.retryable && /* @__PURE__ */ jsx(RetryControl, { onRetry, refreshing })
199
+ ] });
200
+ const RetryControl = ({
201
+ onRetry,
202
+ refreshing
203
+ }) => /* @__PURE__ */ jsx(
204
+ Button,
205
+ {
206
+ type: "button",
207
+ variant: "outlined",
208
+ size: "small",
209
+ onClick: onRetry,
210
+ disabled: refreshing,
211
+ startIcon: refreshing ? /* @__PURE__ */ jsx(CircularProgress, { size: 14 }) : void 0,
212
+ style: { marginTop: 8 },
213
+ children: refreshing ? "Retrying\u2026" : "Retry"
214
+ }
215
+ );
216
+
217
+ export { ArchitectureSection, BriefRail, DatadogSignalSection, DependencySection, OverviewSection, TimelineSection };
218
+ //# sourceMappingURL=BriefSections.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BriefSections.esm.js","sources":["../../../src/components/entity/BriefSections.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport {\n Box,\n Button,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { InfoCard } from '@backstage/core-components';\nimport type {\n BriefSection,\n BriefSectionName,\n SafeguardResult,\n ServiceBrief,\n ServiceOverview,\n} from '../../api/types';\nimport {\n ArchitecturePresenter,\n DependencyFootprintPresenter,\n LatestChangePresenter,\n OperationalPosturePresenter,\n OverviewPresenter,\n SafeguardsPresenter,\n TimelinePresenter,\n} from './SectionPresenters';\nimport { DatadogSignalStripPresenter } from './DatadogLiveSignal';\n\nexport type RetrySection = (section: BriefSectionName) => void;\n\nexport const OverviewSection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection<ServiceOverview>;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <InfoCard noPadding>\n <Box px={2} py={2}>\n <DataSection\n section={section}\n onRetry={() => onRetry('overview')}\n refreshing={refreshing}\n renderData={data => <OverviewPresenter data={data} />}\n />\n </Box>\n </InfoCard>\n);\n\nexport const DependencySection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <SectionCard\n title=\"Dependency footprint\"\n subheader=\"Direct traffic and transitive reach\"\n >\n <DataSection\n section={section}\n onRetry={() => onRetry('topology')}\n refreshing={refreshing}\n renderData={data => <DependencyFootprintPresenter data={data} />}\n />\n </SectionCard>\n);\n\nexport const DatadogSignalSection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <InfoCard noPadding>\n {section.state === 'data' && section.data !== undefined ? (\n <DataSection\n section={section}\n onRetry={() => onRetry('observability')}\n refreshing={refreshing}\n renderData={data => <DatadogSignalStripPresenter data={data} />}\n />\n ) : (\n <Box px={2} py={1.5}>\n <DataSection\n section={section}\n onRetry={() => onRetry('observability')}\n refreshing={refreshing}\n renderData={data => <DatadogSignalStripPresenter data={data} />}\n />\n </Box>\n )}\n </InfoCard>\n);\n\nexport const BriefRail = ({\n brief,\n onRetry,\n refreshing = new Set(),\n}: {\n brief: ServiceBrief;\n onRetry: RetrySection;\n refreshing?: ReadonlySet<BriefSectionName>;\n}) => (\n <Grid container spacing={2}>\n <Grid item xs={12}>\n <CompactSection\n title=\"Operational posture\"\n section={brief.impact}\n onRetry={() => onRetry('impact')}\n refreshing={refreshing.has('impact')}\n renderData={data => <OperationalPosturePresenter data={data} />}\n />\n </Grid>\n <Grid item xs={12}>\n <CompactSection\n title=\"Latest change\"\n section={brief.latestChange}\n onRetry={() => onRetry('latestChange')}\n refreshing={refreshing.has('latestChange')}\n renderData={data => <LatestChangePresenter data={data} />}\n />\n </Grid>\n <Grid item xs={12}>\n <CompactSection<SafeguardResult[]>\n title=\"Runtime safeguards\"\n section={brief.safeguards}\n onRetry={() => onRetry('safeguards')}\n refreshing={refreshing.has('safeguards')}\n renderData={data => <SafeguardsPresenter data={data} />}\n />\n </Grid>\n </Grid>\n);\n\nexport const TimelineSection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <SectionCard\n title=\"Change intelligence\"\n subheader=\"Runtime changes in the last 24 hours\"\n >\n <DataSection\n section={section}\n onRetry={() => onRetry('timeline')}\n refreshing={refreshing}\n renderData={data => <TimelinePresenter data={data} />}\n />\n </SectionCard>\n);\n\nexport const ArchitectureSection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <SectionCard title=\"Service map\" subheader=\"Cross-layer C4 graph evidence\">\n <DataSection\n section={section}\n onRetry={() => onRetry('architecture')}\n refreshing={refreshing}\n renderData={data => <ArchitecturePresenter data={data} />}\n />\n </SectionCard>\n);\n\nconst SectionCard = ({\n title,\n subheader,\n children,\n}: {\n title: string;\n subheader?: string;\n children: ReactNode;\n}) => (\n <InfoCard\n title={\n <Typography component=\"h2\" variant=\"h5\">\n {title}\n </Typography>\n }\n subheader={subheader}\n >\n {children}\n </InfoCard>\n);\n\nconst CompactSection = <T,>({\n title,\n section,\n onRetry,\n refreshing,\n renderData,\n}: {\n title: string;\n section: BriefSection<T>;\n onRetry: () => void;\n refreshing?: boolean;\n renderData: (data: T) => ReactNode;\n}) => (\n <InfoCard\n title={\n <Typography component=\"h2\" variant=\"h5\">\n {title}\n </Typography>\n }\n noPadding\n >\n <Box p={2}>\n <DataSection\n section={section}\n onRetry={onRetry}\n refreshing={refreshing}\n renderData={renderData}\n />\n </Box>\n </InfoCard>\n);\n\nconst DataSection = <T,>({\n section,\n onRetry,\n refreshing,\n renderData,\n}: {\n section: BriefSection<T>;\n onRetry: () => void;\n refreshing?: boolean;\n renderData: (data: T) => ReactNode;\n}) => {\n if (section.state === 'data' && section.data !== undefined) {\n return (\n <>\n {renderData(section.data)}\n {section.retryable && (\n <RetryControl onRetry={onRetry} refreshing={refreshing} />\n )}\n </>\n );\n }\n return (\n <SectionStateContent\n section={section}\n onRetry={onRetry}\n refreshing={refreshing}\n />\n );\n};\n\nconst SectionStateContent = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection;\n onRetry: () => void;\n refreshing?: boolean;\n}) => (\n <>\n <Typography\n color={section.state === 'error' ? 'error' : 'textSecondary'}\n variant=\"body2\"\n >\n {section.message || 'No graph evidence is available.'}\n </Typography>\n {section.retryable && (\n <RetryControl onRetry={onRetry} refreshing={refreshing} />\n )}\n </>\n);\n\nconst RetryControl = ({\n onRetry,\n refreshing,\n}: {\n onRetry: () => void;\n refreshing?: boolean;\n}) => (\n <Button\n type=\"button\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onRetry}\n disabled={refreshing}\n startIcon={refreshing ? <CircularProgress size={14} /> : undefined}\n style={{ marginTop: 8 }}\n >\n {refreshing ? 'Retrying…' : 'Retry'}\n </Button>\n);\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { Box, Typography, makeStyles } from '@material-ui/core';
3
+ import { EvidenceDisclosure } from './EvidenceDisclosure.esm.js';
4
+
5
+ const STATE_COPY = {
6
+ firing: {
7
+ headline: "Service on fire",
8
+ detail: (signal) => `${signal.active} ${signal.active === 1 ? "monitor" : "monitors"} firing now`
9
+ },
10
+ noisy: {
11
+ headline: "Quiet now \xB7 noisy lately",
12
+ detail: () => "No monitor is firing now."
13
+ },
14
+ quiet: {
15
+ headline: "Quiet",
16
+ detail: () => "No paging activity in the last 7 days."
17
+ },
18
+ unavailable: {
19
+ headline: "Signal unavailable",
20
+ detail: () => "No Datadog signal evidence was returned."
21
+ }
22
+ };
23
+ const STATE_COLORS = {
24
+ firing: "#d63230",
25
+ noisy: "#d97706",
26
+ quiet: "#238636",
27
+ unavailable: "#6b7280"
28
+ };
29
+ const useStyles = makeStyles((theme) => ({
30
+ root: {
31
+ borderLeft: "4px solid",
32
+ paddingLeft: theme.spacing(2)
33
+ },
34
+ eyebrow: {
35
+ color: "#632ca6",
36
+ fontWeight: 700,
37
+ letterSpacing: "0.12em"
38
+ },
39
+ headline: {
40
+ fontWeight: 700,
41
+ letterSpacing: "-0.025em"
42
+ },
43
+ statusDot: {
44
+ width: 10,
45
+ height: 10,
46
+ borderRadius: "50%",
47
+ flex: "0 0 auto"
48
+ },
49
+ metric: {
50
+ minWidth: 92,
51
+ padding: theme.spacing(1, 1.5),
52
+ border: `1px solid ${theme.palette.divider}`,
53
+ borderRadius: theme.shape.borderRadius
54
+ },
55
+ metricValue: {
56
+ fontWeight: 700,
57
+ fontVariantNumeric: "tabular-nums"
58
+ },
59
+ monitorRow: {
60
+ padding: theme.spacing(1.25, 0)
61
+ },
62
+ monitorName: {
63
+ overflowWrap: "anywhere"
64
+ },
65
+ partial: {
66
+ marginTop: theme.spacing(2),
67
+ padding: theme.spacing(1),
68
+ borderRadius: theme.shape.borderRadius,
69
+ backgroundColor: theme.palette.action.hover
70
+ }
71
+ }));
72
+ const DatadogSignalStripPresenter = ({ data }) => {
73
+ const classes = useStyles();
74
+ const signal = datadogSignalFrom(data);
75
+ const copy = STATE_COPY[signal.state];
76
+ const color = STATE_COLORS[signal.state];
77
+ return /* @__PURE__ */ jsxs(Box, { px: 2, py: 1.5, style: { borderLeft: `4px solid ${color}` }, children: [
78
+ /* @__PURE__ */ jsxs(Box, { display: "flex", flexWrap: "wrap", alignItems: "center", gridGap: 8, children: [
79
+ /* @__PURE__ */ jsx(
80
+ "span",
81
+ {
82
+ className: classes.statusDot,
83
+ style: { backgroundColor: color },
84
+ "aria-hidden": "true"
85
+ }
86
+ ),
87
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", className: classes.headline, children: copy.headline }),
88
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: compactSummary(signal) })
89
+ ] }),
90
+ signal.partial && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", component: "p", children: "Some Datadog evidence is temporarily unavailable." }),
91
+ /* @__PURE__ */ jsx(EvidenceDisclosure, { data })
92
+ ] });
93
+ };
94
+ function datadogSignalFrom(data) {
95
+ const root = recordFrom(data);
96
+ const alerts = recordFrom(root.alerts);
97
+ const alertNoise = recordFrom(root.alertNoise);
98
+ const counts = recordFrom(alertNoise.counts);
99
+ const alertCause = recordFrom(root.alertCause);
100
+ const firingMonitors = uniqueMonitors(recordsFrom(alerts.firing), "firing");
101
+ const noisyMonitors = uniqueMonitors(
102
+ recordsFrom(alertNoise.monitors),
103
+ "noise"
104
+ );
105
+ const active = numberFrom(alerts.total) ?? firingMonitors.length;
106
+ const fires = numberFrom(counts.totalFires) ?? noisyMonitors.reduce((total, monitor) => total + (monitor.fires ?? 0), 0);
107
+ const recovers = noisyMonitors.reduce(
108
+ (total, monitor) => total + (monitor.recovers ?? 0),
109
+ 0
110
+ );
111
+ const flapping = numberFrom(counts.flapping) ?? noisyMonitors.filter((monitor) => monitor.noiseKind === "flapping").length;
112
+ const stuck = numberFrom(counts.stuck) ?? noisyMonitors.filter((monitor) => monitor.noiseKind === "stuck").length;
113
+ const hasEvidence = isRecord(root.alerts) || isRecord(root.alertNoise);
114
+ const changes = Array.isArray(alertCause.changes) ? alertCause.changes.length : void 0;
115
+ return {
116
+ state: !hasEvidence ? "unavailable" : active > 0 ? "firing" : fires > 0 || flapping > 0 || stuck > 0 ? "noisy" : "quiet",
117
+ active,
118
+ fires,
119
+ recovers,
120
+ flapping,
121
+ stuck,
122
+ firingMonitors,
123
+ noisyMonitors,
124
+ ...changes !== void 0 ? { correlatedChanges: changes } : {},
125
+ partial: Array.isArray(root.errors) && root.errors.length > 0
126
+ };
127
+ }
128
+ function uniqueMonitors(records, source) {
129
+ const unique = /* @__PURE__ */ new Map();
130
+ records.forEach((record) => {
131
+ const name = textFrom(record, source === "firing" ? "monitor" : "name");
132
+ if (!name) return;
133
+ const monitor = {
134
+ key: [
135
+ name,
136
+ textFrom(record, "state"),
137
+ textFrom(record, "service"),
138
+ textFrom(record, "workload"),
139
+ textFrom(record, "namespace")
140
+ ].filter(Boolean).join("|").toLowerCase(),
141
+ name,
142
+ state: textFrom(record, "state"),
143
+ service: textFrom(record, "service"),
144
+ workload: textFrom(record, "workload"),
145
+ namespace: textFrom(record, "namespace"),
146
+ fires: numberFrom(record.fires),
147
+ recovers: numberFrom(record.recovers),
148
+ noiseKind: textFrom(record, "noiseKind")
149
+ };
150
+ if (!unique.has(monitor.key)) unique.set(monitor.key, monitor);
151
+ });
152
+ return [...unique.values()];
153
+ }
154
+ function compactSummary(signal) {
155
+ if (signal.state === "firing") {
156
+ const summary = [
157
+ `${signal.active} ${signal.active === 1 ? "monitor" : "monitors"}`
158
+ ];
159
+ if (signal.correlatedChanges) {
160
+ summary.push(
161
+ `${signal.correlatedChanges} correlated ${signal.correlatedChanges === 1 ? "change" : "changes"}`
162
+ );
163
+ }
164
+ return summary.join(" \xB7 ");
165
+ }
166
+ if (signal.state === "noisy") {
167
+ return `${signal.fires} fire \xB7 ${signal.flapping} flapping`;
168
+ }
169
+ if (signal.state === "quiet") return "No recent paging noise";
170
+ return "No Datadog signal evidence returned";
171
+ }
172
+ function recordFrom(value) {
173
+ return isRecord(value) ? value : {};
174
+ }
175
+ function recordsFrom(value) {
176
+ return Array.isArray(value) ? value.filter(isRecord) : [];
177
+ }
178
+ function isRecord(value) {
179
+ return typeof value === "object" && value !== null && !Array.isArray(value);
180
+ }
181
+ function numberFrom(value) {
182
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
183
+ }
184
+ function textFrom(value, key) {
185
+ const candidate = value[key];
186
+ return typeof candidate === "string" && candidate.trim() ? candidate.trim() : void 0;
187
+ }
188
+
189
+ export { DatadogSignalStripPresenter, datadogSignalFrom };
190
+ //# sourceMappingURL=DatadogLiveSignal.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatadogLiveSignal.esm.js","sources":["../../../src/components/entity/DatadogLiveSignal.tsx"],"sourcesContent":["import {\n Box,\n Chip,\n Divider,\n Grid,\n Typography,\n makeStyles,\n} from '@material-ui/core';\nimport { EvidenceDisclosure } from './EvidenceDisclosure';\n\ntype SignalState = 'firing' | 'noisy' | 'quiet' | 'unavailable';\n\ninterface SignalMonitor {\n key: string;\n name: string;\n state?: string;\n service?: string;\n workload?: string;\n namespace?: string;\n fires?: number;\n recovers?: number;\n noiseKind?: string;\n}\n\nexport interface DatadogSignal {\n state: SignalState;\n active: number;\n fires: number;\n recovers: number;\n flapping: number;\n stuck: number;\n firingMonitors: SignalMonitor[];\n noisyMonitors: SignalMonitor[];\n correlatedChanges?: number;\n partial: boolean;\n}\n\nconst STATE_COPY: Record<\n SignalState,\n { headline: string; detail: (signal: DatadogSignal) => string }\n> = {\n firing: {\n headline: 'Service on fire',\n detail: signal =>\n `${signal.active} ${\n signal.active === 1 ? 'monitor' : 'monitors'\n } firing now`,\n },\n noisy: {\n headline: 'Quiet now · noisy lately',\n detail: () => 'No monitor is firing now.',\n },\n quiet: {\n headline: 'Quiet',\n detail: () => 'No paging activity in the last 7 days.',\n },\n unavailable: {\n headline: 'Signal unavailable',\n detail: () => 'No Datadog signal evidence was returned.',\n },\n};\n\nconst STATE_COLORS: Record<SignalState, string> = {\n firing: '#d63230',\n noisy: '#d97706',\n quiet: '#238636',\n unavailable: '#6b7280',\n};\n\nconst useStyles = makeStyles(theme => ({\n root: {\n borderLeft: '4px solid',\n paddingLeft: theme.spacing(2),\n },\n eyebrow: {\n color: '#632ca6',\n fontWeight: 700,\n letterSpacing: '0.12em',\n },\n headline: {\n fontWeight: 700,\n letterSpacing: '-0.025em',\n },\n statusDot: {\n width: 10,\n height: 10,\n borderRadius: '50%',\n flex: '0 0 auto',\n },\n metric: {\n minWidth: 92,\n padding: theme.spacing(1, 1.5),\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: theme.shape.borderRadius,\n },\n metricValue: {\n fontWeight: 700,\n fontVariantNumeric: 'tabular-nums',\n },\n monitorRow: {\n padding: theme.spacing(1.25, 0),\n },\n monitorName: {\n overflowWrap: 'anywhere',\n },\n partial: {\n marginTop: theme.spacing(2),\n padding: theme.spacing(1),\n borderRadius: theme.shape.borderRadius,\n backgroundColor: theme.palette.action.hover,\n },\n}));\n\nexport const DatadogLiveSignalPresenter = ({ data }: { data: unknown }) => {\n const classes = useStyles();\n const signal = datadogSignalFrom(data);\n const copy = STATE_COPY[signal.state];\n const color = STATE_COLORS[signal.state];\n const monitors =\n signal.state === 'firing' ? signal.firingMonitors : signal.noisyMonitors;\n\n return (\n <Box className={classes.root} style={{ borderLeftColor: color }}>\n <Grid container spacing={3} alignItems=\"flex-start\">\n <Grid item xs={12} md={5}>\n <Typography variant=\"overline\" className={classes.eyebrow}>\n Datadog · live graph signal\n </Typography>\n <Box display=\"flex\" alignItems=\"center\" gridGap={10}>\n <span\n className={classes.statusDot}\n style={{ backgroundColor: color }}\n aria-hidden=\"true\"\n />\n <Typography variant=\"h4\" className={classes.headline}>\n {copy.headline}\n </Typography>\n </Box>\n <Box mt={0.5}>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {copy.detail(signal)}\n </Typography>\n </Box>\n {signal.correlatedChanges !== undefined &&\n signal.correlatedChanges > 0 && (\n <Box mt={2}>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={`${signal.correlatedChanges} correlated ${\n signal.correlatedChanges === 1 ? 'change' : 'changes'\n } · 24h`}\n />\n </Box>\n )}\n </Grid>\n <Grid item xs={12} md={7}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Last 7 days\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={8} mt={0.5}>\n <SignalMetric value={signal.fires} label=\"fire\" classes={classes} />\n <SignalMetric\n value={signal.recovers}\n label=\"recover\"\n classes={classes}\n />\n <SignalMetric\n value={signal.flapping}\n label=\"flapping\"\n classes={classes}\n />\n <SignalMetric\n value={signal.stuck}\n label=\"stuck\"\n classes={classes}\n />\n </Box>\n </Grid>\n </Grid>\n\n {monitors.length > 0 && (\n <Box mt={2}>\n <Divider />\n {monitors.slice(0, 5).map((monitor, index) => (\n <Box key={monitor.key}>\n {index > 0 && <Divider />}\n <Box\n className={classes.monitorRow}\n display=\"flex\"\n justifyContent=\"space-between\"\n alignItems=\"flex-start\"\n gridGap={16}\n >\n <Typography variant=\"subtitle2\" className={classes.monitorName}>\n {monitor.name}\n </Typography>\n <Typography\n variant=\"caption\"\n color=\"textSecondary\"\n style={{ flex: '0 0 auto', textAlign: 'right' }}\n >\n {monitorSummary(monitor, signal.state)}\n </Typography>\n </Box>\n </Box>\n ))}\n </Box>\n )}\n\n {signal.partial && (\n <Typography\n variant=\"caption\"\n color=\"textSecondary\"\n className={classes.partial}\n component=\"p\"\n >\n Some Datadog evidence is temporarily unavailable.\n </Typography>\n )}\n <EvidenceDisclosure data={data} />\n </Box>\n );\n};\n\nexport const DatadogSignalStripPresenter = ({ data }: { data: unknown }) => {\n const classes = useStyles();\n const signal = datadogSignalFrom(data);\n const copy = STATE_COPY[signal.state];\n const color = STATE_COLORS[signal.state];\n\n return (\n <Box px={2} py={1.5} style={{ borderLeft: `4px solid ${color}` }}>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <span\n className={classes.statusDot}\n style={{ backgroundColor: color }}\n aria-hidden=\"true\"\n />\n <Typography variant=\"h6\" className={classes.headline}>\n {copy.headline}\n </Typography>\n <Typography variant=\"body2\" color=\"textSecondary\">\n {compactSummary(signal)}\n </Typography>\n </Box>\n {signal.partial && (\n <Typography variant=\"caption\" color=\"textSecondary\" component=\"p\">\n Some Datadog evidence is temporarily unavailable.\n </Typography>\n )}\n <EvidenceDisclosure data={data} />\n </Box>\n );\n};\n\nconst SignalMetric = ({\n value,\n label,\n classes,\n}: {\n value: number;\n label: string;\n classes: ReturnType<typeof useStyles>;\n}) => (\n <Box className={classes.metric}>\n <Typography variant=\"subtitle2\" className={classes.metricValue}>\n {value} {label}\n </Typography>\n </Box>\n);\n\nexport function datadogSignalFrom(data: unknown): DatadogSignal {\n const root = recordFrom(data);\n const alerts = recordFrom(root.alerts);\n const alertNoise = recordFrom(root.alertNoise);\n const counts = recordFrom(alertNoise.counts);\n const alertCause = recordFrom(root.alertCause);\n const firingMonitors = uniqueMonitors(recordsFrom(alerts.firing), 'firing');\n const noisyMonitors = uniqueMonitors(\n recordsFrom(alertNoise.monitors),\n 'noise',\n );\n const active = numberFrom(alerts.total) ?? firingMonitors.length;\n const fires =\n numberFrom(counts.totalFires) ??\n noisyMonitors.reduce((total, monitor) => total + (monitor.fires ?? 0), 0);\n const recovers = noisyMonitors.reduce(\n (total, monitor) => total + (monitor.recovers ?? 0),\n 0,\n );\n const flapping =\n numberFrom(counts.flapping) ??\n noisyMonitors.filter(monitor => monitor.noiseKind === 'flapping').length;\n const stuck =\n numberFrom(counts.stuck) ??\n noisyMonitors.filter(monitor => monitor.noiseKind === 'stuck').length;\n const hasEvidence = isRecord(root.alerts) || isRecord(root.alertNoise);\n const changes = Array.isArray(alertCause.changes)\n ? alertCause.changes.length\n : undefined;\n\n return {\n state: !hasEvidence\n ? 'unavailable'\n : active > 0\n ? 'firing'\n : fires > 0 || flapping > 0 || stuck > 0\n ? 'noisy'\n : 'quiet',\n active,\n fires,\n recovers,\n flapping,\n stuck,\n firingMonitors,\n noisyMonitors,\n ...(changes !== undefined ? { correlatedChanges: changes } : {}),\n partial: Array.isArray(root.errors) && root.errors.length > 0,\n };\n}\n\nfunction uniqueMonitors(\n records: Array<Record<string, unknown>>,\n source: 'firing' | 'noise',\n): SignalMonitor[] {\n const unique = new Map<string, SignalMonitor>();\n records.forEach(record => {\n const name = textFrom(record, source === 'firing' ? 'monitor' : 'name');\n if (!name) return;\n const monitor: SignalMonitor = {\n key: [\n name,\n textFrom(record, 'state'),\n textFrom(record, 'service'),\n textFrom(record, 'workload'),\n textFrom(record, 'namespace'),\n ]\n .filter(Boolean)\n .join('|')\n .toLowerCase(),\n name,\n state: textFrom(record, 'state'),\n service: textFrom(record, 'service'),\n workload: textFrom(record, 'workload'),\n namespace: textFrom(record, 'namespace'),\n fires: numberFrom(record.fires),\n recovers: numberFrom(record.recovers),\n noiseKind: textFrom(record, 'noiseKind'),\n };\n if (!unique.has(monitor.key)) unique.set(monitor.key, monitor);\n });\n return [...unique.values()];\n}\n\nfunction monitorSummary(monitor: SignalMonitor, state: SignalState): string {\n if (state === 'firing') {\n return [\n monitor.state,\n monitor.workload || monitor.service,\n monitor.namespace,\n ]\n .filter(Boolean)\n .join(' · ');\n }\n return [\n `${monitor.fires ?? 0} fire / ${monitor.recovers ?? 0} recover`,\n monitor.noiseKind,\n ]\n .filter(Boolean)\n .join(' · ');\n}\n\nfunction compactSummary(signal: DatadogSignal): string {\n if (signal.state === 'firing') {\n const summary = [\n `${signal.active} ${signal.active === 1 ? 'monitor' : 'monitors'}`,\n ];\n if (signal.correlatedChanges) {\n summary.push(\n `${signal.correlatedChanges} correlated ${\n signal.correlatedChanges === 1 ? 'change' : 'changes'\n }`,\n );\n }\n return summary.join(' · ');\n }\n if (signal.state === 'noisy') {\n return `${signal.fires} fire · ${signal.flapping} flapping`;\n }\n if (signal.state === 'quiet') return 'No recent paging noise';\n return 'No Datadog signal evidence returned';\n}\n\nfunction recordFrom(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nfunction recordsFrom(value: unknown): Array<Record<string, unknown>> {\n return Array.isArray(value) ? value.filter(isRecord) : [];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction numberFrom(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction textFrom(\n value: Record<string, unknown>,\n key: string,\n): string | undefined {\n const candidate = value[key];\n return typeof candidate === 'string' && candidate.trim()\n ? candidate.trim()\n : undefined;\n}\n"],"names":[],"mappings":";;;;AAqCA,MAAM,UAAA,GAGF;AAAA,EACF,MAAA,EAAQ;AAAA,IACN,QAAA,EAAU,iBAAA;AAAA,IACV,MAAA,EAAQ,CAAA,MAAA,KACN,CAAA,EAAG,MAAA,CAAO,MAAM,IACd,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,SAAA,GAAY,UACpC,CAAA,WAAA;AAAA,GACJ;AAAA,EACA,KAAA,EAAO;AAAA,IACL,QAAA,EAAU,6BAAA;AAAA,IACV,QAAQ,MAAM;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,QAAA,EAAU,OAAA;AAAA,IACV,QAAQ,MAAM;AAAA,GAChB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,QAAA,EAAU,oBAAA;AAAA,IACV,QAAQ,MAAM;AAAA;AAElB,CAAA;AAEA,MAAM,YAAA,GAA4C;AAAA,EAChD,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,SAAA;AAAA,EACP,KAAA,EAAO,SAAA;AAAA,EACP,WAAA,EAAa;AACf,CAAA;AAEA,MAAM,SAAA,GAAY,WAAW,CAAA,KAAA,MAAU;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,UAAA,EAAY,WAAA;AAAA,IACZ,WAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,GAC9B;AAAA,EACA,OAAA,EAAS;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,SAAA,EAAW;AAAA,IACT,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,YAAA,EAAc,KAAA;AAAA,IACd,IAAA,EAAM;AAAA,GACR;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,QAAA,EAAU,EAAA;AAAA,IACV,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAA;AAAA,IAC7B,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,IAC1C,YAAA,EAAc,MAAM,KAAA,CAAM;AAAA,GAC5B;AAAA,EACA,WAAA,EAAa;AAAA,IACX,UAAA,EAAY,GAAA;AAAA,IACZ,kBAAA,EAAoB;AAAA,GACtB;AAAA,EACA,UAAA,EAAY;AAAA,IACV,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,CAAC;AAAA,GAChC;AAAA,EACA,WAAA,EAAa;AAAA,IACX,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,OAAA,EAAS;AAAA,IACP,SAAA,EAAW,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IAC1B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,IACxB,YAAA,EAAc,MAAM,KAAA,CAAM,YAAA;AAAA,IAC1B,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO;AAAA;AAE1C,CAAA,CAAE,CAAA;AAkHK,MAAM,2BAAA,GAA8B,CAAC,EAAE,IAAA,EAAK,KAAyB;AAC1E,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,MAAM,MAAA,GAAS,kBAAkB,IAAI,CAAA;AACrC,EAAA,MAAM,IAAA,GAAO,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AACpC,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,MAAA,CAAO,KAAK,CAAA;AAEvC,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,GAAA,EAAK,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA,UAAA,EAAa,KAAK,CAAA,CAAA,EAAG,EAC7D,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAA,EAAA,EAAI,SAAQ,MAAA,EAAO,QAAA,EAAS,QAAO,UAAA,EAAW,QAAA,EAAS,SAAS,CAAA,EAC/D,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,KAAA,EAAO,EAAE,eAAA,EAAiB,KAAA,EAAM;AAAA,UAChC,aAAA,EAAY;AAAA;AAAA,OACd;AAAA,sBACA,GAAA,CAAC,cAAW,OAAA,EAAQ,IAAA,EAAK,WAAW,OAAA,CAAQ,QAAA,EACzC,eAAK,QAAA,EACR,CAAA;AAAA,sBACA,GAAA,CAAC,cAAW,OAAA,EAAQ,OAAA,EAAQ,OAAM,eAAA,EAC/B,QAAA,EAAA,cAAA,CAAe,MAAM,CAAA,EACxB;AAAA,KAAA,EACF,CAAA;AAAA,IACC,MAAA,CAAO,OAAA,oBACN,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAU,KAAA,EAAM,eAAA,EAAgB,SAAA,EAAU,GAAA,EAAI,QAAA,EAAA,mDAAA,EAElE,CAAA;AAAA,oBAEF,GAAA,CAAC,sBAAmB,IAAA,EAAY;AAAA,GAAA,EAClC,CAAA;AAEJ;AAkBO,SAAS,kBAAkB,IAAA,EAA8B;AAC9D,EAAA,MAAM,IAAA,GAAO,WAAW,IAAI,CAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA;AACrC,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AAC7C,EAAA,MAAM,iBAAiB,cAAA,CAAe,WAAA,CAAY,MAAA,CAAO,MAAM,GAAG,QAAQ,CAAA;AAC1E,EAAA,MAAM,aAAA,GAAgB,cAAA;AAAA,IACpB,WAAA,CAAY,WAAW,QAAQ,CAAA;AAAA,IAC/B;AAAA,GACF;AACA,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,MAAA,CAAO,KAAK,KAAK,cAAA,CAAe,MAAA;AAC1D,EAAA,MAAM,KAAA,GACJ,UAAA,CAAW,MAAA,CAAO,UAAU,KAC5B,aAAA,CAAc,MAAA,CAAO,CAAC,KAAA,EAAO,OAAA,KAAY,KAAA,IAAS,OAAA,CAAQ,KAAA,IAAS,IAAI,CAAC,CAAA;AAC1E,EAAA,MAAM,WAAW,aAAA,CAAc,MAAA;AAAA,IAC7B,CAAC,KAAA,EAAO,OAAA,KAAY,KAAA,IAAS,QAAQ,QAAA,IAAY,CAAA,CAAA;AAAA,IACjD;AAAA,GACF;AACA,EAAA,MAAM,QAAA,GACJ,UAAA,CAAW,MAAA,CAAO,QAAQ,CAAA,IAC1B,aAAA,CAAc,MAAA,CAAO,CAAA,OAAA,KAAW,OAAA,CAAQ,SAAA,KAAc,UAAU,CAAA,CAAE,MAAA;AACpE,EAAA,MAAM,KAAA,GACJ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,IACvB,aAAA,CAAc,MAAA,CAAO,CAAA,OAAA,KAAW,OAAA,CAAQ,SAAA,KAAc,OAAO,CAAA,CAAE,MAAA;AACjE,EAAA,MAAM,cAAc,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA,IAAK,QAAA,CAAS,KAAK,UAAU,CAAA;AACrE,EAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,GAC5C,UAAA,CAAW,QAAQ,MAAA,GACnB,MAAA;AAEJ,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,WAAA,GACJ,aAAA,GACA,MAAA,GAAS,CAAA,GACT,QAAA,GACA,KAAA,GAAQ,CAAA,IAAK,QAAA,GAAW,CAAA,IAAK,KAAA,GAAQ,IACrC,OAAA,GACA,OAAA;AAAA,IACJ,MAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAI,OAAA,KAAY,MAAA,GAAY,EAAE,iBAAA,EAAmB,OAAA,KAAY,EAAC;AAAA,IAC9D,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,IAAK,IAAA,CAAK,OAAO,MAAA,GAAS;AAAA,GAC9D;AACF;AAEA,SAAS,cAAA,CACP,SACA,MAAA,EACiB;AACjB,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAC9C,EAAA,OAAA,CAAQ,QAAQ,CAAA,MAAA,KAAU;AACxB,IAAA,MAAM,OAAO,QAAA,CAAS,MAAA,EAAQ,MAAA,KAAW,QAAA,GAAW,YAAY,MAAM,CAAA;AACtE,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,OAAA,GAAyB;AAAA,MAC7B,GAAA,EAAK;AAAA,QACH,IAAA;AAAA,QACA,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,QACxB,QAAA,CAAS,QAAQ,SAAS,CAAA;AAAA,QAC1B,QAAA,CAAS,QAAQ,UAAU,CAAA;AAAA,QAC3B,QAAA,CAAS,QAAQ,WAAW;AAAA,QAE3B,MAAA,CAAO,OAAO,EACd,IAAA,CAAK,GAAG,EACR,WAAA,EAAY;AAAA,MACf,IAAA;AAAA,MACA,KAAA,EAAO,QAAA,CAAS,MAAA,EAAQ,OAAO,CAAA;AAAA,MAC/B,OAAA,EAAS,QAAA,CAAS,MAAA,EAAQ,SAAS,CAAA;AAAA,MACnC,QAAA,EAAU,QAAA,CAAS,MAAA,EAAQ,UAAU,CAAA;AAAA,MACrC,SAAA,EAAW,QAAA,CAAS,MAAA,EAAQ,WAAW,CAAA;AAAA,MACvC,KAAA,EAAO,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AAAA,MAC9B,QAAA,EAAU,UAAA,CAAW,MAAA,CAAO,QAAQ,CAAA;AAAA,MACpC,SAAA,EAAW,QAAA,CAAS,MAAA,EAAQ,WAAW;AAAA,KACzC;AACA,IAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAG,GAAG,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,OAAO,CAAA;AAAA,EAC/D,CAAC,CAAA;AACD,EAAA,OAAO,CAAC,GAAG,MAAA,CAAO,MAAA,EAAQ,CAAA;AAC5B;AAoBA,SAAS,eAAe,MAAA,EAA+B;AACrD,EAAA,IAAI,MAAA,CAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,CAAA,EAAG,OAAO,MAAM,CAAA,CAAA,EAAI,OAAO,MAAA,KAAW,CAAA,GAAI,YAAY,UAAU,CAAA;AAAA,KAClE;AACA,IAAA,IAAI,OAAO,iBAAA,EAAmB;AAC5B,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,EAAG,OAAO,iBAAiB,CAAA,YAAA,EACzB,OAAO,iBAAA,KAAsB,CAAA,GAAI,WAAW,SAC9C,CAAA;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,OAAA,CAAQ,KAAK,QAAK,CAAA;AAAA,EAC3B;AACA,EAAA,IAAI,MAAA,CAAO,UAAU,OAAA,EAAS;AAC5B,IAAA,OAAO,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,WAAA,EAAW,OAAO,QAAQ,CAAA,SAAA,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,MAAA,CAAO,KAAA,KAAU,OAAA,EAAS,OAAO,wBAAA;AACrC,EAAA,OAAO,qCAAA;AACT;AAEA,SAAS,WAAW,KAAA,EAAyC;AAC3D,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,GAAI,KAAA,GAAQ,EAAC;AACpC;AAEA,SAAS,YAAY,KAAA,EAAgD;AACnE,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA,GAAI,MAAM,MAAA,CAAO,QAAQ,IAAI,EAAC;AAC1D;AAEA,SAAS,SAAS,KAAA,EAAkD;AAClE,EAAA,OAAO,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAEA,SAAS,WAAW,KAAA,EAAoC;AACtD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,QAAA,CAAS,KAAK,IACrD,KAAA,GACA,MAAA;AACN;AAEA,SAAS,QAAA,CACP,OACA,GAAA,EACoB;AACpB,EAAA,MAAM,SAAA,GAAY,MAAM,GAAG,CAAA;AAC3B,EAAA,OAAO,OAAO,cAAc,QAAA,IAAY,SAAA,CAAU,MAAK,GACnD,SAAA,CAAU,MAAK,GACf,MAAA;AACN;;;;"}
@@ -0,0 +1,20 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+
3
+ const EvidenceDisclosure = ({ data }) => /* @__PURE__ */ jsxs("details", { style: { marginTop: 16 }, children: [
4
+ /* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontWeight: 500 }, children: "View evidence" }),
5
+ /* @__PURE__ */ jsx(
6
+ "pre",
7
+ {
8
+ style: {
9
+ overflowX: "auto",
10
+ whiteSpace: "pre-wrap",
11
+ overflowWrap: "anywhere",
12
+ fontSize: 12
13
+ },
14
+ children: JSON.stringify(data, null, 2)
15
+ }
16
+ )
17
+ ] });
18
+
19
+ export { EvidenceDisclosure };
20
+ //# sourceMappingURL=EvidenceDisclosure.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EvidenceDisclosure.esm.js","sources":["../../../src/components/entity/EvidenceDisclosure.tsx"],"sourcesContent":["export const EvidenceDisclosure = ({ data }: { data: unknown }) => (\n <details style={{ marginTop: 16 }}>\n <summary style={{ cursor: 'pointer', fontWeight: 500 }}>\n View evidence\n </summary>\n <pre\n style={{\n overflowX: 'auto',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'anywhere',\n fontSize: 12,\n }}\n >\n {JSON.stringify(data, null, 2)}\n </pre>\n </details>\n);\n"],"names":[],"mappings":";;AAAO,MAAM,kBAAA,GAAqB,CAAC,EAAE,IAAA,EAAK,qBACxC,IAAA,CAAC,SAAA,EAAA,EAAQ,KAAA,EAAO,EAAE,SAAA,EAAW,EAAA,EAAG,EAC9B,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAQ,OAAO,EAAE,MAAA,EAAQ,WAAW,UAAA,EAAY,GAAA,IAAO,QAAA,EAAA,eAAA,EAExD,CAAA;AAAA,kBACA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,SAAA,EAAW,MAAA;AAAA,QACX,UAAA,EAAY,UAAA;AAAA,QACZ,YAAA,EAAc,UAAA;AAAA,QACd,QAAA,EAAU;AAAA,OACZ;AAAA,MAEC,QAAA,EAAA,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC;AAAA;AAAA;AAC/B,CAAA,EACF;;;;"}
@@ -0,0 +1,89 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Box, CircularProgress, Typography } from '@material-ui/core';
3
+ import mermaid from 'mermaid';
4
+ import { useMemo, useRef, useState, useEffect } from 'react';
5
+ import { buildArchitectureDiagram } from './architectureDiagram.esm.js';
6
+
7
+ let diagramSequence = 0;
8
+ let mermaidInitialized = false;
9
+ const RelationshipFallback = ({
10
+ relationships
11
+ }) => /* @__PURE__ */ jsxs(Box, { mt: 2, children: [
12
+ /* @__PURE__ */ jsx(Typography, { color: "error", variant: "body2", role: "alert", children: "The architecture diagram could not be drawn. Showing relationships instead." }),
13
+ /* @__PURE__ */ jsx(
14
+ Box,
15
+ {
16
+ component: "ul",
17
+ m: 0,
18
+ mt: 1,
19
+ p: 0,
20
+ "aria-label": "Architecture relationships",
21
+ children: relationships.map((relationship) => /* @__PURE__ */ jsx(
22
+ Box,
23
+ {
24
+ component: "li",
25
+ py: 0.5,
26
+ style: { listStyle: "none" },
27
+ children: /* @__PURE__ */ jsx(Typography, { variant: "body2", children: relationship })
28
+ },
29
+ relationship
30
+ ))
31
+ }
32
+ )
33
+ ] });
34
+ const ArchitectureDiagram = ({
35
+ graph,
36
+ view = "runtime"
37
+ }) => {
38
+ const definition = useMemo(
39
+ () => buildArchitectureDiagram(graph, { view }),
40
+ [graph, view]
41
+ );
42
+ const diagramId = useRef(`anyshift-architecture-${diagramSequence++}`);
43
+ const [svg, setSvg] = useState();
44
+ const [renderFailed, setRenderFailed] = useState(false);
45
+ useEffect(() => {
46
+ let active = true;
47
+ setSvg(void 0);
48
+ setRenderFailed(false);
49
+ if (!mermaidInitialized) {
50
+ mermaid.initialize({
51
+ startOnLoad: false,
52
+ securityLevel: "strict",
53
+ theme: "base",
54
+ flowchart: { htmlLabels: false, curve: "basis" }
55
+ });
56
+ mermaidInitialized = true;
57
+ }
58
+ Promise.resolve().then(() => mermaid.render(diagramId.current, definition.source)).then((result) => {
59
+ if (active) setSvg(result.svg);
60
+ }).catch(() => {
61
+ if (active) setRenderFailed(true);
62
+ });
63
+ return () => {
64
+ active = false;
65
+ };
66
+ }, [definition.source]);
67
+ if (renderFailed) {
68
+ return /* @__PURE__ */ jsx(RelationshipFallback, { relationships: definition.fallbackRelationships });
69
+ }
70
+ if (!svg) {
71
+ return /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gridGap: 8, py: 3, children: [
72
+ /* @__PURE__ */ jsx(CircularProgress, { size: 18 }),
73
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Drawing architecture\u2026" })
74
+ ] });
75
+ }
76
+ return /* @__PURE__ */ jsx(
77
+ Box,
78
+ {
79
+ "aria-label": "C4 architecture diagram",
80
+ role: "img",
81
+ mt: 1,
82
+ style: { overflowX: "auto" },
83
+ dangerouslySetInnerHTML: { __html: svg }
84
+ }
85
+ );
86
+ };
87
+
88
+ export { ArchitectureDiagram };
89
+ //# sourceMappingURL=MermaidArchitecture.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MermaidArchitecture.esm.js","sources":["../../../src/components/entity/MermaidArchitecture.tsx"],"sourcesContent":["import { Box, CircularProgress, Typography } from '@material-ui/core';\nimport mermaid from 'mermaid';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n buildArchitectureDiagram,\n type ArchitectureGraph,\n} from './architectureDiagram';\n\nlet diagramSequence = 0;\nlet mermaidInitialized = false;\n\nconst RelationshipFallback = ({\n relationships,\n}: {\n relationships: string[];\n}) => (\n <Box mt={2}>\n <Typography color=\"error\" variant=\"body2\" role=\"alert\">\n The architecture diagram could not be drawn. Showing relationships\n instead.\n </Typography>\n <Box\n component=\"ul\"\n m={0}\n mt={1}\n p={0}\n aria-label=\"Architecture relationships\"\n >\n {relationships.map(relationship => (\n <Box\n component=\"li\"\n key={relationship}\n py={0.5}\n style={{ listStyle: 'none' }}\n >\n <Typography variant=\"body2\">{relationship}</Typography>\n </Box>\n ))}\n </Box>\n </Box>\n);\n\nexport const ArchitectureDiagram = ({\n graph,\n view = 'runtime',\n}: {\n graph: ArchitectureGraph;\n view?: 'context' | 'runtime';\n}) => {\n const definition = useMemo(\n () => buildArchitectureDiagram(graph, { view }),\n [graph, view],\n );\n const diagramId = useRef(`anyshift-architecture-${diagramSequence++}`);\n const [svg, setSvg] = useState<string>();\n const [renderFailed, setRenderFailed] = useState(false);\n\n useEffect(() => {\n let active = true;\n setSvg(undefined);\n setRenderFailed(false);\n\n if (!mermaidInitialized) {\n mermaid.initialize({\n startOnLoad: false,\n securityLevel: 'strict',\n theme: 'base',\n flowchart: { htmlLabels: false, curve: 'basis' },\n });\n mermaidInitialized = true;\n }\n\n Promise.resolve()\n .then(() => mermaid.render(diagramId.current, definition.source))\n .then(result => {\n if (active) setSvg(result.svg);\n })\n .catch(() => {\n if (active) setRenderFailed(true);\n });\n\n return () => {\n active = false;\n };\n }, [definition.source]);\n\n if (renderFailed) {\n return (\n <RelationshipFallback relationships={definition.fallbackRelationships} />\n );\n }\n\n if (!svg) {\n return (\n <Box display=\"flex\" alignItems=\"center\" gridGap={8} py={3}>\n <CircularProgress size={18} />\n <Typography variant=\"body2\" color=\"textSecondary\">\n Drawing architecture…\n </Typography>\n </Box>\n );\n }\n\n return (\n <Box\n aria-label=\"C4 architecture diagram\"\n role=\"img\"\n mt={1}\n style={{ overflowX: 'auto' }}\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n );\n};\n"],"names":[],"mappings":"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"}