@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.
Files changed (49) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +3 -11
  3. package/dist/api/AnyshiftApi.esm.js +5 -56
  4. package/dist/api/AnyshiftApi.esm.js.map +1 -1
  5. package/dist/components/cloud/CloudResourceContent.esm.js +45 -444
  6. package/dist/components/cloud/CloudResourceContent.esm.js.map +1 -1
  7. package/dist/components/entity/AnyshiftEntityContent.esm.js +23 -128
  8. package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -1
  9. package/dist/components/entity/BriefSections.esm.js +4 -24
  10. package/dist/components/entity/BriefSections.esm.js.map +1 -1
  11. package/dist/components/entity/DatadogLiveSignal.esm.js +23 -85
  12. package/dist/components/entity/DatadogLiveSignal.esm.js.map +1 -1
  13. package/dist/components/entity/MermaidArchitecture.esm.js +43 -202
  14. package/dist/components/entity/MermaidArchitecture.esm.js.map +1 -1
  15. package/dist/components/entity/SectionPresenters.esm.js +82 -145
  16. package/dist/components/entity/SectionPresenters.esm.js.map +1 -1
  17. package/dist/components/entity/architectureDiagram.esm.js +15 -48
  18. package/dist/components/entity/architectureDiagram.esm.js.map +1 -1
  19. package/dist/components/explorer/AnyshiftExplorerPage.esm.js +19 -154
  20. package/dist/components/explorer/AnyshiftExplorerPage.esm.js.map +1 -1
  21. package/dist/components/explorer/DatadogOperationsRadar.esm.js +31 -92
  22. package/dist/components/explorer/DatadogOperationsRadar.esm.js.map +1 -1
  23. package/dist/index.d.ts +4 -18
  24. package/dist/index.esm.js +1 -1
  25. package/dist/package.json.esm.js +13 -13
  26. package/dist/plugin.esm.js +2 -6
  27. package/dist/plugin.esm.js.map +1 -1
  28. package/package.json +15 -15
  29. package/CHANGELOG.md +0 -87
  30. package/dist/components/ask/AskAnyshiftCard.esm.js +0 -348
  31. package/dist/components/ask/AskAnyshiftCard.esm.js.map +0 -1
  32. package/dist/components/ask/askPresenters.esm.js +0 -1203
  33. package/dist/components/ask/askPresenters.esm.js.map +0 -1
  34. package/dist/components/ask/askScope.esm.js +0 -27
  35. package/dist/components/ask/askScope.esm.js.map +0 -1
  36. package/dist/components/ask/askSuggestions.esm.js +0 -41
  37. package/dist/components/ask/askSuggestions.esm.js.map +0 -1
  38. package/dist/components/cloud/CloudImpactSection.esm.js +0 -54
  39. package/dist/components/cloud/CloudImpactSection.esm.js.map +0 -1
  40. package/dist/components/cloud/CloudRelationshipSections.esm.js +0 -43
  41. package/dist/components/cloud/CloudRelationshipSections.esm.js.map +0 -1
  42. package/dist/components/entity/ArchitectureOperationDetails.esm.js +0 -107
  43. package/dist/components/entity/ArchitectureOperationDetails.esm.js.map +0 -1
  44. package/dist/components/entity/architectureGraph.esm.js +0 -145
  45. package/dist/components/entity/architectureGraph.esm.js.map +0 -1
  46. package/dist/components/entity/entityIdentity.esm.js +0 -40
  47. package/dist/components/entity/entityIdentity.esm.js.map +0 -1
  48. package/dist/components/entity/relatedCatalogEntities.esm.js +0 -60
  49. package/dist/components/entity/relatedCatalogEntities.esm.js.map +0 -1
@@ -1,39 +1,21 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
2
+ import { useState, useRef, useCallback, useEffect } from 'react';
3
3
  import { Typography, Box, Chip, Button, CircularProgress, Grid } from '@material-ui/core';
4
4
  import { Progress } from '@backstage/core-components';
5
- import { useApi, useApiHolder } from '@backstage/frontend-plugin-api';
6
- import { ANYSHIFT_KIND_ANNOTATION, ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION, ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION, ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION, ANYSHIFT_RESOURCE_ID_ANNOTATION } from '@anyshift/backstage-plugin-anyshift-common';
7
- import { useEntity, catalogApiRef } from '@backstage/plugin-catalog-react';
5
+ import { useApi } from '@backstage/frontend-plugin-api';
6
+ import { ANYSHIFT_KIND_ANNOTATION, ANYSHIFT_TARGET_ANNOTATION, GITHUB_PROJECT_SLUG_ANNOTATION } from '@anyshift/backstage-plugin-anyshift-common';
7
+ import { useEntity } from '@backstage/plugin-catalog-react';
8
8
  import { anyshiftApiRef } from '../../api/AnyshiftApi.esm.js';
