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

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 (32) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +14 -1
  3. package/dist/api/AnyshiftApi.esm.js +59 -7
  4. package/dist/api/AnyshiftApi.esm.js.map +1 -1
  5. package/dist/components/ask/AskAnyshiftCard.esm.js +342 -0
  6. package/dist/components/ask/AskAnyshiftCard.esm.js.map +1 -0
  7. package/dist/components/ask/askPresenters.esm.js +1174 -0
  8. package/dist/components/ask/askPresenters.esm.js.map +1 -0
  9. package/dist/components/ask/askScope.esm.js +24 -0
  10. package/dist/components/ask/askScope.esm.js.map +1 -0
  11. package/dist/components/ask/askSuggestions.esm.js +41 -0
  12. package/dist/components/ask/askSuggestions.esm.js.map +1 -0
  13. package/dist/components/cloud/CloudPage.esm.js +104 -0
  14. package/dist/components/cloud/CloudPage.esm.js.map +1 -0
  15. package/dist/components/cloud/CloudResourceContent.esm.js +358 -0
  16. package/dist/components/cloud/CloudResourceContent.esm.js.map +1 -0
  17. package/dist/components/entity/AnyshiftEntityContent.esm.js +64 -8
  18. package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -1
  19. package/dist/components/entity/BriefSections.esm.js +24 -4
  20. package/dist/components/entity/BriefSections.esm.js.map +1 -1
  21. package/dist/components/entity/SectionPresenters.esm.js +136 -46
  22. package/dist/components/entity/SectionPresenters.esm.js.map +1 -1
  23. package/dist/components/explorer/AnyshiftExplorerPage.esm.js +277 -29
  24. package/dist/components/explorer/AnyshiftExplorerPage.esm.js.map +1 -1
  25. package/dist/index.d.ts +109 -7
  26. package/dist/index.esm.js +1 -1
  27. package/dist/package.json.esm.js +1 -1
  28. package/dist/plugin.esm.js +47 -8
  29. package/dist/plugin.esm.js.map +1 -1
  30. package/dist/routes.esm.js +2 -1
  31. package/dist/routes.esm.js.map +1 -1
  32. package/package.json +2 -2
@@ -1,16 +1,18 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { useState, useEffect } from 'react';
3
- import { Typography, TextField, Grid, Button } from '@material-ui/core';
2
+ import { useState, useEffect, useCallback } from 'react';
3
+ import { Typography, Grid, Button, TextField, Box, Chip } from '@material-ui/core';
4
4
  import { Page, Header, Content, Progress, ContentHeader, InfoCard } from '@backstage/core-components';
5
5
  import { useApi } from '@backstage/frontend-plugin-api';
6
6
  import { usePermission } from '@backstage/plugin-permission-react';
