@anyshift/backstage-plugin-anyshift 0.1.0-beta.20 → 0.1.0-beta.21
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/LICENSE +1 -0
- package/README.md +3 -11
- package/dist/api/AnyshiftApi.esm.js +5 -56
- package/dist/api/AnyshiftApi.esm.js.map +1 -1
- package/dist/components/cloud/CloudResourceContent.esm.js +45 -444
- package/dist/components/cloud/CloudResourceContent.esm.js.map +1 -1
- package/dist/components/entity/AnyshiftEntityContent.esm.js +23 -128
- package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -1
- package/dist/components/entity/BriefSections.esm.js +4 -24
- package/dist/components/entity/BriefSections.esm.js.map +1 -1
- package/dist/components/entity/DatadogLiveSignal.esm.js +23 -85
- package/dist/components/entity/DatadogLiveSignal.esm.js.map +1 -1
- package/dist/components/entity/MermaidArchitecture.esm.js +43 -202
- package/dist/components/entity/MermaidArchitecture.esm.js.map +1 -1
- package/dist/components/entity/SectionPresenters.esm.js +82 -145
- package/dist/components/entity/SectionPresenters.esm.js.map +1 -1
- package/dist/components/entity/architectureDiagram.esm.js +15 -48
- package/dist/components/entity/architectureDiagram.esm.js.map +1 -1
- package/dist/components/explorer/AnyshiftExplorerPage.esm.js +19 -154
- package/dist/components/explorer/AnyshiftExplorerPage.esm.js.map +1 -1
- package/dist/components/explorer/DatadogOperationsRadar.esm.js +31 -92
- package/dist/components/explorer/DatadogOperationsRadar.esm.js.map +1 -1
- package/dist/index.d.ts +4 -18
- package/dist/index.esm.js +1 -1
- package/dist/package.json.esm.js +13 -13
- package/dist/plugin.esm.js +2 -6
- package/dist/plugin.esm.js.map +1 -1
- package/package.json +15 -15
- package/CHANGELOG.md +0 -87
- package/dist/components/ask/AskAnyshiftCard.esm.js +0 -348
- package/dist/components/ask/AskAnyshiftCard.esm.js.map +0 -1
- package/dist/components/ask/askPresenters.esm.js +0 -1203
- package/dist/components/ask/askPresenters.esm.js.map +0 -1
- package/dist/components/ask/askScope.esm.js +0 -27
- package/dist/components/ask/askScope.esm.js.map +0 -1
- package/dist/components/ask/askSuggestions.esm.js +0 -41
- package/dist/components/ask/askSuggestions.esm.js.map +0 -1
- package/dist/components/cloud/CloudImpactSection.esm.js +0 -54
- package/dist/components/cloud/CloudImpactSection.esm.js.map +0 -1
- package/dist/components/cloud/CloudRelationshipSections.esm.js +0 -43
- package/dist/components/cloud/CloudRelationshipSections.esm.js.map +0 -1
- package/dist/components/entity/ArchitectureOperationDetails.esm.js +0 -107
- package/dist/components/entity/ArchitectureOperationDetails.esm.js.map +0 -1
- package/dist/components/entity/architectureGraph.esm.js +0 -145
- package/dist/components/entity/architectureGraph.esm.js.map +0 -1
- package/dist/components/entity/entityIdentity.esm.js +0 -40
- package/dist/components/entity/entityIdentity.esm.js.map +0 -1
- package/dist/components/entity/relatedCatalogEntities.esm.js +0 -60
- package/dist/components/entity/relatedCatalogEntities.esm.js.map +0 -1
|
@@ -1 +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 provider?: string;\n severity?: string;\n providerStatus?: string;\n state?: string;\n service?: string;\n workload?: string;\n namespace?: string;\n fires?: number;\n recovers?: number;\n noiseKind?: string;\n}\n\ninterface SignalProviderCoverage {\n provider: string;\n status: string;\n}\n\ninterface SignalWarning {\n message: string;\n provider?: string;\n}\n\nexport interface DatadogSignal {\n state: SignalState;\n active: number;\n activeHasMore: boolean;\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 providers: SignalProviderCoverage[];\n warnings: SignalWarning[];\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.activeHasMore ? 'At least ' : ''}${signal.active} ${\n signal.active === 1 ? 'alert' : 'alerts'\n } firing now`,\n },\n noisy: {\n headline: 'Quiet now · noisy lately',\n detail: () => 'No alert 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: signal =>\n signal.partial\n ? 'Operational alert evidence is incomplete.'\n : 'No operational alert 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 Operational alerts · 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 <>\n <Typography\n variant=\"caption\"\n color=\"textSecondary\"\n className={classes.partial}\n component=\"p\"\n >\n {signal.activeHasMore\n ? 'Additional alert rows are available; the loaded count is a lower bound.'\n : 'Some operational alert evidence is temporarily unavailable.'}\n </Typography>\n <AlertCoverage signal={signal} />\n </>\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 <>\n <Typography variant=\"caption\" color=\"textSecondary\" component=\"p\">\n {signal.activeHasMore\n ? 'Additional alert rows are available; the loaded count is a lower bound.'\n : 'Some operational alert evidence is temporarily unavailable.'}\n </Typography>\n <AlertCoverage signal={signal} />\n </>\n )}\n <EvidenceDisclosure data={data} />\n </Box>\n );\n};\n\nconst AlertCoverage = ({ signal }: { signal: DatadogSignal }) => (\n <>\n {signal.providers\n .filter(provider => provider.status !== 'available')\n .map(provider => (\n <Typography\n key={provider.provider}\n variant=\"caption\"\n color=\"textSecondary\"\n component=\"p\"\n >\n Alert coverage: {readableProvider(provider.provider)}{' '}\n {provider.status}.\n </Typography>\n ))}\n {signal.warnings.map(warning => (\n <Typography\n key={`${warning.provider ?? 'alert'}:${warning.message}`}\n variant=\"caption\"\n color=\"textSecondary\"\n component=\"p\"\n >\n Alert warning: {warning.message}\n {warning.message.endsWith('.') ? '' : '.'}\n </Typography>\n ))}\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 providers = providerCoverageFrom(alerts.providers);\n const warnings = warningsFrom(alerts.warnings);\n const activeHasMore = recordFrom(alerts.page).hasMore === true;\n const alertEvidenceIncomplete =\n alerts.partial === true ||\n activeHasMore ||\n providers.some(provider => provider.status !== 'available') ||\n warnings.length > 0;\n const firingMonitors = uniqueMonitors(\n recordsFrom(alerts.items).filter(\n record => textFrom(record, 'status') === 'firing',\n ),\n 'alert',\n );\n const noisyMonitors = uniqueMonitors(\n recordsFrom(alertNoise.monitors),\n 'noise',\n );\n const active = 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 : alertEvidenceIncomplete\n ? 'unavailable'\n : fires > 0 || flapping > 0 || stuck > 0\n ? 'noisy'\n : 'quiet',\n active,\n activeHasMore,\n fires,\n recovers,\n flapping,\n stuck,\n firingMonitors,\n noisyMonitors,\n ...(changes !== undefined ? { correlatedChanges: changes } : {}),\n partial:\n (Array.isArray(root.errors) && root.errors.length > 0) ||\n alertEvidenceIncomplete,\n providers,\n warnings,\n };\n}\n\nfunction providerCoverageFrom(value: unknown): SignalProviderCoverage[] {\n return recordsFrom(value).flatMap(provider => {\n const name = textFrom(provider, 'provider');\n const status = textFrom(provider, 'status');\n return name && status ? [{ provider: name, status }] : [];\n });\n}\n\nfunction warningsFrom(value: unknown): SignalWarning[] {\n return recordsFrom(value).flatMap(warning => {\n const message = textFrom(warning, 'message');\n const provider = textFrom(warning, 'provider');\n return message ? [{ message, ...(provider ? { provider } : {}) }] : [];\n });\n}\n\nfunction readableProvider(provider: string): string {\n return provider.charAt(0).toUpperCase() + provider.slice(1);\n}\n\nfunction uniqueMonitors(\n records: Array<Record<string, unknown>>,\n source: 'alert' | 'noise',\n): SignalMonitor[] {\n const unique = new Map<string, SignalMonitor>();\n records.forEach(record => {\n const name = textFrom(record, source === 'alert' ? 'title' : 'name');\n if (!name) return;\n const service = recordFrom(record.service);\n const monitor: SignalMonitor = {\n key:\n source === 'alert'\n ? textFrom(record, 'id') ?? name.toLowerCase()\n : [name, textFrom(record, 'noiseKind')]\n .filter(Boolean)\n .join('|')\n .toLowerCase(),\n name,\n state:\n source === 'alert'\n ? textFrom(record, 'providerStatus') ?? textFrom(record, 'status')\n : textFrom(record, 'state'),\n provider: source === 'alert' ? textFrom(record, 'provider') : undefined,\n severity: source === 'alert' ? textFrom(record, 'severity') : undefined,\n providerStatus:\n source === 'alert' ? textFrom(record, 'providerStatus') : undefined,\n service:\n source === 'alert'\n ? textFrom(service, 'name')\n : textFrom(record, 'service'),\n workload:\n source === 'alert'\n ? textFrom(service, 'name')\n : textFrom(record, 'workload'),\n namespace:\n source === 'alert'\n ? textFrom(service, 'namespace')\n : 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.provider,\n monitor.severity,\n monitor.providerStatus ?? 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.activeHasMore ? 'At least ' : ''}${signal.active} ${\n signal.active === 1 ? 'alert' : 'alerts'\n }`,\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 signal.partial\n ? 'Operational alert evidence incomplete'\n : 'No operational alert 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":"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"}
|
|
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":"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"}
|
|
@@ -1,114 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Box, CircularProgress, Typography
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, CircularProgress, Typography } from '@material-ui/core';
|
|
3
3
|
import mermaid from 'mermaid';
|
|
4
4
|
import { useMemo, useRef, useState, useEffect } from 'react';
|
|
5
5
|
import { buildArchitectureDiagram } from './architectureDiagram.esm.js';
|
|
6
|
-
import { operationPreview, ArchitectureOperationDetails } from './ArchitectureOperationDetails.esm.js';
|
|
7
6
|
|
|
8
7
|
let diagramSequence = 0;
|
|
9
8
|
let mermaidInitialized = false;
|
|
10
|
-
const useStyles = makeStyles((theme) => ({
|
|
11
|
-
diagram: {
|
|
12
|
-
"& .anyshift-http-edge-affordance": {
|
|
13
|
-
cursor: "pointer"
|
|
14
|
-
},
|
|
15
|
-
"& .anyshift-http-edge-affordance:focus": {
|
|
16
|
-
outline: `2px solid ${theme.palette.text.primary}`,
|
|
17
|
-
outlineOffset: 2
|
|
18
|
-
},
|
|
19
|
-
"& .edgeLabel.anyshift-http-edge-affordance rect": {
|
|
20
|
-
rx: 4,
|
|
21
|
-
ry: 4,
|
|
22
|
-
stroke: theme.palette.divider,
|
|
23
|
-
strokeWidth: 1
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
fallbackButton: {
|
|
27
|
-
appearance: "none",
|
|
28
|
-
background: "transparent",
|
|
29
|
-
border: 0,
|
|
30
|
-
color: "inherit",
|
|
31
|
-
cursor: "pointer",
|
|
32
|
-
font: "inherit",
|
|
33
|
-
padding: 0,
|
|
34
|
-
textAlign: "left",
|
|
35
|
-
"&:focus": {
|
|
36
|
-
outline: `2px solid ${theme.palette.text.primary}`,
|
|
37
|
-
outlineOffset: 2
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
const hasUsableOperations = (relationship) => relationship.operationCount > 0 && operationPreview(relationship) !== "";
|
|
42
9
|
const RelationshipFallback = ({
|
|
43
|
-
relationships
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"aria-label": `Show HTTP operations for ${relationship.fromLabel} to ${relationship.toLabel}`,
|
|
68
|
-
"aria-expanded": selectedId === relationship.id,
|
|
69
|
-
className: classes.fallbackButton,
|
|
70
|
-
onClick: () => onSelect(relationship),
|
|
71
|
-
type: "button",
|
|
72
|
-
children: /* @__PURE__ */ jsx(Typography, { component: "span", variant: "body2", children: relationship.label })
|
|
73
|
-
}
|
|
74
|
-
) : /* @__PURE__ */ jsx(Typography, { variant: "body2", children: relationship.label })
|
|
75
|
-
},
|
|
76
|
-
relationship.id
|
|
77
|
-
))
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
] });
|
|
81
|
-
};
|
|
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
|
+
] });
|
|
82
34
|
const ArchitectureDiagram = ({
|
|
83
35
|
graph,
|
|
84
36
|
view = "runtime"
|
|
85
37
|
}) => {
|
|
86
|
-
const classes = useStyles();
|
|
87
38
|
const definition = useMemo(
|
|
88
39
|
() => buildArchitectureDiagram(graph, { view }),
|
|
89
40
|
[graph, view]
|
|
90
41
|
);
|
|
91
42
|
const diagramId = useRef(`anyshift-architecture-${diagramSequence++}`);
|
|
92
|
-
const diagramRef = useRef(null);
|
|
93
43
|
const [svg, setSvg] = useState();
|
|
94
44
|
const [renderFailed, setRenderFailed] = useState(false);
|
|
95
|
-
const [selectedId, setSelectedId] = useState();
|
|
96
|
-
const [previewId, setPreviewId] = useState();
|
|
97
|
-
const operationRelationships = useMemo(
|
|
98
|
-
() => definition.relationships.filter(hasUsableOperations),
|
|
99
|
-
[definition.relationships]
|
|
100
|
-
);
|
|
101
|
-
const relationshipsById = useMemo(
|
|
102
|
-
() => new Map(
|
|
103
|
-
operationRelationships.map((relationship) => [
|
|
104
|
-
relationship.id,
|
|
105
|
-
relationship
|
|
106
|
-
])
|
|
107
|
-
),
|
|
108
|
-
[operationRelationships]
|
|
109
|
-
);
|
|
110
|
-
const selectedRelationship = selectedId ? relationshipsById.get(selectedId) : void 0;
|
|
111
|
-
const previewRelationship = previewId ? relationshipsById.get(previewId) : void 0;
|
|
112
45
|
useEffect(() => {
|
|
113
46
|
let active = true;
|
|
114
47
|
setSvg(void 0);
|
|
@@ -131,117 +64,25 @@ const ArchitectureDiagram = ({
|
|
|
131
64
|
active = false;
|
|
132
65
|
};
|
|
133
66
|
}, [definition.source]);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
setPreviewId(void 0);
|
|
140
|
-
}
|
|
141
|
-
}, [previewId, relationshipsById, selectedId]);
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
if (!svg || !diagramRef.current) return;
|
|
144
|
-
const edgePaths = diagramRef.current.querySelectorAll(".edgePath");
|
|
145
|
-
const edgeLabels = diagramRef.current.querySelectorAll(".edgeLabel");
|
|
146
|
-
operationRelationships.forEach((relationship) => {
|
|
147
|
-
const ariaLabel = `HTTP operations for ${relationship.fromLabel} to ${relationship.toLabel}`;
|
|
148
|
-
[
|
|
149
|
-
edgePaths.item(relationship.diagramIndex),
|
|
150
|
-
edgeLabels.item(relationship.diagramIndex)
|
|
151
|
-
].forEach((element) => {
|
|
152
|
-
if (!(element instanceof HTMLElement || element instanceof SVGElement)) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
element.dataset.anyshiftEdgeId = relationship.id;
|
|
156
|
-
element.setAttribute("role", "button");
|
|
157
|
-
element.setAttribute("tabindex", "0");
|
|
158
|
-
element.setAttribute("aria-label", ariaLabel);
|
|
159
|
-
element.setAttribute(
|
|
160
|
-
"aria-expanded",
|
|
161
|
-
String(selectedId === relationship.id)
|
|
162
|
-
);
|
|
163
|
-
element.classList.add("anyshift-http-edge-affordance");
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
}, [operationRelationships, selectedId, svg]);
|
|
167
|
-
const relationshipFromTarget = (target) => {
|
|
168
|
-
if (!(target instanceof Element)) return void 0;
|
|
169
|
-
const edge = target.closest("[data-anyshift-edge-id]");
|
|
170
|
-
const id = edge?.dataset.anyshiftEdgeId;
|
|
171
|
-
return id ? relationshipsById.get(id) : void 0;
|
|
172
|
-
};
|
|
173
|
-
const selectRelationship = (target) => {
|
|
174
|
-
const relationship = relationshipFromTarget(target);
|
|
175
|
-
if (relationship) setSelectedId(relationship.id);
|
|
176
|
-
};
|
|
177
|
-
const handleKeyDown = (event) => {
|
|
178
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
179
|
-
const relationship = relationshipFromTarget(event.target);
|
|
180
|
-
if (relationship) {
|
|
181
|
-
event.preventDefault();
|
|
182
|
-
setSelectedId(relationship.id);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (event.key === "Escape") setSelectedId(void 0);
|
|
186
|
-
};
|
|
187
|
-
const handleMouseOver = (event) => {
|
|
188
|
-
const relationship = relationshipFromTarget(event.target);
|
|
189
|
-
if (relationship) setPreviewId(relationship.id);
|
|
190
|
-
};
|
|
191
|
-
const handleMouseOut = (event) => {
|
|
192
|
-
const relationship = relationshipFromTarget(event.target);
|
|
193
|
-
const nextRelationship = relationshipFromTarget(event.relatedTarget);
|
|
194
|
-
if (relationship && relationship.id !== nextRelationship?.id) {
|
|
195
|
-
setPreviewId(void 0);
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
const handleFocus = (event) => {
|
|
199
|
-
const relationship = relationshipFromTarget(event.target);
|
|
200
|
-
if (relationship) setPreviewId(relationship.id);
|
|
201
|
-
};
|
|
202
|
-
const handleBlur = (event) => {
|
|
203
|
-
const relationship = relationshipFromTarget(event.target);
|
|
204
|
-
const nextRelationship = relationshipFromTarget(event.relatedTarget);
|
|
205
|
-
if (relationship && relationship.id !== nextRelationship?.id) {
|
|
206
|
-
setPreviewId(void 0);
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
return /* @__PURE__ */ jsxs(Box, { onKeyDown: handleKeyDown, children: [
|
|
210
|
-
renderFailed ? /* @__PURE__ */ jsx(
|
|
211
|
-
RelationshipFallback,
|
|
212
|
-
{
|
|
213
|
-
relationships: definition.relationships,
|
|
214
|
-
onSelect: (relationship) => setSelectedId(relationship.id),
|
|
215
|
-
selectedId
|
|
216
|
-
}
|
|
217
|
-
) : !svg ? /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gridGap: 8, py: 3, children: [
|
|
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: [
|
|
218
72
|
/* @__PURE__ */ jsx(CircularProgress, { size: 18 }),
|
|
219
73
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "Drawing architecture\u2026" })
|
|
220
|
-
] })
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
style: { overflowX: "auto" },
|
|
233
|
-
children: /* @__PURE__ */ jsx("div", { ref: diagramRef, dangerouslySetInnerHTML: { __html: svg } })
|
|
234
|
-
}
|
|
235
|
-
),
|
|
236
|
-
previewRelationship && /* @__PURE__ */ jsx(Typography, { role: "tooltip", variant: "caption", color: "textSecondary", children: operationPreview(previewRelationship) }),
|
|
237
|
-
selectedRelationship && /* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(
|
|
238
|
-
ArchitectureOperationDetails,
|
|
239
|
-
{
|
|
240
|
-
relationship: selectedRelationship,
|
|
241
|
-
onClose: () => setSelectedId(void 0)
|
|
242
|
-
}
|
|
243
|
-
) })
|
|
244
|
-
] });
|
|
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
|
+
);
|
|
245
86
|
};
|
|
246
87
|
|
|
247
88
|
export { ArchitectureDiagram };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MermaidArchitecture.esm.js","sources":["../../../src/components/entity/MermaidArchitecture.tsx"],"sourcesContent":["import {\n Box,\n CircularProgress,\n Typography,\n makeStyles,\n} from '@material-ui/core';\nimport mermaid from 'mermaid';\nimport {\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n buildArchitectureDiagram,\n type ArchitectureGraph,\n type ArchitectureDiagramRelationship,\n} from './architectureDiagram';\nimport {\n ArchitectureOperationDetails,\n operationPreview,\n} from './ArchitectureOperationDetails';\n\nlet diagramSequence = 0;\nlet mermaidInitialized = false;\n\nconst useStyles = makeStyles(theme => ({\n diagram: {\n '& .anyshift-http-edge-affordance': {\n cursor: 'pointer',\n },\n '& .anyshift-http-edge-affordance:focus': {\n outline: `2px solid ${theme.palette.text.primary}`,\n outlineOffset: 2,\n },\n '& .edgeLabel.anyshift-http-edge-affordance rect': {\n rx: 4,\n ry: 4,\n stroke: theme.palette.divider,\n strokeWidth: 1,\n },\n },\n fallbackButton: {\n appearance: 'none',\n background: 'transparent',\n border: 0,\n color: 'inherit',\n cursor: 'pointer',\n font: 'inherit',\n padding: 0,\n textAlign: 'left',\n '&:focus': {\n outline: `2px solid ${theme.palette.text.primary}`,\n outlineOffset: 2,\n },\n },\n}));\n\nconst hasUsableOperations = (\n relationship: ArchitectureDiagramRelationship,\n): boolean =>\n relationship.operationCount > 0 && operationPreview(relationship) !== '';\n\nconst RelationshipFallback = ({\n relationships,\n onSelect,\n selectedId,\n}: {\n relationships: ArchitectureDiagramRelationship[];\n onSelect: (relationship: ArchitectureDiagramRelationship) => void;\n selectedId?: string;\n}) => {\n const classes = useStyles();\n return (\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.id}\n py={0.5}\n style={{ listStyle: 'none' }}\n >\n {hasUsableOperations(relationship) ? (\n <button\n aria-label={`Show HTTP operations for ${relationship.fromLabel} to ${relationship.toLabel}`}\n aria-expanded={selectedId === relationship.id}\n className={classes.fallbackButton}\n onClick={() => onSelect(relationship)}\n type=\"button\"\n >\n <Typography component=\"span\" variant=\"body2\">\n {relationship.label}\n </Typography>\n </button>\n ) : (\n <Typography variant=\"body2\">{relationship.label}</Typography>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n\nexport const ArchitectureDiagram = ({\n graph,\n view = 'runtime',\n}: {\n graph: ArchitectureGraph;\n view?: 'context' | 'runtime';\n}) => {\n const classes = useStyles();\n const definition = useMemo(\n () => buildArchitectureDiagram(graph, { view }),\n [graph, view],\n );\n const diagramId = useRef(`anyshift-architecture-${diagramSequence++}`);\n const diagramRef = useRef<HTMLDivElement>(null);\n const [svg, setSvg] = useState<string>();\n const [renderFailed, setRenderFailed] = useState(false);\n const [selectedId, setSelectedId] = useState<string>();\n const [previewId, setPreviewId] = useState<string>();\n const operationRelationships = useMemo(\n () => definition.relationships.filter(hasUsableOperations),\n [definition.relationships],\n );\n const relationshipsById = useMemo(\n () =>\n new Map(\n operationRelationships.map(relationship => [\n relationship.id,\n relationship,\n ]),\n ),\n [operationRelationships],\n );\n const selectedRelationship = selectedId\n ? relationshipsById.get(selectedId)\n : undefined;\n const previewRelationship = previewId\n ? relationshipsById.get(previewId)\n : undefined;\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 useEffect(() => {\n if (selectedId && !relationshipsById.has(selectedId)) {\n setSelectedId(undefined);\n }\n if (previewId && !relationshipsById.has(previewId)) {\n setPreviewId(undefined);\n }\n }, [previewId, relationshipsById, selectedId]);\n\n useEffect(() => {\n if (!svg || !diagramRef.current) return;\n\n const edgePaths = diagramRef.current.querySelectorAll('.edgePath');\n const edgeLabels = diagramRef.current.querySelectorAll('.edgeLabel');\n operationRelationships.forEach(relationship => {\n const ariaLabel = `HTTP operations for ${relationship.fromLabel} to ${relationship.toLabel}`;\n [\n edgePaths.item(relationship.diagramIndex),\n edgeLabels.item(relationship.diagramIndex),\n ].forEach(element => {\n if (\n !(element instanceof HTMLElement || element instanceof SVGElement)\n ) {\n return;\n }\n element.dataset.anyshiftEdgeId = relationship.id;\n element.setAttribute('role', 'button');\n element.setAttribute('tabindex', '0');\n element.setAttribute('aria-label', ariaLabel);\n element.setAttribute(\n 'aria-expanded',\n String(selectedId === relationship.id),\n );\n element.classList.add('anyshift-http-edge-affordance');\n });\n });\n }, [operationRelationships, selectedId, svg]);\n\n const relationshipFromTarget = (target: EventTarget | null) => {\n if (!(target instanceof Element)) return undefined;\n const edge = target.closest<HTMLElement>('[data-anyshift-edge-id]');\n const id = edge?.dataset.anyshiftEdgeId;\n return id ? relationshipsById.get(id) : undefined;\n };\n\n const selectRelationship = (target: EventTarget | null) => {\n const relationship = relationshipFromTarget(target);\n if (relationship) setSelectedId(relationship.id);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key === 'Enter' || event.key === ' ') {\n const relationship = relationshipFromTarget(event.target);\n if (relationship) {\n event.preventDefault();\n setSelectedId(relationship.id);\n }\n }\n if (event.key === 'Escape') setSelectedId(undefined);\n };\n\n const handleMouseOver = (event: MouseEvent<HTMLElement>) => {\n const relationship = relationshipFromTarget(event.target);\n if (relationship) setPreviewId(relationship.id);\n };\n\n const handleMouseOut = (event: MouseEvent<HTMLElement>) => {\n const relationship = relationshipFromTarget(event.target);\n const nextRelationship = relationshipFromTarget(event.relatedTarget);\n if (relationship && relationship.id !== nextRelationship?.id) {\n setPreviewId(undefined);\n }\n };\n\n const handleFocus = (event: FocusEvent<HTMLElement>) => {\n const relationship = relationshipFromTarget(event.target);\n if (relationship) setPreviewId(relationship.id);\n };\n\n const handleBlur = (event: FocusEvent<HTMLElement>) => {\n const relationship = relationshipFromTarget(event.target);\n const nextRelationship = relationshipFromTarget(event.relatedTarget);\n if (relationship && relationship.id !== nextRelationship?.id) {\n setPreviewId(undefined);\n }\n };\n\n return (\n <Box onKeyDown={handleKeyDown}>\n {renderFailed ? (\n <RelationshipFallback\n relationships={definition.relationships}\n onSelect={relationship => setSelectedId(relationship.id)}\n selectedId={selectedId}\n />\n ) : !svg ? (\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 <Box\n aria-label=\"C4 architecture diagram\"\n className={classes.diagram}\n onBlur={handleBlur}\n onClick={event => selectRelationship(event.target)}\n onFocus={handleFocus}\n onMouseOut={handleMouseOut}\n onMouseOver={handleMouseOver}\n role=\"group\"\n mt={1}\n style={{ overflowX: 'auto' }}\n >\n <div ref={diagramRef} dangerouslySetInnerHTML={{ __html: svg }} />\n </Box>\n )}\n {previewRelationship && (\n <Typography role=\"tooltip\" variant=\"caption\" color=\"textSecondary\">\n {operationPreview(previewRelationship)}\n </Typography>\n )}\n {selectedRelationship && (\n <Box mt={2}>\n <ArchitectureOperationDetails\n relationship={selectedRelationship}\n onClose={() => setSelectedId(undefined)}\n />\n </Box>\n )}\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
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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"}
|