9
- import { AskAnyshiftCard } from '../ask/AskAnyshiftCard.esm.js';
10
- import { askScopeForEntity } from '../ask/askScope.esm.js';
11
- import { CloudAnyshiftEntityContent } from '../cloud/CloudResourceContent.esm.js';
12
- import { isCloudResourceEntity, entityTarget } from './entityIdentity.esm.js';
13
- import { resolveRelatedCatalogEntities } from './relatedCatalogEntities.esm.js';
14
- import { OverviewSection, WhyNowSection, DatadogSignalSection, ArchitectureSection, DependencySection, BriefRail, TimelineSection } from './BriefSections.esm.js';
9
+ import { OverviewSection, DatadogSignalSection, ArchitectureSection, DependencySection, BriefRail, TimelineSection } from './BriefSections.esm.js';
15
10
 
16
11
  const AnyshiftEntityContent = () => {
17
- const { entity } = useEntity();
18
- return isCloudResourceEntity(entity) ? /* @__PURE__ */ jsx(CloudAnyshiftEntityContent, {}) : /* @__PURE__ */ jsx(ServiceAnyshiftEntityContent, {});
19
- };
20
- const ServiceAnyshiftEntityContent = () => {
21
12
  const { entity } = useEntity();
22
13
  const api = useApi(anyshiftApiRef);
23
- const catalogApi = useApiHolder().get(catalogApiRef);
24
14
  const annotations = entity.metadata.annotations ?? {};
25
15
  const target = entityTarget(entity);
26
16
  const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || "workload";
27
17
  const namespace = entity.metadata.namespace;
28
- const configurationEndpoints = annotations[ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION];
29
- const configurationDependencies = annotations[ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION];
30
- const configurationTarget = annotations[ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION] ?? annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION];
31
18
  const [brief, setBrief] = useState();
32
- const [catalogEntities, setCatalogEntities] = useState([]);
33
- const [capabilities, setCapabilities] = useState({
34
- askEnabled: false,
35
- queryEnabled: false
36
- });
37
19
  const [error, setError] = useState();
38
20
  const [refreshingAll, setRefreshingAll] = useState(false);