7
- import { anyshiftQueryPermission } from '@anyshift/backstage-plugin-anyshift-common';
7
+ import { anyshiftQueryPermission, anyshiftCatalogSyncPermission, ANYSHIFT_CATALOG_SYNC_ERROR_ANNOTATION, ANYSHIFT_CATALOG_SYNC_FINISHED_AT_ANNOTATION, ANYSHIFT_CATALOG_SYNC_TRIGGER_ANNOTATION, ANYSHIFT_CATALOG_SYNC_STATUS_ANNOTATION } from '@anyshift/backstage-plugin-anyshift-common';
8
8
  import { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react';
9
9
  import { anyshiftApiRef } from '../../api/AnyshiftApi.esm.js';
10
+ import { AskAnyshiftCard } from '../ask/AskAnyshiftCard.esm.js';
10
11
  import { TimelinePresenter, ImpactPresenter } from '../entity/SectionPresenters.esm.js';
11
12
  import { DatadogOperationsRadar } from './DatadogOperationsRadar.esm.js';
12
13
 
13
14
  const DEFAULT_QUERY = "SELECT * FROM resources WHERE type = deployment LIMIT 10";
15
+ const CATALOG_SYNC_STATUS_ENTITY = "anyshift-catalog-sync";
14
16
  function isDeterministicSelect(value) {
15
17
  const sql = value.trim();
16
18
  return /^SELECT\b/i.test(sql) && sql.length <= 4096 && !sql.includes(";") && !sql.includes("--") && !sql.includes("/*");
@@ -27,24 +29,179 @@ function matchesCatalogEntity(entity, value) {
27
29
  ];
28
30
  return searchable.some((item) => item?.toLocaleLowerCase().includes(query));
29
31
  }
32
+ function summarizeCatalogSync(entities) {
33
+ const components = entities.filter(
34
+ (entity) => entity.kind.toLowerCase() === "component"
35
+ );
36
+ const configured = components.filter(
37
+ (entity) => entity.metadata.annotations?.["anyshift.io/target"]
38
+ );
39
+ const excluded = components.filter(
40
+ (entity) => entity.metadata.annotations?.["anyshift.io/catalog-sync"]?.toLowerCase() === "excluded"
41
+ );
42
+ return {
43
+ components: components.length,
44
+ configured: configured.length,
45
+ excluded: excluded.length,
46
+ unclassified: Math.max(
47
+ 0,
48
+ components.length - configured.length - excluded.length
49
+ ),
50
+ observed: configured.filter(
51
+ (entity) => entity.metadata.annotations?.["anyshift.io/observed-service"]
52
+ ).length,
53
+ managedResources: entities.filter(
54
+ (entity) => entity.kind.toLowerCase() === "resource" && entity.metadata.name !== CATALOG_SYNC_STATUS_ENTITY && entity.metadata.annotations?.["anyshift.io/managed-by"] === "catalog-provider"
55
+ ).length
56
+ };
57
+ }
58
+ function catalogSyncStatus(entities) {
59
+ const entity = entities.find(
60
+ (candidate) => candidate.kind.toLowerCase() === "resource" && candidate.metadata.name === CATALOG_SYNC_STATUS_ENTITY
61
+ );
62
+ const annotations = entity?.metadata.annotations ?? {};
63
+ return {
64
+ status: annotations[ANYSHIFT_CATALOG_SYNC_STATUS_ANNOTATION] ?? "waiting",
65
+ trigger: annotations[ANYSHIFT_CATALOG_SYNC_TRIGGER_ANNOTATION],
66
+ finishedAt: annotations[ANYSHIFT_CATALOG_SYNC_FINISHED_AT_ANNOTATION],
67
+ error: annotations[ANYSHIFT_CATALOG_SYNC_ERROR_ANNOTATION]
68
+ };
69
+ }
30
70
  const EstateInsightsGrid = ({
31
- insights
32
- }) => /* @__PURE__ */ jsx(Fragment, { children: insights.sections.map((item) => /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsx(InfoCard, { title: item.title, children: item.section.state === "error" ? /* @__PURE__ */ jsx(Typography, { color: "error", children: item.section.message }) : item.section.state === "empty" || item.section.state === "unsupported" || item.section.data === void 0 ? /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: item.section.message || "No insight evidence is available." }) : item.id === "recent-change" ? /* @__PURE__ */ jsx(
33
- TimelinePresenter,
34
- {
35
- data: item.section.data,
36
- fallbackLabel: "Deployment"
37
- }
38
- ) : /* @__PURE__ */ jsx(ImpactPresenter, { data: item.section.data }) }) }, item.id)) });
71
+ insights,
72
+ onRetryCoverage,
73
+ refreshingCoverage = false
74
+ }) => {
75
+ const coverage = insights.coverage ?? {
76
+ state: "unsupported",
77
+ message: "Evidence coverage is not available from this backend version."
78
+ };
79
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
80
+ /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(
81
+ InfoCard,
82
+ {
83
+ title: "Evidence coverage",
84
+ subheader: "Observed graph sources and observability blind spots",
85
+ children: coverage.state === "data" && coverage.data ? /* @__PURE__ */ jsxs(Fragment, { children: [
86
+ /* @__PURE__ */ jsx(EvidenceCoveragePresenter, { data: coverage.data }),
87
+ coverage.retryable && onRetryCoverage && /* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(
88
+ Button,
89
+ {
90
+ variant: "outlined",
91
+ size: "small",
92
+ onClick: onRetryCoverage,
93
+ disabled: refreshingCoverage,
94
+ children: refreshingCoverage ? "Retrying\u2026" : "Retry evidence coverage"
95
+ }
96
+ ) })
97
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
98
+ /* @__PURE__ */ jsx(
99
+ Typography,
100
+ {
101
+ color: coverage.state === "error" ? "error" : "textSecondary",
102
+ children: coverage.message || "No coverage evidence is available."
103
+ }
104
+ ),
105
+ coverage.retryable && onRetryCoverage && /* @__PURE__ */ jsx(Box, { mt: 2, children: /* @__PURE__ */ jsx(
106
+ Button,
107
+ {
108
+ variant: "outlined",
109
+ size: "small",
110
+ onClick: onRetryCoverage,
111
+ disabled: refreshingCoverage,
112
+ children: refreshingCoverage ? "Retrying\u2026" : "Retry evidence coverage"
113
+ }
114
+ ) })
115
+ ] })
116
+ }
117
+ ) }),
118
+ insights.sections.map((item) => /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, md: 6, children: /* @__PURE__ */ jsx(InfoCard, { title: item.title, children: item.section.state === "error" ? /* @__PURE__ */ jsx(Typography, { color: "error", children: item.section.message }) : item.section.state === "empty" || item.section.state === "unsupported" || item.section.data === void 0 ? /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: item.section.message || "No insight evidence is available." }) : item.id === "recent-change" ? /* @__PURE__ */ jsx(
119
+ TimelinePresenter,
120
+ {
121
+ data: item.section.data,
122
+ fallbackLabel: "Deployment"
123
+ }
124
+ ) : /* @__PURE__ */ jsx(ImpactPresenter, { data: item.section.data }) }) }, item.id))
125
+ ] });
126
+ };
127
+ const EvidenceCoveragePresenter = ({
128
+ data
129
+ }) => {
130
+ const metrics = [
131
+ [data.graph.nodes, "Graph nodes"],
132
+ [data.graph.relationships, "Relationships"],
133
+ [data.graph.bridges, "Cross-source bridges"],
134
+ [data.graph.events, "Runtime events"]
135
+ ];
136
+ const refreshedAt = Date.parse(data.refreshedAt);
137
+ const stale = Number.isFinite(refreshedAt) && Date.now() - refreshedAt > 15 * 60 * 1e3;
138
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
139
+ /* @__PURE__ */ jsxs(
140
+ Box,
141
+ {
142
+ display: "flex",
143
+ flexWrap: "wrap",
144
+ alignItems: "center",
145
+ gridGap: 8,
146
+ mb: 2,
147
+ children: [
148
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: data.connectedSources === null ? `Unknown of ${data.expectedSources} sources` : `${data.connectedSources} of ${data.expectedSources} sources` }),
149
+ /* @__PURE__ */ jsx(
150
+ Chip,
151
+ {
152
+ size: "small",
153
+ color: stale ? "secondary" : "primary",
154
+ label: stale ? "Stale evidence" : "Fresh evidence"
155
+ }
156
+ )
157
+ ]
158
+ }
159
+ ),
160
+ /* @__PURE__ */ jsx(Grid, { container: true, spacing: 2, children: metrics.map(([value, label]) => /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 3, children: [
161
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", children: value === null ? "N/A" : value.toLocaleString() }),
162
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", children: label })
163
+ ] }, label)) }),
164
+ /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, children: [
165
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 12, md: 6, children: [
166
+ /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "textSecondary", children: "Missing source evidence" }),
167
+ data.missingSources.length > 0 ? /* @__PURE__ */ jsx(Box, { display: "flex", flexWrap: "wrap", gridGap: 6, children: data.missingSources.map((source) => /* @__PURE__ */ jsx(
168
+ Chip,
169
+ {
170
+ size: "small",
171
+ variant: "outlined",
172
+ label: source
173
+ },
174
+ source
175
+ )) }) : /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "textSecondary", children: "None reported by the Graph API." })
176
+ ] }),
177
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 12, md: 6, children: [
178
+ /* @__PURE__ */ jsx(Typography, { variant: "overline", color: "textSecondary", children: "Observability blind spots" }),
179
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: data.blindSpots.workloadCount === null ? "Workload coverage unavailable" : `${data.blindSpots.workloadCount} workloads` }),
180
+ data.blindSpots.workloads.map((workload) => /* @__PURE__ */ jsxs(Box, { children: [
181
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: workload.name }),
182
+ workload.namespace && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", children: workload.namespace })
183
+ ] }, `${workload.namespace}/${workload.name}`))
184
+ ] })
185
+ ] }),
186
+ /* @__PURE__ */ jsx(Box, { mt: 2, children: data.warnings.map((warning) => /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "textSecondary", children: warning }, warning)) })
187
+ ] });
188
+ };
39
189
  const AnyshiftExplorerPage = () => {
40
190
  const api = useApi(anyshiftApiRef);
41
191
  const catalogApi = useApi(catalogApiRef);
42
192
  const queryPermission = usePermission({
43
193
  permission: anyshiftQueryPermission
44
194
  });
45
- const [queryEnabled, setQueryEnabled] = useState(false);
195
+ const catalogSyncPermission = usePermission({
196
+ permission: anyshiftCatalogSyncPermission
197
+ });
198
+ const [capabilities, setCapabilities] = useState({
199
+ askEnabled: false,
200
+ queryEnabled: false
201
+ });
46
202
  const [insights, setInsights] = useState();
47
203
  const [insightError, setInsightError] = useState();
204
+ const [refreshingInsights, setRefreshingInsights] = useState(false);
48
205
  const [datadogSignals, setDatadogSignals] = useState();
49
206
  const [datadogError, setDatadogError] = useState();
50
207
  const [refreshingDatadog, setRefreshingDatadog] = useState(false);
@@ -54,33 +211,47 @@ const AnyshiftExplorerPage = () => {
54
211
  const [sql, setSql] = useState(DEFAULT_QUERY);
55
212
  const [queryResult, setQueryResult] = useState();
56
213
  const [queryError, setQueryError] = useState();
214
+ const [requestingSync, setRequestingSync] = useState(false);
215
+ const [syncRequestMessage, setSyncRequestMessage] = useState();
216
+ const [syncRequestError, setSyncRequestError] = useState();
57
217
  useEffect(() => {
58
- api.capabilities().then((capabilities) => setQueryEnabled(capabilities.queryEnabled)).catch(() => setQueryEnabled(false));
218
+ api.capabilities().then(setCapabilities).catch(() => setCapabilities({ askEnabled: false, queryEnabled: false }));
59
219
  }, [api]);
60
220
  useEffect(() => {
61
221
  api.datadogSignals().then(setDatadogSignals).catch((error) => {
62
222
  setDatadogError(error instanceof Error ? error.message : String(error));
63
223
  });
64
224
  }, [api]);
225
+ const loadInsights = useCallback(
226
+ async (refresh = false) => {
227
+ if (refresh) setRefreshingInsights(true);
228
+ setInsightError(void 0);
229
+ try {
230
+ setInsights(await api.insights({ refresh }));
231
+ } catch (error) {
232
+ setInsightError(error instanceof Error ? error.message : String(error));
233
+ } finally {
234
+ if (refresh) setRefreshingInsights(false);
235
+ }
236
+ },
237
+ [api]
238
+ );
65
239
  useEffect(() => {
66
- api.insights().then(setInsights).catch((error) => {
67
- setInsightError(error instanceof Error ? error.message : String(error));
68
- });
69
- }, [api]);
240
+ void loadInsights();
241
+ }, [loadInsights]);
70
242
  useEffect(() => {
71
243
  catalogApi.getEntities({
72
244
  filter: [{ kind: "Component" }, { kind: "Resource" }]
73
- }).then(
74
- (response) => setCatalogEntities(
75
- response.items.filter(
76
- (entity) => entity.metadata.annotations?.["anyshift.io/target"]
77
- )
78
- )
79
- ).catch((error) => {
245
+ }).then((response) => setCatalogEntities(response.items)).catch((error) => {
80
246
  setCatalogError(error instanceof Error ? error.message : String(error));
81
247
  });
82
248
  }, [catalogApi]);