39
21
  const [refreshing, setRefreshing] = useState(
@@ -45,13 +27,7 @@ const ServiceAnyshiftEntityContent = () => {
45
27
  setError(void 0);
46
28
  if (refresh) setRefreshingAll(true);
47
29
  try {
48
- const next = await api.brief(kind, target, {
49
- namespace,
50
- refresh,
51
- configurationEndpoints,
52
- configurationDependencies,
53
- configurationTarget
54
- });
30
+ const next = await api.brief(kind, target, { namespace, refresh });
55
31
  if (active.current) setBrief(next);
56
32
  } catch (cause) {
57
33
  if (active.current)
@@ -60,15 +36,7 @@ const ServiceAnyshiftEntityContent = () => {
60
36
  if (active.current) setRefreshingAll(false);
61
37
  }
62
38
  },
63
- [
64
- api,
65
- configurationDependencies,
66
- configurationEndpoints,
67
- configurationTarget,
68
- kind,
69
- namespace,
70
- target
71
- ]
39
+ [api, kind, namespace, target]
72
40
  );
73
41
  const retrySection = useCallback(
74
42
  async (section) => {
@@ -76,10 +44,7 @@ const ServiceAnyshiftEntityContent = () => {
76
44
  try {
77
45
  const response = await api.briefSection(kind, target, section, {
78
46
  namespace,
79
- refresh: true,
80
- configurationEndpoints,
81
- configurationDependencies,
82
- configurationTarget
47
+ refresh: true
83
48
  });
84
49
  if (active.current) {
85
50
  setBrief(
@@ -101,15 +66,7 @@ const ServiceAnyshiftEntityContent = () => {
101
66
  }
102
67
  }
103
68
  },
104
- [
105
- api,
106
- configurationDependencies,
107
- configurationEndpoints,
108
- configurationTarget,
109
- kind,
110
- namespace,
111
- target
112
- ]
69
+ [api, kind, namespace, target]
113
70
  );
114
71
  useEffect(() => {
115
72
  active.current = true;
@@ -118,71 +75,28 @@ const ServiceAnyshiftEntityContent = () => {
118
75
  active.current = false;
119
76
  };
120
77
  }, [load]);
121
- useEffect(() => {
122
- let cancelled = false;
123
- if (!catalogApi) {
124
- setCatalogEntities([]);
125
- return () => {
126
- cancelled = true;
127
- };
128
- }
129
- catalogApi.getEntities({
130
- filter: [{ kind: "Component" }, { kind: "Resource" }],
131
- fields: ["kind", "metadata.name", "metadata.namespace"]
132
- }).then((response) => {
133
- if (!cancelled) setCatalogEntities(response.items);
134
- }).catch(() => {
135
- if (!cancelled) setCatalogEntities([]);
136
- });
137
- return () => {
138
- cancelled = true;
139
- };
140
- }, [catalogApi]);
141
- useEffect(() => {
142
- api.capabilities().then((next) => {
143
- if (active.current) setCapabilities(next);
144
- }).catch(() => {
145
- if (active.current) {
146
- setCapabilities({ askEnabled: false, queryEnabled: false });
147
- }
148
- });
149
- }, [api]);
150
- const resolvedBrief = useMemo(() => {
151
- if (!brief || brief.impact.state !== "data" || !brief.impact.data)
152
- return brief;
153
- const impactData = brief.impact.data;
154
- return {
155
- ...brief,
156
- impact: {
157
- ...brief.impact,
158
- data: {
159
- ...impactData,
160
- relatedEntities: resolveRelatedCatalogEntities(
161
- impactData.relatedEntities,
162
- catalogEntities
163
- )
164
- }
165
- }
166
- };
167
- }, [brief, catalogEntities]);
168
- if (error && !resolvedBrief)
169
- return /* @__PURE__ */ jsx(Typography, { color: "error", children: error });
170
- if (!resolvedBrief) return /* @__PURE__ */ jsx(Progress, {});
78
+ if (error && !brief) return /* @__PURE__ */ jsx(Typography, { color: "error", children: error });
79
+ if (!brief) return /* @__PURE__ */ jsx(Progress, {});
171
80
  return /* @__PURE__ */ jsx(
172
81
  ServiceBriefView,
173
82
  {
174
- brief: resolvedBrief,
83
+ brief,
175
84
  onRetry: retrySection,
176
85
  refreshing,
177
86
  onRefresh: () => void load(true),
178
87
  refreshingAll,
179
- refreshError: error,
180
- askEnabled: capabilities.askEnabled,
181
- askScope: askScopeForEntity(entity),
182
- askScopeLabel: target
88
+ refreshError: error
183
89
  }
184
90
  );
185
91
  };
92
+ function entityTarget(entity) {
93
+ const annotations = entity.metadata.annotations ?? {};
94
+ const explicit = annotations[ANYSHIFT_TARGET_ANNOTATION]?.trim();
95
+ if (explicit) return explicit;
96
+ const slug = annotations[GITHUB_PROJECT_SLUG_ANNOTATION]?.trim();
97
+ const repository = slug?.split("/").filter(Boolean).at(-1);
98
+ return repository || entity.metadata.name;
99
+ }
186
100
  const ServiceBriefView = ({
187
101
  brief,
188
102
  onRetry,
@@ -190,10 +104,7 @@ const ServiceBriefView = ({
190
104
  onRefresh = () => {
191
105
  },
192
106
  refreshingAll = false,
193
- refreshError,
194
- askEnabled = false,
195
- askScope,
196
- askScopeLabel
107
+ refreshError
197
108
  }) => /* @__PURE__ */ jsxs(Fragment, { children: [
198
109
  /* @__PURE__ */ jsxs(
199
110
  Box,
@@ -258,22 +169,6 @@ const ServiceBriefView = ({
258
169
  refreshing: refreshing.has("overview")
259
170
  }
260
171
  ) }),
261
- /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
262
- WhyNowSection,
263
- {
264
- section: brief.whyNow,
265
- onRetry,
266
- refreshing: refreshing.has("whyNow")
267
- }
268
- ) }),
269
- askEnabled && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
270
- AskAnyshiftCard,
271
- {
272
- context: "entity",
273
- scope: askScope,
274
- scopeLabel: askScopeLabel
275
- }
276
- ) }),
277
172
  /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
278
173
  DatadogSignalSection,
279
174
  {
@@ -314,5 +209,5 @@ function formatTimestamp(value) {
314
209
  return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();
315
210
  }
316
211
 
317
- export { AnyshiftEntityContent, ServiceAnyshiftEntityContent, ServiceBriefView };
212
+ export { AnyshiftEntityContent, ServiceBriefView, entityTarget };
318
213
  //# sourceMappingURL=AnyshiftEntityContent.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnyshiftEntityContent.esm.js","sources":["../../../src/components/entity/AnyshiftEntityContent.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { useApi, useApiHolder } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION,\n ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION,\n ANYSHIFT_KIND_ANNOTATION,\n ANYSHIFT_RESOURCE_ID_ANNOTATION,\n ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type {\n AnyshiftCapabilities,\n AskScope,\n BriefSectionName,\n ServiceBrief,\n} from '../../api/types';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport { CloudAnyshiftEntityContent } from '../cloud/CloudResourceContent';\nimport { entityTarget, isCloudResourceEntity } from './entityIdentity';\nimport { resolveRelatedCatalogEntities } from './relatedCatalogEntities';\nimport {\n ArchitectureSection,\n BriefRail,\n DatadogSignalSection,\n DependencySection,\n OverviewSection,\n TimelineSection,\n WhyNowSection,\n} from './BriefSections';\n\nexport const AnyshiftEntityContent = () => {\n const { entity } = useEntity();\n return isCloudResourceEntity(entity) ? (\n <CloudAnyshiftEntityContent />\n ) : (\n <ServiceAnyshiftEntityContent />\n );\n};\n\nexport const ServiceAnyshiftEntityContent = () => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const catalogApi = useApiHolder().get(catalogApiRef);\n const annotations = entity.metadata.annotations ?? {};\n const target = entityTarget(entity);\n const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || 'workload';\n const namespace = entity.metadata.namespace;\n const configurationEndpoints =\n annotations[ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION];\n const configurationDependencies =\n annotations[ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION];\n const configurationTarget =\n annotations[ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION] ??\n annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION];\n const [brief, setBrief] = useState<ServiceBrief>();\n const [catalogEntities, setCatalogEntities] = useState<Entity[]>([]);\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const [error, setError] = useState<string>();\n const [refreshingAll, setRefreshingAll] = useState(false);\n const [refreshing, setRefreshing] = useState<Set<BriefSectionName>>(\n new Set(),\n );\n const active = useRef(true);\n\n const load = useCallback(\n async (refresh = false) => {\n setError(undefined);\n if (refresh) setRefreshingAll(true);\n try {\n const next = await api.brief(kind, target, {\n namespace,\n refresh,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) setBrief(next);\n } catch (cause) {\n if (active.current)\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (active.current) setRefreshingAll(false);\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n const retrySection = useCallback(\n async (section: BriefSectionName) => {\n setRefreshing(current => new Set(current).add(section));\n try {\n const response = await api.briefSection(kind, target, section, {\n namespace,\n refresh: true,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) {\n setBrief(current =>\n current\n ? {\n ...current,\n [section]: response.value,\n refreshedAt: response.refreshedAt,\n ...(response.observedService\n ? { observedService: response.observedService }\n : {}),\n }\n : current,\n );\n }\n } finally {\n if (active.current) {\n setRefreshing(current => {\n const next = new Set(current);\n next.delete(section);\n return next;\n });\n }\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n useEffect(() => {\n active.current = true;\n void load();\n return () => {\n active.current = false;\n };\n }, [load]);\n\n useEffect(() => {\n let cancelled = false;\n if (!catalogApi) {\n setCatalogEntities([]);\n return () => {\n cancelled = true;\n };\n }\n catalogApi\n .getEntities({\n filter: [{ kind: 'Component' }, { kind: 'Resource' }],\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n })\n .then(response => {\n if (!cancelled) setCatalogEntities(response.items);\n })\n .catch(() => {\n if (!cancelled) setCatalogEntities([]);\n });\n return () => {\n cancelled = true;\n };\n }, [catalogApi]);\n\n useEffect(() => {\n api\n .capabilities()\n .then(next => {\n if (active.current) setCapabilities(next);\n })\n .catch(() => {\n if (active.current) {\n setCapabilities({ askEnabled: false, queryEnabled: false });\n }\n });\n }, [api]);\n\n const resolvedBrief = useMemo<ServiceBrief | undefined>(() => {\n if (!brief || brief.impact.state !== 'data' || !brief.impact.data)\n return brief;\n const impactData = brief.impact.data;\n return {\n ...brief,\n impact: {\n ...brief.impact,\n data: {\n ...impactData,\n relatedEntities: resolveRelatedCatalogEntities(\n impactData.relatedEntities,\n catalogEntities,\n ),\n },\n },\n };\n }, [brief, catalogEntities]);\n\n if (error && !resolvedBrief)\n return <Typography color=\"error\">{error}</Typography>;\n if (!resolvedBrief) return <Progress />;\n return (\n <ServiceBriefView\n brief={resolvedBrief}\n onRetry={retrySection}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n refreshingAll={refreshingAll}\n refreshError={error}\n askEnabled={capabilities.askEnabled}\n askScope={askScopeForEntity(entity)}\n askScopeLabel={target}\n />\n );\n};\n\nexport const ServiceBriefView = ({\n brief,\n onRetry,\n refreshing = new Set(),\n onRefresh = () => {},\n refreshingAll = false,\n refreshError,\n askEnabled = false,\n askScope,\n askScopeLabel,\n}: {\n brief: ServiceBrief;\n onRetry: (section: BriefSectionName) => void;\n refreshing?: ReadonlySet<BriefSectionName>;\n onRefresh?: () => void;\n refreshingAll?: boolean;\n refreshError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n askScopeLabel?: string;\n}) => (\n <>\n <Box\n mb={3}\n px={2.5}\n py={2}\n borderLeft={4}\n borderColor=\"primary.main\"\n bgcolor=\"background.paper\"\n >\n <Box display=\"flex\" justifyContent=\"space-between\" gridGap={16}>\n <Box>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Anyshift evidence trace\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Chip size=\"small\" label={`Workload · ${brief.target}`} />\n <Typography aria-hidden=\"true\" color=\"primary\">\n →\n </Typography>\n <Chip\n size=\"small\"\n color=\"primary\"\n label={`Observed service · ${\n brief.observedService || 'Not resolved'\n }`}\n />\n </Box>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Runtime namespace: {brief.namespace || 'Not set'} · Refreshed{' '}\n {formatTimestamp(brief.refreshedAt)}\n </Typography>\n </Box>\n <Button\n type=\"button\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onRefresh}\n disabled={refreshingAll}\n startIcon={refreshingAll ? <CircularProgress size={14} /> : undefined}\n >\n {refreshingAll ? 'Refreshing…' : 'Refresh brief'}\n </Button>\n </Box>\n {refreshError && (\n <Typography color=\"error\" variant=\"caption\">\n Refresh failed: {refreshError}. Existing evidence is still shown.\n </Typography>\n )}\n </Box>\n\n <Grid container spacing={3} alignItems=\"stretch\">\n <Grid item xs={12}>\n <OverviewSection\n section={brief.overview}\n onRetry={onRetry}\n refreshing={refreshing.has('overview')}\n />\n </Grid>\n <Grid item xs={12}>\n <WhyNowSection\n section={brief.whyNow}\n onRetry={onRetry}\n refreshing={refreshing.has('whyNow')}\n />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard\n context=\"entity\"\n scope={askScope}\n scopeLabel={askScopeLabel}\n />\n </Grid>\n )}\n <Grid item xs={12}>\n <DatadogSignalSection\n section={brief.observability}\n onRetry={onRetry}\n refreshing={refreshing.has('observability')}\n />\n </Grid>\n <Grid item xs={12}>\n <ArchitectureSection\n section={brief.architecture}\n onRetry={onRetry}\n refreshing={refreshing.has('architecture')}\n />\n </Grid>\n <Grid item xs={12} md={8}>\n <DependencySection\n section={brief.topology}\n onRetry={onRetry}\n refreshing={refreshing.has('topology')}\n />\n </Grid>\n <Grid item xs={12} md={4}>\n <BriefRail brief={brief} onRetry={onRetry} refreshing={refreshing} />\n </Grid>\n <Grid item xs={12}>\n <TimelineSection\n section={brief.timeline}\n onRetry={onRetry}\n refreshing={refreshing.has('timeline')}\n />\n </Grid>\n </Grid>\n </>\n);\n\nfunction formatTimestamp(value: string): string {\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AnyshiftEntityContent.esm.js","sources":["../../../src/components/entity/AnyshiftEntityContent.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport {\n ANYSHIFT_KIND_ANNOTATION,\n ANYSHIFT_TARGET_ANNOTATION,\n GITHUB_PROJECT_SLUG_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport type { Entity } from '@backstage/catalog-model';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type { BriefSectionName, ServiceBrief } from '../../api/types';\nimport {\n ArchitectureSection,\n BriefRail,\n DatadogSignalSection,\n DependencySection,\n OverviewSection,\n TimelineSection,\n} from './BriefSections';\n\nexport const AnyshiftEntityContent = () => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const annotations = entity.metadata.annotations ?? {};\n const target = entityTarget(entity);\n const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || 'workload';\n const namespace = entity.metadata.namespace;\n const [brief, setBrief] = useState<ServiceBrief>();\n const [error, setError] = useState<string>();\n const [refreshingAll, setRefreshingAll] = useState(false);\n const [refreshing, setRefreshing] = useState<Set<BriefSectionName>>(\n new Set(),\n );\n const active = useRef(true);\n\n const load = useCallback(\n async (refresh = false) => {\n setError(undefined);\n if (refresh) setRefreshingAll(true);\n try {\n const next = await api.brief(kind, target, { namespace, refresh });\n if (active.current) setBrief(next);\n } catch (cause) {\n if (active.current)\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (active.current) setRefreshingAll(false);\n }\n },\n [api, kind, namespace, target],\n );\n\n const retrySection = useCallback(\n async (section: BriefSectionName) => {\n setRefreshing(current => new Set(current).add(section));\n try {\n const response = await api.briefSection(kind, target, section, {\n namespace,\n refresh: true,\n });\n if (active.current) {\n setBrief(current =>\n current\n ? {\n ...current,\n [section]: response.value,\n refreshedAt: response.refreshedAt,\n ...(response.observedService\n ? { observedService: response.observedService }\n : {}),\n }\n : current,\n );\n }\n } finally {\n if (active.current) {\n setRefreshing(current => {\n const next = new Set(current);\n next.delete(section);\n return next;\n });\n }\n }\n },\n [api, kind, namespace, target],\n );\n\n useEffect(() => {\n active.current = true;\n void load();\n return () => {\n active.current = false;\n };\n }, [load]);\n\n if (error && !brief) return <Typography color=\"error\">{error}</Typography>;\n if (!brief) return <Progress />;\n return (\n <ServiceBriefView\n brief={brief}\n onRetry={retrySection}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n refreshingAll={refreshingAll}\n refreshError={error}\n />\n );\n};\n\nexport function entityTarget(entity: Entity): string {\n const annotations = entity.metadata.annotations ?? {};\n const explicit = annotations[ANYSHIFT_TARGET_ANNOTATION]?.trim();\n if (explicit) return explicit;\n\n const slug = annotations[GITHUB_PROJECT_SLUG_ANNOTATION]?.trim();\n const repository = slug?.split('/').filter(Boolean).at(-1);\n return repository || entity.metadata.name;\n}\n\nexport const ServiceBriefView = ({\n brief,\n onRetry,\n refreshing = new Set(),\n onRefresh = () => {},\n refreshingAll = false,\n refreshError,\n}: {\n brief: ServiceBrief;\n onRetry: (section: BriefSectionName) => void;\n refreshing?: ReadonlySet<BriefSectionName>;\n onRefresh?: () => void;\n refreshingAll?: boolean;\n refreshError?: string;\n}) => (\n <>\n <Box\n mb={3}\n px={2.5}\n py={2}\n borderLeft={4}\n borderColor=\"primary.main\"\n bgcolor=\"background.paper\"\n >\n <Box display=\"flex\" justifyContent=\"space-between\" gridGap={16}>\n <Box>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Anyshift evidence trace\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Chip size=\"small\" label={`Workload · ${brief.target}`} />\n <Typography aria-hidden=\"true\" color=\"primary\">\n →\n </Typography>\n <Chip\n size=\"small\"\n color=\"primary\"\n label={`Observed service · ${\n brief.observedService || 'Not resolved'\n }`}\n />\n </Box>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Runtime namespace: {brief.namespace || 'Not set'} · Refreshed{' '}\n {formatTimestamp(brief.refreshedAt)}\n </Typography>\n </Box>\n <Button\n type=\"button\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onRefresh}\n disabled={refreshingAll}\n startIcon={refreshingAll ? <CircularProgress size={14} /> : undefined}\n >\n {refreshingAll ? 'Refreshing…' : 'Refresh brief'}\n </Button>\n </Box>\n {refreshError && (\n <Typography color=\"error\" variant=\"caption\">\n Refresh failed: {refreshError}. Existing evidence is still shown.\n </Typography>\n )}\n </Box>\n\n <Grid container spacing={3} alignItems=\"stretch\">\n <Grid item xs={12}>\n <OverviewSection\n section={brief.overview}\n onRetry={onRetry}\n refreshing={refreshing.has('overview')}\n />\n </Grid>\n <Grid item xs={12}>\n <DatadogSignalSection\n section={brief.observability}\n onRetry={onRetry}\n refreshing={refreshing.has('observability')}\n />\n </Grid>\n <Grid item xs={12}>\n <ArchitectureSection\n section={brief.architecture}\n onRetry={onRetry}\n refreshing={refreshing.has('architecture')}\n />\n </Grid>\n <Grid item xs={12} md={8}>\n <DependencySection\n section={brief.topology}\n onRetry={onRetry}\n refreshing={refreshing.has('topology')}\n />\n </Grid>\n <Grid item xs={12} md={4}>\n <BriefRail brief={brief} onRetry={onRetry} refreshing={refreshing} />\n </Grid>\n <Grid item xs={12}>\n <TimelineSection\n section={brief.timeline}\n onRetry={onRetry}\n refreshing={refreshing.has('timeline')}\n />\n </Grid>\n </Grid>\n </>\n);\n\nfunction formatTimestamp(value: string): string {\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { Box, Grid, Typography, Button, CircularProgress } from '@material-ui/core';
3
3
  import { InfoCard } from '@backstage/core-components';
4
- import { OverviewPresenter, WhyNowPresenter, ArchitecturePresenter, DependencyFootprintPresenter, AffectedFootprintPresenter, LatestChangePresenter, SafeguardsPresenter, TimelinePresenter } from './SectionPresenters.esm.js';
4
+ import { OverviewPresenter, ArchitecturePresenter, DependencyFootprintPresenter, OperationalPosturePresenter, LatestChangePresenter, SafeguardsPresenter, TimelinePresenter } from './SectionPresenters.esm.js';
5
5
  import { DatadogSignalStripPresenter } from './DatadogLiveSignal.esm.js';
6
6
 
7
7
  const OverviewSection = ({
@@ -58,26 +58,6 @@ const DatadogSignalSection = ({
58
58
  renderData: (data) => /* @__PURE__ */ jsx(DatadogSignalStripPresenter, { data })
59
59
  }
60
60
  ) }) });