83
- const matchingEntities = catalogEntities.filter((entity) => matchesCatalogEntity(entity, catalogQuery)).slice(0, 12);
249
+ const anyshiftEntities = catalogEntities.filter(
250
+ (entity) => entity.metadata.annotations?.["anyshift.io/target"]
251
+ );
252
+ const syncSummary = summarizeCatalogSync(catalogEntities);
253
+ const syncStatus = catalogSyncStatus(catalogEntities);
254
+ const matchingEntities = anyshiftEntities.filter((entity) => matchesCatalogEntity(entity, catalogQuery)).slice(0, 12);
84
255
  const runQuery = async () => {
85
256
  if (!isDeterministicSelect(sql)) {
86
257
  setQueryError("Enter one deterministic SELECT query.");
@@ -104,6 +275,23 @@ const AnyshiftExplorerPage = () => {
104
275
  setRefreshingDatadog(false);
105
276
  }
106
277
  };
278
+ const requestCatalogSync = async () => {
279
+ setRequestingSync(true);
280
+ setSyncRequestError(void 0);
281
+ setSyncRequestMessage(void 0);
282
+ try {
283
+ const accepted = await api.reconcileCatalog();
284
+ setSyncRequestMessage(
285
+ `Reconciliation accepted ${formatTimestamp(accepted.acceptedAt)}.`
286
+ );
287
+ } catch (error) {
288
+ setSyncRequestError(
289
+ error instanceof Error ? error.message : String(error)
290
+ );
291
+ } finally {
292
+ setRequestingSync(false);
293
+ }
294
+ };
107
295
  return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
108
296
  /* @__PURE__ */ jsx(
109
297
  Header,
@@ -117,12 +305,60 @@ const AnyshiftExplorerPage = () => {
117
305
  DatadogOperationsRadar,
118
306
  {
119
307
  signals: datadogSignals,
120
- catalogEntities,
308
+ catalogEntities: anyshiftEntities,
121
309
  onRefresh: refreshDatadog,
122
310
  refreshing: refreshingDatadog,
123
311
  error: datadogError
124
312
  }
125
313
  ) : datadogError ? /* @__PURE__ */ jsx(Typography, { color: "error", children: datadogError }) : /* @__PURE__ */ jsx(Progress, {}),
314
+ /* @__PURE__ */ jsx(ContentHeader, { title: "Catalog synchronization" }),
315
+ /* @__PURE__ */ jsx(InfoCard, { subheader: "GitHub ownership stays authoritative; Anyshift adds observed infrastructure context", children: /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 2, children: [
316
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 2, children: [
317
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: syncSummary.configured }),
318
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "Configured" })
319
+ ] }),
320
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 2, children: [
321
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: syncSummary.excluded }),
322
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "Excluded" })
323
+ ] }),
324
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 2, children: [
325
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: syncSummary.unclassified }),
326
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "Unclassified" })
327
+ ] }),
328
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 2, children: [
329
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: syncSummary.observed }),
330
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "Active matches" })
331
+ ] }),
332
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 6, md: 2, children: [
333
+ /* @__PURE__ */ jsx(Typography, { variant: "h5", children: syncSummary.managedResources }),
334
+ /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: "Managed resources" })
335
+ ] }),
336
+ /* @__PURE__ */ jsxs(Grid, { item: true, xs: 12, children: [
337
+ /* @__PURE__ */ jsxs(Typography, { children: [
338
+ "Last reconciliation: ",
339
+ /* @__PURE__ */ jsx("strong", { children: syncStatus.status }),
340
+ syncStatus.finishedAt ? ` \xB7 ${formatTimestamp(syncStatus.finishedAt)}` : "",
341
+ syncStatus.trigger ? ` \xB7 ${syncStatus.trigger}` : ""
342
+ ] }),
343
+ syncStatus.error && /* @__PURE__ */ jsxs(Typography, { color: "error", children: [
344
+ "Last failure: ",
345
+ syncStatus.error
346
+ ] }),
347
+ catalogSyncPermission.allowed && /* @__PURE__ */ jsx(
348
+ Button,
349
+ {
350
+ variant: "outlined",
351
+ color: "primary",
352
+ disabled: requestingSync,
353
+ onClick: requestCatalogSync,
354
+ style: { marginTop: 12 },
355
+ children: requestingSync ? "Requesting\u2026" : "Reconcile now"
356
+ }
357
+ ),
358
+ syncRequestMessage && /* @__PURE__ */ jsx(Typography, { color: "textSecondary", children: syncRequestMessage }),
359
+ syncRequestError && /* @__PURE__ */ jsx(Typography, { color: "error", children: syncRequestError })
360
+ ] })
361
+ ] }) }),
126
362
  /* @__PURE__ */ jsx(ContentHeader, { title: "Find a service" }),
127
363
  /* @__PURE__ */ jsxs(InfoCard, { subheader: "Anyshift-annotated Components and Resources in the Backstage catalog", children: [
128
364
  /* @__PURE__ */ jsx(
@@ -151,8 +387,16 @@ const AnyshiftExplorerPage = () => {
151
387
  insightError && /* @__PURE__ */ jsx(Typography, { color: "error", children: insightError }),
152
388
  !insights && !insightError ? /* @__PURE__ */ jsx(Progress, {}) : null,
153
389
  /* @__PURE__ */ jsxs(Grid, { container: true, spacing: 3, children: [
154
- insights && /* @__PURE__ */ jsx(EstateInsightsGrid, { insights }),
155
- queryEnabled && queryPermission.allowed && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(
390
+ insights && /* @__PURE__ */ jsx(
391
+ EstateInsightsGrid,
392
+ {
393
+ insights,
394
+ onRetryCoverage: () => void loadInsights(true),
395
+ refreshingCoverage: refreshingInsights
396
+ }
397
+ ),
398
+ capabilities.askEnabled && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsx(AskAnyshiftCard, { context: "estate" }) }),
399
+ capabilities.queryEnabled && queryPermission.allowed && /* @__PURE__ */ jsx(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs(
156
400
  InfoCard,
157
401
  {
158
402
  title: "Advanced query",
@@ -188,6 +432,10 @@ const AnyshiftExplorerPage = () => {
188
432
  ] })
189
433
  ] });
190
434
  };
435
+ function formatTimestamp(value) {
436
+ const parsed = Date.parse(value);
437
+ return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();
438
+ }
191
439
 
192
- export { AnyshiftExplorerPage, EstateInsightsGrid, isDeterministicSelect, matchesCatalogEntity };
440
+ export { AnyshiftExplorerPage, EstateInsightsGrid, EvidenceCoveragePresenter, catalogSyncStatus, isDeterministicSelect, matchesCatalogEntity, summarizeCatalogSync };
193
441
  //# sourceMappingURL=AnyshiftExplorerPage.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnyshiftExplorerPage.esm.js","sources":["../../../src/components/explorer/AnyshiftExplorerPage.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Button, Grid, TextField, Typography } from '@material-ui/core';\nimport {\n Content,\n ContentHeader,\n Header,\n InfoCard,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport { anyshiftQueryPermission } from '@anyshift/backstage-plugin-anyshift-common';\nimport type { Entity } from '@backstage/catalog-model';\nimport { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type {\n DatadogSignals,\n EstateInsights,\n QueryResult,\n} from '../../api/types';\nimport {\n ImpactPresenter,\n TimelinePresenter,\n} from '../entity/SectionPresenters';\nimport { DatadogOperationsRadar } from './DatadogOperationsRadar';\n\nconst DEFAULT_QUERY =\n 'SELECT * FROM resources WHERE type = deployment LIMIT 10';\n\nexport function isDeterministicSelect(value: string): boolean {\n const sql = value.trim();\n return (\n /^SELECT\\b/i.test(sql) &&\n sql.length <= 4_096 &&\n !sql.includes(';') &&\n !sql.includes('--') &&\n !sql.includes('/*')\n );\n}\n\nexport function matchesCatalogEntity(entity: Entity, value: string): boolean {\n const query = value.trim().toLocaleLowerCase();\n if (!query) return true;\n const searchable = [\n entity.metadata.name,\n entity.metadata.title,\n entity.metadata.description,\n entity.metadata.annotations?.['anyshift.io/target'],\n typeof entity.spec?.owner === 'string' ? entity.spec.owner : undefined,\n ];\n return searchable.some(item => item?.toLocaleLowerCase().includes(query));\n}\n\nexport const EstateInsightsGrid = ({\n insights,\n}: {\n insights: EstateInsights;\n}) => (\n <>\n {insights.sections.map(item => (\n <Grid item xs={12} md={6} key={item.id}>\n <InfoCard title={item.title}>\n {item.section.state === 'error' ? (\n <Typography color=\"error\">{item.section.message}</Typography>\n ) : item.section.state === 'empty' ||\n item.section.state === 'unsupported' ||\n item.section.data === undefined ? (\n <Typography color=\"textSecondary\">\n {item.section.message || 'No insight evidence is available.'}\n </Typography>\n ) : item.id === 'recent-change' ? (\n <TimelinePresenter\n data={item.section.data}\n fallbackLabel=\"Deployment\"\n />\n ) : (\n <ImpactPresenter data={item.section.data} />\n )}\n </InfoCard>\n </Grid>\n ))}\n </>\n);\n\nexport const AnyshiftExplorerPage = () => {\n const api = useApi(anyshiftApiRef);\n const catalogApi = useApi(catalogApiRef);\n const queryPermission = usePermission({\n permission: anyshiftQueryPermission,\n });\n const [queryEnabled, setQueryEnabled] = useState(false);\n const [insights, setInsights] = useState<EstateInsights>();\n const [insightError, setInsightError] = useState<string>();\n const [datadogSignals, setDatadogSignals] = useState<DatadogSignals>();\n const [datadogError, setDatadogError] = useState<string>();\n const [refreshingDatadog, setRefreshingDatadog] = useState(false);\n const [catalogEntities, setCatalogEntities] = useState<Entity[]>([]);\n const [catalogError, setCatalogError] = useState<string>();\n const [catalogQuery, setCatalogQuery] = useState('');\n const [sql, setSql] = useState(DEFAULT_QUERY);\n const [queryResult, setQueryResult] = useState<QueryResult>();\n const [queryError, setQueryError] = useState<string>();\n\n useEffect(() => {\n api\n .capabilities()\n .then(capabilities => setQueryEnabled(capabilities.queryEnabled))\n .catch(() => setQueryEnabled(false));\n }, [api]);\n\n useEffect(() => {\n api\n .datadogSignals()\n .then(setDatadogSignals)\n .catch(error => {\n setDatadogError(error instanceof Error ? error.message : String(error));\n });\n }, [api]);\n\n useEffect(() => {\n api\n .insights()\n .then(setInsights)\n .catch(error => {\n setInsightError(error instanceof Error ? error.message : String(error));\n });\n }, [api]);\n\n useEffect(() => {\n catalogApi\n .getEntities({\n filter: [{ kind: 'Component' }, { kind: 'Resource' }],\n })\n .then(response =>\n setCatalogEntities(\n response.items.filter(\n entity => entity.metadata.annotations?.['anyshift.io/target'],\n ),\n ),\n )\n .catch(error => {\n setCatalogError(error instanceof Error ? error.message : String(error));\n });\n }, [catalogApi]);\n\n const matchingEntities = catalogEntities\n .filter(entity => matchesCatalogEntity(entity, catalogQuery))\n .slice(0, 12);\n\n const runQuery = async () => {\n if (!isDeterministicSelect(sql)) {\n setQueryError('Enter one deterministic SELECT query.');\n return;\n }\n setQueryError(undefined);\n try {\n setQueryResult(await api.query(sql.trim()));\n } catch (error) {\n setQueryError(error instanceof Error ? error.message : String(error));\n }\n };\n\n const refreshDatadog = async () => {\n setRefreshingDatadog(true);\n setDatadogError(undefined);\n try {\n setDatadogSignals(await api.datadogSignals({ refresh: true }));\n } catch (error) {\n setDatadogError(error instanceof Error ? error.message : String(error));\n } finally {\n setRefreshingDatadog(false);\n }\n };\n\n return (\n <Page themeId=\"tool\">\n <Header\n title=\"Anyshift\"\n subtitle=\"Live infrastructure context for your software catalog\"\n />\n <Content>\n {datadogSignals ? (\n <DatadogOperationsRadar\n signals={datadogSignals}\n catalogEntities={catalogEntities}\n onRefresh={refreshDatadog}\n refreshing={refreshingDatadog}\n error={datadogError}\n />\n ) : datadogError ? (\n <Typography color=\"error\">{datadogError}</Typography>\n ) : (\n <Progress />\n )}\n <ContentHeader title=\"Find a service\" />\n <InfoCard subheader=\"Anyshift-annotated Components and Resources in the Backstage catalog\">\n <TextField\n fullWidth\n variant=\"outlined\"\n label=\"Search services and resources\"\n value={catalogQuery}\n onChange={event => setCatalogQuery(event.target.value)}\n />\n {catalogError && (\n <Typography color=\"error\">{catalogError}</Typography>\n )}\n {!catalogError && matchingEntities.length === 0 ? (\n <Typography color=\"textSecondary\" style={{ marginTop: 12 }}>\n No matching Anyshift catalog entities.\n </Typography>\n ) : (\n <ul>\n {matchingEntities.map(entity => (\n <li\n key={`${entity.kind}:${\n entity.metadata.namespace ?? 'default'\n }/${entity.metadata.name}`}\n >\n <EntityRefLink entityRef={entity} />\n {entity.metadata.description\n ? ` - ${entity.metadata.description}`\n : null}\n </li>\n ))}\n </ul>\n )}\n </InfoCard>\n <ContentHeader title=\"Estate insights\" />\n {insightError && <Typography color=\"error\">{insightError}</Typography>}\n {!insights && !insightError ? <Progress /> : null}\n <Grid container spacing={3}>\n {insights && <EstateInsightsGrid insights={insights} />}\n {queryEnabled && queryPermission.allowed && (\n <Grid item xs={12}>\n <InfoCard\n title=\"Advanced query\"\n subheader=\"Deterministic Graph API SELECT queries only\"\n >\n <TextField\n fullWidth\n multiline\n minRows={2}\n variant=\"outlined\"\n value={sql}\n onChange={event => setSql(event.target.value)}\n />\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={runQuery}\n style={{ marginTop: 12 }}\n >\n Run query\n </Button>\n {queryError && (\n <Typography color=\"error\">{queryError}</Typography>\n )}\n {queryResult && (\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: 12 }}>\n {JSON.stringify(queryResult, null, 2)}\n </pre>\n )}\n </InfoCard>\n </Grid>\n )}\n </Grid>\n </Content>\n </Page>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AnyshiftExplorerPage.esm.js","sources":["../../../src/components/explorer/AnyshiftExplorerPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n Grid,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport {\n Content,\n ContentHeader,\n Header,\n InfoCard,\n Page,\n Progress,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport { usePermission } from '@backstage/plugin-permission-react';\nimport {\n ANYSHIFT_CATALOG_SYNC_ERROR_ANNOTATION,\n ANYSHIFT_CATALOG_SYNC_FINISHED_AT_ANNOTATION,\n ANYSHIFT_CATALOG_SYNC_STATUS_ANNOTATION,\n ANYSHIFT_CATALOG_SYNC_TRIGGER_ANNOTATION,\n anyshiftCatalogSyncPermission,\n anyshiftQueryPermission,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport type { Entity } from '@backstage/catalog-model';\nimport { catalogApiRef, EntityRefLink } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type {\n AnyshiftCapabilities,\n DatadogSignals,\n EvidenceCoverage,\n EstateInsights,\n QueryResult,\n} from '../../api/types';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport {\n ImpactPresenter,\n TimelinePresenter,\n} from '../entity/SectionPresenters';\nimport { DatadogOperationsRadar } from './DatadogOperationsRadar';\n\nconst DEFAULT_QUERY =\n 'SELECT * FROM resources WHERE type = deployment LIMIT 10';\nconst CATALOG_SYNC_STATUS_ENTITY = 'anyshift-catalog-sync';\n\nexport function isDeterministicSelect(value: string): boolean {\n const sql = value.trim();\n return (\n /^SELECT\\b/i.test(sql) &&\n sql.length <= 4_096 &&\n !sql.includes(';') &&\n !sql.includes('--') &&\n !sql.includes('/*')\n );\n}\n\nexport function matchesCatalogEntity(entity: Entity, value: string): boolean {\n const query = value.trim().toLocaleLowerCase();\n if (!query) return true;\n const searchable = [\n entity.metadata.name,\n entity.metadata.title,\n entity.metadata.description,\n entity.metadata.annotations?.['anyshift.io/target'],\n typeof entity.spec?.owner === 'string' ? entity.spec.owner : undefined,\n ];\n return searchable.some(item => item?.toLocaleLowerCase().includes(query));\n}\n\nexport function summarizeCatalogSync(entities: Entity[]) {\n const components = entities.filter(\n entity => entity.kind.toLowerCase() === 'component',\n );\n const configured = components.filter(\n entity => entity.metadata.annotations?.['anyshift.io/target'],\n );\n const excluded = components.filter(\n entity =>\n entity.metadata.annotations?.[\n 'anyshift.io/catalog-sync'\n ]?.toLowerCase() === 'excluded',\n );\n return {\n components: components.length,\n configured: configured.length,\n excluded: excluded.length,\n unclassified: Math.max(\n 0,\n components.length - configured.length - excluded.length,\n ),\n observed: configured.filter(\n entity => entity.metadata.annotations?.['anyshift.io/observed-service'],\n ).length,\n managedResources: entities.filter(\n entity =>\n entity.kind.toLowerCase() === 'resource' &&\n entity.metadata.name !== CATALOG_SYNC_STATUS_ENTITY &&\n entity.metadata.annotations?.['anyshift.io/managed-by'] ===\n 'catalog-provider',\n ).length,\n };\n}\n\nexport function catalogSyncStatus(entities: Entity[]) {\n const entity = entities.find(\n candidate =>\n candidate.kind.toLowerCase() === 'resource' &&\n candidate.metadata.name === CATALOG_SYNC_STATUS_ENTITY,\n );\n const annotations = entity?.metadata.annotations ?? {};\n return {\n status: annotations[ANYSHIFT_CATALOG_SYNC_STATUS_ANNOTATION] ?? 'waiting',\n trigger: annotations[ANYSHIFT_CATALOG_SYNC_TRIGGER_ANNOTATION],\n finishedAt: annotations[ANYSHIFT_CATALOG_SYNC_FINISHED_AT_ANNOTATION],\n error: annotations[ANYSHIFT_CATALOG_SYNC_ERROR_ANNOTATION],\n };\n}\n\nexport const EstateInsightsGrid = ({\n insights,\n onRetryCoverage,\n refreshingCoverage = false,\n}: {\n insights: EstateInsights;\n onRetryCoverage?: () => void;\n refreshingCoverage?: boolean;\n}) => {\n const coverage = insights.coverage ?? {\n state: 'unsupported' as const,\n message: 'Evidence coverage is not available from this backend version.',\n };\n return (\n <>\n <Grid item xs={12}>\n <InfoCard\n title=\"Evidence coverage\"\n subheader=\"Observed graph sources and observability blind spots\"\n >\n {coverage.state === 'data' && coverage.data ? (\n <>\n <EvidenceCoveragePresenter data={coverage.data} />\n {coverage.retryable && onRetryCoverage && (\n <Box mt={2}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={onRetryCoverage}\n disabled={refreshingCoverage}\n >\n {refreshingCoverage\n ? 'Retrying…'\n : 'Retry evidence coverage'}\n </Button>\n </Box>\n )}\n </>\n ) : (\n <>\n <Typography\n color={coverage.state === 'error' ? 'error' : 'textSecondary'}\n >\n {coverage.message || 'No coverage evidence is available.'}\n </Typography>\n {coverage.retryable && onRetryCoverage && (\n <Box mt={2}>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={onRetryCoverage}\n disabled={refreshingCoverage}\n >\n {refreshingCoverage\n ? 'Retrying…'\n : 'Retry evidence coverage'}\n </Button>\n </Box>\n )}\n </>\n )}\n </InfoCard>\n </Grid>\n {insights.sections.map(item => (\n <Grid item xs={12} md={6} key={item.id}>\n <InfoCard title={item.title}>\n {item.section.state === 'error' ? (\n <Typography color=\"error\">{item.section.message}</Typography>\n ) : item.section.state === 'empty' ||\n item.section.state === 'unsupported' ||\n item.section.data === undefined ? (\n <Typography color=\"textSecondary\">\n {item.section.message || 'No insight evidence is available.'}\n </Typography>\n ) : item.id === 'recent-change' ? (\n <TimelinePresenter\n data={item.section.data}\n fallbackLabel=\"Deployment\"\n />\n ) : (\n <ImpactPresenter data={item.section.data} />\n )}\n </InfoCard>\n </Grid>\n ))}\n </>\n );\n};\n\nexport const EvidenceCoveragePresenter = ({\n data,\n}: {\n data: EvidenceCoverage;\n}) => {\n const metrics = [\n [data.graph.nodes, 'Graph nodes'],\n [data.graph.relationships, 'Relationships'],\n [data.graph.bridges, 'Cross-source bridges'],\n [data.graph.events, 'Runtime events'],\n ] as const;\n const refreshedAt = Date.parse(data.refreshedAt);\n const stale =\n Number.isFinite(refreshedAt) && Date.now() - refreshedAt > 15 * 60 * 1000;\n\n return (\n <>\n <Box\n display=\"flex\"\n flexWrap=\"wrap\"\n alignItems=\"center\"\n gridGap={8}\n mb={2}\n >\n <Typography variant=\"h5\">\n {data.connectedSources === null\n ? `Unknown of ${data.expectedSources} sources`\n : `${data.connectedSources} of ${data.expectedSources} sources`}\n </Typography>\n <Chip\n size=\"small\"\n color={stale ? 'secondary' : 'primary'}\n label={stale ? 'Stale evidence' : 'Fresh evidence'}\n />\n </Box>\n <Grid container spacing={2}>\n {metrics.map(([value, label]) => (\n <Grid item xs={6} md={3} key={label}>\n <Typography variant=\"h6\">\n {value === null ? 'N/A' : value.toLocaleString()}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {label}\n </Typography>\n </Grid>\n ))}\n </Grid>\n <Grid container spacing={3}>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Missing source evidence\n </Typography>\n {data.missingSources.length > 0 ? (\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={6}>\n {data.missingSources.map(source => (\n <Chip\n key={source}\n size=\"small\"\n variant=\"outlined\"\n label={source}\n />\n ))}\n </Box>\n ) : (\n <Typography variant=\"body2\" color=\"textSecondary\">\n None reported by the Graph API.\n </Typography>\n )}\n </Grid>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Observability blind spots\n </Typography>\n <Typography variant=\"body2\">\n {data.blindSpots.workloadCount === null\n ? 'Workload coverage unavailable'\n : `${data.blindSpots.workloadCount} workloads`}\n </Typography>\n {data.blindSpots.workloads.map(workload => (\n <Box key={`${workload.namespace}/${workload.name}`}>\n <Typography variant=\"body2\">{workload.name}</Typography>\n {workload.namespace && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {workload.namespace}\n </Typography>\n )}\n </Box>\n ))}\n </Grid>\n </Grid>\n <Box mt={2}>\n {data.warnings.map(warning => (\n <Typography key={warning} variant=\"caption\" color=\"textSecondary\">\n {warning}\n </Typography>\n ))}\n </Box>\n </>\n );\n};\n\nexport const AnyshiftExplorerPage = () => {\n const api = useApi(anyshiftApiRef);\n const catalogApi = useApi(catalogApiRef);\n const queryPermission = usePermission({\n permission: anyshiftQueryPermission,\n });\n const catalogSyncPermission = usePermission({\n permission: anyshiftCatalogSyncPermission,\n });\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const [insights, setInsights] = useState<EstateInsights>();\n const [insightError, setInsightError] = useState<string>();\n const [refreshingInsights, setRefreshingInsights] = useState(false);\n const [datadogSignals, setDatadogSignals] = useState<DatadogSignals>();\n const [datadogError, setDatadogError] = useState<string>();\n const [refreshingDatadog, setRefreshingDatadog] = useState(false);\n const [catalogEntities, setCatalogEntities] = useState<Entity[]>([]);\n const [catalogError, setCatalogError] = useState<string>();\n const [catalogQuery, setCatalogQuery] = useState('');\n const [sql, setSql] = useState(DEFAULT_QUERY);\n const [queryResult, setQueryResult] = useState<QueryResult>();\n const [queryError, setQueryError] = useState<string>();\n const [requestingSync, setRequestingSync] = useState(false);\n const [syncRequestMessage, setSyncRequestMessage] = useState<string>();\n const [syncRequestError, setSyncRequestError] = useState<string>();\n\n useEffect(() => {\n api\n .capabilities()\n .then(setCapabilities)\n .catch(() => setCapabilities({ askEnabled: false, queryEnabled: false }));\n }, [api]);\n\n useEffect(() => {\n api\n .datadogSignals()\n .then(setDatadogSignals)\n .catch(error => {\n setDatadogError(error instanceof Error ? error.message : String(error));\n });\n }, [api]);\n\n const loadInsights = useCallback(\n async (refresh = false) => {\n if (refresh) setRefreshingInsights(true);\n setInsightError(undefined);\n try {\n setInsights(await api.insights({ refresh }));\n } catch (error) {\n setInsightError(error instanceof Error ? error.message : String(error));\n } finally {\n if (refresh) setRefreshingInsights(false);\n }\n },\n [api],\n );\n\n useEffect(() => {\n void loadInsights();\n }, [loadInsights]);\n\n useEffect(() => {\n catalogApi\n .getEntities({\n filter: [{ kind: 'Component' }, { kind: 'Resource' }],\n })\n .then(response => setCatalogEntities(response.items))\n .catch(error => {\n setCatalogError(error instanceof Error ? error.message : String(error));\n });\n }, [catalogApi]);\n\n const anyshiftEntities = catalogEntities.filter(\n entity => entity.metadata.annotations?.['anyshift.io/target'],\n );\n const syncSummary = summarizeCatalogSync(catalogEntities);\n const syncStatus = catalogSyncStatus(catalogEntities);\n const matchingEntities = anyshiftEntities\n .filter(entity => matchesCatalogEntity(entity, catalogQuery))\n .slice(0, 12);\n\n const runQuery = async () => {\n if (!isDeterministicSelect(sql)) {\n setQueryError('Enter one deterministic SELECT query.');\n return;\n }\n setQueryError(undefined);\n try {\n setQueryResult(await api.query(sql.trim()));\n } catch (error) {\n setQueryError(error instanceof Error ? error.message : String(error));\n }\n };\n\n const refreshDatadog = async () => {\n setRefreshingDatadog(true);\n setDatadogError(undefined);\n try {\n setDatadogSignals(await api.datadogSignals({ refresh: true }));\n } catch (error) {\n setDatadogError(error instanceof Error ? error.message : String(error));\n } finally {\n setRefreshingDatadog(false);\n }\n };\n\n const requestCatalogSync = async () => {\n setRequestingSync(true);\n setSyncRequestError(undefined);\n setSyncRequestMessage(undefined);\n try {\n const accepted = await api.reconcileCatalog();\n setSyncRequestMessage(\n `Reconciliation accepted ${formatTimestamp(accepted.acceptedAt)}.`,\n );\n } catch (error) {\n setSyncRequestError(\n error instanceof Error ? error.message : String(error),\n );\n } finally {\n setRequestingSync(false);\n }\n };\n\n return (\n <Page themeId=\"tool\">\n <Header\n title=\"Anyshift\"\n subtitle=\"Live infrastructure context for your software catalog\"\n />\n <Content>\n {datadogSignals ? (\n <DatadogOperationsRadar\n signals={datadogSignals}\n catalogEntities={anyshiftEntities}\n onRefresh={refreshDatadog}\n refreshing={refreshingDatadog}\n error={datadogError}\n />\n ) : datadogError ? (\n <Typography color=\"error\">{datadogError}</Typography>\n ) : (\n <Progress />\n )}\n <ContentHeader title=\"Catalog synchronization\" />\n <InfoCard subheader=\"GitHub ownership stays authoritative; Anyshift adds observed infrastructure context\">\n <Grid container spacing={2}>\n <Grid item xs={6} md={2}>\n <Typography variant=\"h5\">{syncSummary.configured}</Typography>\n <Typography color=\"textSecondary\">Configured</Typography>\n </Grid>\n <Grid item xs={6} md={2}>\n <Typography variant=\"h5\">{syncSummary.excluded}</Typography>\n <Typography color=\"textSecondary\">Excluded</Typography>\n </Grid>\n <Grid item xs={6} md={2}>\n <Typography variant=\"h5\">{syncSummary.unclassified}</Typography>\n <Typography color=\"textSecondary\">Unclassified</Typography>\n </Grid>\n <Grid item xs={6} md={2}>\n <Typography variant=\"h5\">{syncSummary.observed}</Typography>\n <Typography color=\"textSecondary\">Active matches</Typography>\n </Grid>\n <Grid item xs={6} md={2}>\n <Typography variant=\"h5\">\n {syncSummary.managedResources}\n </Typography>\n <Typography color=\"textSecondary\">Managed resources</Typography>\n </Grid>\n <Grid item xs={12}>\n <Typography>\n Last reconciliation: <strong>{syncStatus.status}</strong>\n {syncStatus.finishedAt\n ? ` · ${formatTimestamp(syncStatus.finishedAt)}`\n : ''}\n {syncStatus.trigger ? ` · ${syncStatus.trigger}` : ''}\n </Typography>\n {syncStatus.error && (\n <Typography color=\"error\">\n Last failure: {syncStatus.error}\n </Typography>\n )}\n {catalogSyncPermission.allowed && (\n <Button\n variant=\"outlined\"\n color=\"primary\"\n disabled={requestingSync}\n onClick={requestCatalogSync}\n style={{ marginTop: 12 }}\n >\n {requestingSync ? 'Requesting…' : 'Reconcile now'}\n </Button>\n )}\n {syncRequestMessage && (\n <Typography color=\"textSecondary\">\n {syncRequestMessage}\n </Typography>\n )}\n {syncRequestError && (\n <Typography color=\"error\">{syncRequestError}</Typography>\n )}\n </Grid>\n </Grid>\n </InfoCard>\n <ContentHeader title=\"Find a service\" />\n <InfoCard subheader=\"Anyshift-annotated Components and Resources in the Backstage catalog\">\n <TextField\n fullWidth\n variant=\"outlined\"\n label=\"Search services and resources\"\n value={catalogQuery}\n onChange={event => setCatalogQuery(event.target.value)}\n />\n {catalogError && (\n <Typography color=\"error\">{catalogError}</Typography>\n )}\n {!catalogError && matchingEntities.length === 0 ? (\n <Typography color=\"textSecondary\" style={{ marginTop: 12 }}>\n No matching Anyshift catalog entities.\n </Typography>\n ) : (\n <ul>\n {matchingEntities.map(entity => (\n <li\n key={`${entity.kind}:${\n entity.metadata.namespace ?? 'default'\n }/${entity.metadata.name}`}\n >\n <EntityRefLink entityRef={entity} />\n {entity.metadata.description\n ? ` - ${entity.metadata.description}`\n : null}\n </li>\n ))}\n </ul>\n )}\n </InfoCard>\n <ContentHeader title=\"Estate insights\" />\n {insightError && <Typography color=\"error\">{insightError}</Typography>}\n {!insights && !insightError ? <Progress /> : null}\n <Grid container spacing={3}>\n {insights && (\n <EstateInsightsGrid\n insights={insights}\n onRetryCoverage={() => void loadInsights(true)}\n refreshingCoverage={refreshingInsights}\n />\n )}\n {capabilities.askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"estate\" />\n </Grid>\n )}\n {capabilities.queryEnabled && queryPermission.allowed && (\n <Grid item xs={12}>\n <InfoCard\n title=\"Advanced query\"\n subheader=\"Deterministic Graph API SELECT queries only\"\n >\n <TextField\n fullWidth\n multiline\n minRows={2}\n variant=\"outlined\"\n value={sql}\n onChange={event => setSql(event.target.value)}\n />\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={runQuery}\n style={{ marginTop: 12 }}\n >\n Run query\n </Button>\n {queryError && (\n <Typography color=\"error\">{queryError}</Typography>\n )}\n {queryResult && (\n <pre style={{ whiteSpace: 'pre-wrap', fontSize: 12 }}>\n {JSON.stringify(queryResult, null, 2)}\n </pre>\n )}\n </InfoCard>\n </Grid>\n )}\n </Grid>\n </Content>\n </Page>\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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"}