61
- const WhyNowSection = ({
62
- section,
63
- onRetry,
64
- refreshing
65
- }) => /* @__PURE__ */ jsx(
66
- SectionCard,
67
- {
68
- title: "Why now?",
69
- subheader: "Current symptoms and evidence-backed suspects",
70
- children: /* @__PURE__ */ jsx(
71
- DataSection,
72
- {
73
- section,
74
- onRetry: () => onRetry("whyNow"),
75
- refreshing,
76
- renderData: (data) => /* @__PURE__ */ jsx(WhyNowPresenter, { data })
77
- }
78
- )
79
- }
80
- );
81
61
  const BriefRail = ({
82
62
  brief,
83
63
  onRetry,
@@ -86,11 +66,11 @@ const BriefRail = ({
86
66
  /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
87
67
  CompactSection,
88
68
  {
89
- title: "Affected footprint",
69
+ title: "Operational posture",
90
70
  section: brief.impact,
91
71
  onRetry: () => onRetry("impact"),
92
72
  refreshing: refreshing.has("impact"),
93
- renderData: (data) => /* @__PURE__ */ jsx(AffectedFootprintPresenter, { data })
73
+ renderData: (data) => /* @__PURE__ */ jsx(OperationalPosturePresenter, { data })
94
74
  }
95
75
  ) }),
96
76
  /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
@@ -234,5 +214,5 @@ const RetryControl = ({
234
214
  }
235
215
  );
236
216
 
237
- export { ArchitectureSection, BriefRail, DatadogSignalSection, DependencySection, OverviewSection, TimelineSection, WhyNowSection };
217
+ export { ArchitectureSection, BriefRail, DatadogSignalSection, DependencySection, OverviewSection, TimelineSection };
238
218
  //# sourceMappingURL=BriefSections.esm.js.map
@@ -1 +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 EntityImpact,\n SafeguardResult,\n ServiceBrief,\n ServiceOverview,\n WhyNowAssessment,\n} from '../../api/types';\nimport {\n AffectedFootprintPresenter,\n ArchitecturePresenter,\n DependencyFootprintPresenter,\n LatestChangePresenter,\n OverviewPresenter,\n SafeguardsPresenter,\n TimelinePresenter,\n WhyNowPresenter,\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 WhyNowSection = ({\n section,\n onRetry,\n refreshing,\n}: {\n section: BriefSection<WhyNowAssessment>;\n onRetry: RetrySection;\n refreshing?: boolean;\n}) => (\n <SectionCard\n title=\"Why now?\"\n subheader=\"Current symptoms and evidence-backed suspects\"\n >\n <DataSection\n section={section}\n onRetry={() => onRetry('whyNow')}\n refreshing={refreshing}\n renderData={data => <WhyNowPresenter data={data} />}\n />\n </SectionCard>\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=\"Affected footprint\"\n section={brief.impact}\n onRetry={() => onRetry('impact')}\n refreshing={refreshing.has('impact')}\n renderData={(data: EntityImpact) => (\n <AffectedFootprintPresenter data={data} />\n )}\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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"}
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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"}
@@ -1,15 +1,15 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { Box, Typography, makeStyles } from '@material-ui/core';
3
3
  import { EvidenceDisclosure } from './EvidenceDisclosure.esm.js';
4
4
 
5
5
  const STATE_COPY = {
6
6
  firing: {
7
7
  headline: "Service on fire",
8
- detail: (signal) => `${signal.activeHasMore ? "At least " : ""}${signal.active} ${signal.active === 1 ? "alert" : "alerts"} firing now`
8
+ detail: (signal) => `${signal.active} ${signal.active === 1 ? "monitor" : "monitors"} firing now`
9
9
  },
10
10
  noisy: {
11
11
  headline: "Quiet now \xB7 noisy lately",
12
- detail: () => "No alert is firing now."
12
+ detail: () => "No monitor is firing now."
13
13
  },
14
14
  quiet: {
15
15
  headline: "Quiet",
@@ -17,7 +17,7 @@ const STATE_COPY = {
17
17
  },
18
18
  unavailable: {
19
19
  headline: "Signal unavailable",
20
- detail: (signal) => signal.partial ? "Operational alert evidence is incomplete." : "No operational alert evidence was returned."
20
+ detail: () => "No Datadog signal evidence was returned."
21
21
  }
22
22
  };
23
23
  const STATE_COLORS = {
@@ -87,66 +87,22 @@ const DatadogSignalStripPresenter = ({ data }) => {
87
87
  /* @__PURE__ */ jsx(Typography, { variant: "h6", className: classes.headline, children: copy.headline }),
88
88
  /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: compactSummary(signal) })
89
89
  ] }),
90
- signal.partial && /* @__PURE__ */ jsxs(Fragment, { children: [
91
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", component: "p", children: signal.activeHasMore ? "Additional alert rows are available; the loaded count is a lower bound." : "Some operational alert evidence is temporarily unavailable." }),
92
- /* @__PURE__ */ jsx(AlertCoverage, { signal })
93
- ] }),
90
+ signal.partial && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", component: "p", children: "Some Datadog evidence is temporarily unavailable." }),
94
91
  /* @__PURE__ */ jsx(EvidenceDisclosure, { data })
95
92
  ] });
96
93
  };
97
- const AlertCoverage = ({ signal }) => /* @__PURE__ */ jsxs(Fragment, { children: [
98
- signal.providers.filter((provider) => provider.status !== "available").map((provider) => /* @__PURE__ */ jsxs(
99
- Typography,
100
- {
101
- variant: "caption",
102
- color: "textSecondary",
103
- component: "p",
104
- children: [
105
- "Alert coverage: ",
106
- readableProvider(provider.provider),
107
- " ",
108
- provider.status,
109
- "."
110
- ]
111
- },
112
- provider.provider
113
- )),
114
- signal.warnings.map((warning) => /* @__PURE__ */ jsxs(
115
- Typography,
116
- {
117
- variant: "caption",
118
- color: "textSecondary",
119
- component: "p",
120
- children: [
121
- "Alert warning: ",
122
- warning.message,
123
- warning.message.endsWith(".") ? "" : "."
124
- ]
125
- },
126
- `${warning.provider ?? "alert"}:${warning.message}`
127
- ))
128
- ] });
129
94
  function datadogSignalFrom(data) {
130
95
  const root = recordFrom(data);
131
96
  const alerts = recordFrom(root.alerts);
132
97
  const alertNoise = recordFrom(root.alertNoise);
133
98
  const counts = recordFrom(alertNoise.counts);
134
99
  const alertCause = recordFrom(root.alertCause);
135
- const providers = providerCoverageFrom(alerts.providers);
136
- const warnings = warningsFrom(alerts.warnings);
137
- const activeHasMore = recordFrom(alerts.page).hasMore === true;
138
- const alertEvidenceIncomplete = alerts.partial === true || activeHasMore || providers.some((provider) => provider.status !== "available") || warnings.length > 0;
139
- const firingMonitors = uniqueMonitors(
140
- recordsFrom(alerts.items).filter(
141
- (record) => textFrom(record, "status") === "firing"
142
- ),
143
- "alert"
144
- );
100
+ const firingMonitors = uniqueMonitors(recordsFrom(alerts.firing), "firing");
145
101
  const noisyMonitors = uniqueMonitors(
146
102
  recordsFrom(alertNoise.monitors),
147
103
  "noise"
148
104
  );
149
- const active = firingMonitors.length;
105
+ const active = numberFrom(alerts.total) ?? firingMonitors.length;
150
106
  const fires = numberFrom(counts.totalFires) ?? noisyMonitors.reduce((total, monitor) => total + (monitor.fires ?? 0), 0);
151
107
  const recovers = noisyMonitors.reduce(
152
108
  (total, monitor) => total + (monitor.recovers ?? 0),
@@ -157,9 +113,8 @@ function datadogSignalFrom(data) {
157
113
  const hasEvidence = isRecord(root.alerts) || isRecord(root.alertNoise);
158
114
  const changes = Array.isArray(alertCause.changes) ? alertCause.changes.length : void 0;
159
115
  return {
160
- state: !hasEvidence ? "unavailable" : active > 0 ? "firing" : alertEvidenceIncomplete ? "unavailable" : fires > 0 || flapping > 0 || stuck > 0 ? "noisy" : "quiet",
116
+ state: !hasEvidence ? "unavailable" : active > 0 ? "firing" : fires > 0 || flapping > 0 || stuck > 0 ? "noisy" : "quiet",
161
117
  active,
162
- activeHasMore,
163
118
  fires,
164
119
  recovers,
165
120
  flapping,
@@ -167,44 +122,27 @@ function datadogSignalFrom(data) {
167
122
  firingMonitors,
168
123
  noisyMonitors,
169
124
  ...changes !== void 0 ? { correlatedChanges: changes } : {},
170
- partial: Array.isArray(root.errors) && root.errors.length > 0 || alertEvidenceIncomplete,
171
- providers,
172
- warnings
125
+ partial: Array.isArray(root.errors) && root.errors.length > 0
173
126
  };
174
127
  }
175
- function providerCoverageFrom(value) {
176
- return recordsFrom(value).flatMap((provider) => {
177
- const name = textFrom(provider, "provider");
178
- const status = textFrom(provider, "status");
179
- return name && status ? [{ provider: name, status }] : [];
180
- });
181
- }
182
- function warningsFrom(value) {
183
- return recordsFrom(value).flatMap((warning) => {
184
- const message = textFrom(warning, "message");
185
- const provider = textFrom(warning, "provider");
186
- return message ? [{ message, ...provider ? { provider } : {} }] : [];
187
- });
188
- }
189
- function readableProvider(provider) {
190
- return provider.charAt(0).toUpperCase() + provider.slice(1);
191
- }
192
128
  function uniqueMonitors(records, source) {
193
129
  const unique = /* @__PURE__ */ new Map();
194
130
  records.forEach((record) => {
195
- const name = textFrom(record, source === "alert" ? "title" : "name");
131
+ const name = textFrom(record, source === "firing" ? "monitor" : "name");
196
132
  if (!name) return;
197
- const service = recordFrom(record.service);
198
133
  const monitor = {
199
- key: source === "alert" ? textFrom(record, "id") ?? name.toLowerCase() : [name, textFrom(record, "noiseKind")].filter(Boolean).join("|").toLowerCase(),
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(),
200
141
  name,
201
- state: source === "alert" ? textFrom(record, "providerStatus") ?? textFrom(record, "status") : textFrom(record, "state"),
202
- provider: source === "alert" ? textFrom(record, "provider") : void 0,
203
- severity: source === "alert" ? textFrom(record, "severity") : void 0,
204
- providerStatus: source === "alert" ? textFrom(record, "providerStatus") : void 0,
205
- service: source === "alert" ? textFrom(service, "name") : textFrom(record, "service"),
206
- workload: source === "alert" ? textFrom(service, "name") : textFrom(record, "workload"),
207
- namespace: source === "alert" ? textFrom(service, "namespace") : textFrom(record, "namespace"),
142
+ state: textFrom(record, "state"),
143
+ service: textFrom(record, "service"),
144
+ workload: textFrom(record, "workload"),
145
+ namespace: textFrom(record, "namespace"),
208
146
  fires: numberFrom(record.fires),
209
147
  recovers: numberFrom(record.recovers),
210
148
  noiseKind: textFrom(record, "noiseKind")
@@ -216,7 +154,7 @@ function uniqueMonitors(records, source) {
216
154
  function compactSummary(signal) {
217
155
  if (signal.state === "firing") {
218
156
  const summary = [
219
- `${signal.activeHasMore ? "At least " : ""}${signal.active} ${signal.active === 1 ? "alert" : "alerts"}`
157
+ `${signal.active} ${signal.active === 1 ? "monitor" : "monitors"}`
220
158
  ];
221
159
  if (signal.correlatedChanges) {
222
160
  summary.push(
@@ -229,7 +167,7 @@ function compactSummary(signal) {
229
167
  return `${signal.fires} fire \xB7 ${signal.flapping} flapping`;
230
168
  }
231
169
  if (signal.state === "quiet") return "No recent paging noise";
232
- return signal.partial ? "Operational alert evidence incomplete" : "No operational alert evidence returned";
170
+ return "No Datadog signal evidence returned";
233
171
  }
234
172
  function recordFrom(value) {
235
173
  return isRecord(value) ? value : {};