@gravitee/gamma-lib-observability 6.3.0 → 6.4.0

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 (105) hide show
  1. package/INTEGRATION.md +43 -25
  2. package/dist/components/FailureDetailsSheet.d.ts +13 -0
  3. package/dist/components/FailureDetailsSheet.d.ts.map +1 -0
  4. package/dist/components/LoadFailedState.d.ts +40 -0
  5. package/dist/components/LoadFailedState.d.ts.map +1 -0
  6. package/dist/components/QueryErrorBanner.d.ts +5 -3
  7. package/dist/components/QueryErrorBanner.d.ts.map +1 -1
  8. package/dist/components/failure-wording.d.ts +61 -0
  9. package/dist/components/failure-wording.d.ts.map +1 -0
  10. package/dist/components/index.d.ts +3 -0
  11. package/dist/components/index.d.ts.map +1 -1
  12. package/dist/components/refusal-wording.d.ts +9 -4
  13. package/dist/components/refusal-wording.d.ts.map +1 -1
  14. package/dist/dashboard-access-provider.js +151 -104
  15. package/dist/dashboards/DashboardView.d.ts.map +1 -1
  16. package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts +3 -0
  17. package/dist/dashboards/analytics-table/use-analytics-table-query.d.ts.map +1 -1
  18. package/dist/dashboards/editor/DashboardEditorPage.d.ts.map +1 -1
  19. package/dist/dashboards/index.d.ts +2 -1
  20. package/dist/dashboards/index.d.ts.map +1 -1
  21. package/dist/dashboards/renderers/BarWidgetRenderer.d.ts.map +1 -1
  22. package/dist/dashboards/renderers/BreakdownWidgetRenderer.d.ts.map +1 -1
  23. package/dist/dashboards/renderers/CartesianWidgetRenderer.d.ts.map +1 -1
  24. package/dist/dashboards/renderers/DoughnutWidgetRenderer.d.ts.map +1 -1
  25. package/dist/dashboards/renderers/MetricGroupWidgetRenderer.d.ts.map +1 -1
  26. package/dist/dashboards/renderers/MetricWidgetRenderer.d.ts.map +1 -1
  27. package/dist/dashboards/renderers/TableWidgetRenderer.d.ts.map +1 -1
  28. package/dist/dashboards/renderers/WidgetAccessDenied.d.ts +0 -12
  29. package/dist/dashboards/renderers/WidgetAccessDenied.d.ts.map +1 -1
  30. package/dist/dashboards/renderers/WidgetLoadFailed.d.ts +23 -0
  31. package/dist/dashboards/renderers/WidgetLoadFailed.d.ts.map +1 -0
  32. package/dist/dashboards/renderers/widget-question.d.ts +9 -0
  33. package/dist/dashboards/renderers/widget-question.d.ts.map +1 -0
  34. package/dist/dashboards/renderers/widget-trouble.d.ts +33 -0
  35. package/dist/dashboards/renderers/widget-trouble.d.ts.map +1 -0
  36. package/dist/data-sources/http-errors.d.ts +16 -3
  37. package/dist/data-sources/http-errors.d.ts.map +1 -1
  38. package/dist/filters/FilterAsyncValueField.d.ts +3 -2
  39. package/dist/filters/FilterAsyncValueField.d.ts.map +1 -1
  40. package/dist/filters/FilterBar.d.ts.map +1 -1
  41. package/dist/filters/FilterValueCombobox.d.ts +1 -2
  42. package/dist/filters/FilterValueCombobox.d.ts.map +1 -1
  43. package/dist/filters/FilterValueField.d.ts.map +1 -1
  44. package/dist/filters/filter-providers-context.d.ts +4 -0
  45. package/dist/filters/filter-providers-context.d.ts.map +1 -1
  46. package/dist/hooks/retry-policy.d.ts +3 -2
  47. package/dist/hooks/retry-policy.d.ts.map +1 -1
  48. package/dist/hooks/use-filter-catalog-load.d.ts +16 -0
  49. package/dist/hooks/use-filter-catalog-load.d.ts.map +1 -0
  50. package/dist/hooks/use-infinite-options.d.ts +6 -0
  51. package/dist/hooks/use-infinite-options.d.ts.map +1 -1
  52. package/dist/hooks/use-kept-answer.d.ts +52 -0
  53. package/dist/hooks/use-kept-answer.d.ts.map +1 -0
  54. package/dist/hooks/use-log-detail-query.d.ts +4 -0
  55. package/dist/hooks/use-log-detail-query.d.ts.map +1 -1
  56. package/dist/hooks/use-logs-paged-query.d.ts +4 -0
  57. package/dist/hooks/use-logs-paged-query.d.ts.map +1 -1
  58. package/dist/hooks/use-resume-live-data.d.ts +17 -0
  59. package/dist/hooks/use-resume-live-data.d.ts.map +1 -0
  60. package/dist/hooks/use-retry-failed-queries.d.ts +9 -0
  61. package/dist/hooks/use-retry-failed-queries.d.ts.map +1 -0
  62. package/dist/hooks/use-trace-detail-query.d.ts +4 -0
  63. package/dist/hooks/use-trace-detail-query.d.ts.map +1 -1
  64. package/dist/hooks/use-traces-paged-query.d.ts +4 -0
  65. package/dist/hooks/use-traces-paged-query.d.ts.map +1 -1
  66. package/dist/index.d.ts +4 -4
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +4629 -4062
  69. package/dist/live/LiveIndicator.d.ts +4 -0
  70. package/dist/live/LiveIndicator.d.ts.map +1 -1
  71. package/dist/live/format-clock.d.ts +5 -0
  72. package/dist/live/format-clock.d.ts.map +1 -0
  73. package/dist/live/use-live-retry-countdown.d.ts +12 -0
  74. package/dist/live/use-live-retry-countdown.d.ts.map +1 -0
  75. package/dist/logs/LogsExplorerPage.d.ts.map +1 -1
  76. package/dist/logs/detail/components/LogDetailContextChart.d.ts.map +1 -1
  77. package/dist/logs/detail/components/LogDetailDrawer.d.ts.map +1 -1
  78. package/dist/logs/detail/components/LogDetailError.d.ts +5 -1
  79. package/dist/logs/detail/components/LogDetailError.d.ts.map +1 -1
  80. package/dist/logs/detail/components/LogDetailPage.d.ts.map +1 -1
  81. package/dist/logs/detail/presets/message-log-preset.d.ts.map +1 -1
  82. package/dist/providers/live-refresh-provider.d.ts +17 -0
  83. package/dist/providers/live-refresh-provider.d.ts.map +1 -1
  84. package/dist/routing/DashboardListPage.d.ts.map +1 -1
  85. package/dist/routing/ObservabilityDashboardPage.d.ts.map +1 -1
  86. package/dist/routing/ObservabilityRoutes.d.ts.map +1 -1
  87. package/dist/routing/TracingFilterProvider.d.ts.map +1 -1
  88. package/dist/routing/TracingScreen.d.ts.map +1 -1
  89. package/dist/shared/ExplorerTable.d.ts.map +1 -1
  90. package/dist/styles/observability.css +1 -1
  91. package/dist/testing/graphene-charts-mock.d.ts +1 -0
  92. package/dist/testing/graphene-charts-mock.d.ts.map +1 -1
  93. package/dist/testing/graphene-core-mock.d.ts +2 -0
  94. package/dist/testing/graphene-core-mock.d.ts.map +1 -1
  95. package/dist/testing.js +6 -6
  96. package/dist/traces/TraceExplorerPage.d.ts.map +1 -1
  97. package/dist/traces/TracingApiSelector.d.ts +4 -1
  98. package/dist/traces/TracingApiSelector.d.ts.map +1 -1
  99. package/dist/traces/detail/TraceDetailDrawer.d.ts.map +1 -1
  100. package/dist/traces/detail/TraceDetailPage.d.ts.map +1 -1
  101. package/dist/traces/detail/TraceDetailStates.d.ts +5 -1
  102. package/dist/traces/detail/TraceDetailStates.d.ts.map +1 -1
  103. package/dist/traces/use-tracing-api-paginated-options.d.ts +5 -1
  104. package/dist/traces/use-tracing-api-paginated-options.d.ts.map +1 -1
  105. package/package.json +1 -1
package/INTEGRATION.md CHANGED
@@ -1279,25 +1279,27 @@ Capabilities say what the host allows in general; the backend's ACLs decide per
1279
1279
 
1280
1280
  Refusals are remembered **per verb family** (read, write), not per operation: one refused delete withdraws every authoring affordance — create, edit and delete alike — until some write succeeds or the section remounts. If your ACL model routinely grants partial write sets, expect that coarseness.
1281
1281
 
1282
- A store that enforces permissions must reject with `DashboardForbiddenError` (or a `status: 403` error) for the degradation to engage — see the port's documentation. Only a 403 earns the quiet degradation: any other listing failure is a fault, not a designed experience (its current silence on the list is a known gap).
1282
+ A store that enforces permissions must reject with `DashboardForbiddenError` (or a `status: 403` error) for the degradation to engage — see the port's documentation. Only a 403 earns the quiet degradation: any other listing failure is a fault, and the list says so above its table ("Couldn't load custom dashboards.", with "Try again" and "View details"), the templates still listed.
1283
1283
 
1284
1284
  #### Refused data (logs, traces, analytics, filters)
1285
1285
 
1286
1286
  The same rule holds for the data behind the screens. The built-in HTTP sources reject a failed call with an `ObservabilityHttpError` that keeps the HTTP `status`; `isForbiddenError(error)` tells a refusal from any other failure, reading the status from the shape so a host source's own errors (anything with `status: 403`) count too. A refusal is named where it happened, never offered a retry, and never shown as "no data". Every refusal uses the same component, `AccessDeniedState`, so the reader is guided the same way everywhere: the title names the data, and the description is always "Ask an administrator for access." Its `compact` variant (a chart's area, dashboard tiles) drops the description by itself when its box is too short; its `inline` variant fits next to a control.
1287
1287
 
1288
- | Where | On a refusal | On any other failure |
1289
- | ------------------------------ | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
1290
- | Logs page, logs table | Headers kept; "No access to logs" where "No logs found" would be | Error banner with Retry (unchanged) |
1291
- | Logs page, chart | "No access to analytics" in the chart's area, at its height | The chart's empty state (unchanged) |
1292
- | Logs page, both refused | One "No access to logs and analytics" for the page, in place of chart and table; no filters or time range | Each part as above |
1293
- | Log detail chart | "No access to analytics" in the chart's place | The chart's empty state (unchanged) |
1294
- | Traces table | Headers kept; "No access to traces" in the empty rows; no filters or time range | Error banner with Retry (unchanged) |
1295
- | Log and trace detail | "No access to this log" / "No access to this trace" | Error with Retry (unchanged) |
1296
- | A dashboard widget | "No access to analytics" (or logs, traces) in that tile only, when the dashboard is mixed | The widget's empty state (unchanged) |
1297
- | A whole dashboard | One state named after the refused kinds, in place of the widget grid; title kept, no filters or time range | Each widget as above |
1298
- | Filter bar (both filter lists) | "No access to filters." inline, next to the disabled "Add filter" | "Filters could not be loaded." with Retry |
1299
- | Tracing API picker (paginated) | "No access to APIs." inline, next to the field | "Failed to load APIs. Try again." |
1300
- | Filter values | Falls back to typing the value, as for any listing failure | Same (unchanged) |
1288
+ | Where | On a refusal | On any other failure |
1289
+ | --------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
1290
+ | Logs page, logs table | Headers kept; "No access to logs" where "No logs found" would be | "Couldn't load logs" in the empty rows |
1291
+ | Logs page, chart | "No access to analytics" in the chart's area, at its height | "Couldn't load analytics" in its area |
1292
+ | Logs page, both refused | One "No access to logs and analytics" for the page, in place of chart and table; no filters or time range | Both failed: one state with Try again |
1293
+ | Log detail chart | "No access to analytics" in the chart's place | "Couldn't load analytics" in its place |
1294
+ | Traces table | Headers kept; "No access to traces" in the empty rows; no filters or time range | "Couldn't load traces" with Try again |
1295
+ | Log and trace detail | "No access to this log" / "No access to this trace" | "Couldn't load this log" with Try again |
1296
+ | A dashboard widget | "No access to analytics" (or logs, traces) in that tile only, when the dashboard is mixed | "Couldn't load analytics" in that tile |
1297
+ | A whole dashboard | One state named after the refused kinds, in place of the widget grid; title kept, no filters or time range | All failed: one state with Try again |
1298
+ | Filter bar (both filter lists) | "No access to filters." inline, next to the disabled "Add filter" | "Couldn't load filters." with Try again |
1299
+ | Tracing API picker (paginated) | "No access to APIs." inline, next to the field | "Couldn't load APIs." with Try again |
1300
+ | Filter values | Falls back to typing the value, with "No access to these values." under the field | Falls back to typing the value, with "Couldn't load values." and Try again under the field |
1301
+ | A custom dashboard (page, editor) | "No access to this dashboard"; the editor keeps "Back to dashboards" | "Couldn't load this dashboard" with Try again |
1302
+ | Dashboards list | Read-only template experience, no error | "Couldn't load custom dashboards." with Try again, above the templates |
1301
1303
 
1302
1304
  **404 that may stand for a refusal.** The trace search, trace detail and log detail endpoints answer 404 for an API the reader may not see, so that its existence does not leak. These three screens keep that promise: on a 404 (`isNotFoundError`), and on a log detail the source reports as missing, they show "API not found, or you don't have access" (in the traces table), "Trace not found, …" or "Log not found, …", with "Check the link, or ask an administrator for access.", and no retry. A 404 anywhere else keeps its existing handling.
1303
1305
 
@@ -1307,19 +1309,35 @@ An empty answer is not a refusal: a reader whose APIs have no traffic in range,
1307
1309
 
1308
1310
  **Retries.** The library's queries run on the host's `QueryClient`, and its `retry` setting still applies to failures (5xx, network). A 4xx answer is never retried: the server answered on purpose, so the screen says so at once instead of showing skeletons through every retry.
1309
1311
 
1312
+ ### Load failures (5xx, network)
1313
+
1314
+ A failure that is not a refusal (a 5xx, a network error, a host source's own error) is shown the same way everywhere, with `LoadFailedState`, the sibling of `AccessDeniedState`: same variants and the same layout (an icon, a title naming the data, one line under it), nothing in red, and in the data's own place, so a failure never reads as an empty answer and never sits above one. The table above lists where. "No data" and "No logs found" are for empty answers only.
1315
+
1316
+ - **Wording.** The title names the data: "Couldn't load logs", "Couldn't load analytics", "Couldn't load traces", "Couldn't load this log", "Couldn't load this trace". A compact state (a tile, a chart's area) shows the title alone. While Live is on, a state whose data follows the Live window (`followsLive`) counts down to the refresh that loads it again: "Trying again in 42 seconds.", and a page-level state's button reads "Try now". Otherwise (Live paused, an absolute range, a log or trace opened by id) a page-level state says "Something went wrong. Try again in a moment." with "Try again".
1317
+ - **A failed refetch keeps what is on screen, everywhere.** Live data keeps its earlier answer and the Live pill says so; a log or a trace opened by id keeps showing when a background refetch fails (the detail hooks' `isError` means "failed with nothing to show"); a filter list asked again keeps the screens, its failure saying "Trying again…" (`FilterCatalogLoad.retrying`), never the first-load skeleton.
1318
+ - **No flicker between two failures.** While the same question is asked again (the next Live refresh, "Try again"), the failure stays on screen until an answer comes back, rather than flashing a loading state; the details stay open. Meanwhile the state says "Trying again…" in place of its countdown, its button pending (`LoadFailure.retrying`, set by the library's hooks; a host passes `retrying` to `WidgetLoadFailed`).
1319
+ - **One retry per page.** One part of a page failing (a widget tile, the logs chart or the logs table, the log detail's chart) gets no retry: the rest of the page still works and the next refresh asks again. A page whose every part failed gets exactly one "Try again", which re-runs every failed query on screen: the traces page, a log or trace detail (a drawer included), the logs page with both parts failed (one state, "Couldn't load logs and analytics"), the logs page without a chart, a dashboard whose every widget failed. The filter bar, the tracing API picker and the message list of a log detail keep their own inline "Try again": Live mode refreshes the data, never those lists.
1320
+ - **One state for a page.** A dashboard shows one state for all of it only when every widget has the same outcome, all refused or all failed, in place of its grid. Any mix, a refused widget next to a failed one included, keeps a state per tile. On the Logs page, a refusal on one side and a failure on the other stay each in place. Unlike a refusal, a failure keeps the filters and the time range: it may depend on them.
1321
+ - **Details on demand.** A state's "View details" opens a side panel with each failed call: its status, the call, what went wrong in words and when it failed, and "Copy for support", which copies exactly that as text. The words are labelled "Server message", in monospace, when they are what the server said in its answer (the `message`, `detail` or `error` of a JSON body, or a short plain-text body; never an HTML error page), kept as `ObservabilityHttpError.detail`. The Management API answers with the exception's message only, never its stack: a failed search answers `{ "message": "Unable to search", "http_status": 500 }`, what its Elasticsearch client says for any search that fails, and an invalid request names the problem ("Value 'abc' is not a whole number, as filter 'HTTP_STATUS' requires", on a 400). A call that got no response shows "Error" with the error it ended on, such as "Failed to fetch". Every form of the state, a tile, a chart's area and a line next to a control included, offers the same "View details". There is no request id: the sources read no response headers. `ObservabilityHttpError` carries the `call` for this; a host source's error with a `status` and a `call` is described the same way. The `[gamma-lib-observability]` prefix of the error message stays in console logs.
1322
+ - **A failed refresh keeps the data.** Live mode refetches every minute by moving the window forward, and switching Paused back to Live refetches at once, on every page, the data Live keeps fresh only (analytics, logs and traces searches): a log or a trace open in a drawer, a filter list or a dashboard definition is not reloaded. When a refresh fails with data on screen, the data stays and the Live pill says so: an amber dot, and "Couldn't refresh at HH:MM. Showing earlier data." in its tooltip. That is the page's one signal of stale data, never a failure state over good data. A change of filters or time range is a new question: if it fails, the failure is shown, never the old data. A refusal never keeps old data either.
1323
+ - **Host widgets.** A host widget renderer shows its failure with `WidgetLoadFailed` (`error`, `failedAt`, and `dataKind` for logs or traces), which also lets the dashboard show one state when every widget failed. Pass the query's own `error`: the same object from one render to the next.
1324
+
1325
+ `QueryErrorBanner` stays exported for hosts that render it, but the library's pages no longer use it.
1326
+
1310
1327
  **Try it.** The Storybook story `Routing/Permissions › Playground` renders every observability page through the real routes against mock sources. Its controls reach each case above without code, and default to everything allowed. Changing a right refreshes the page you are on, and navigating in the story's sidebar moves the Page control along:
1311
1328
 
1312
- | Control | Values | What it drives |
1313
- | --------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------ |
1314
- | Page | Home, Dashboard, Logs, Log detail, Tracing, Trace detail | The page the reader opens (Home: the section root) |
1315
- | Analytics | Allowed, Refused (403), Failing (500) | Dashboard widgets, the logs histogram, the log detail chart |
1316
- | Logs | Allowed, Refused (403), Failing (500) | The logs table, a log detail, the dashboard's logs widget |
1317
- | Traces | Allowed, Refused (403), Failing (500) | The traces table and a trace detail |
1318
- | API the reader may not see | on / off | The deliberate 404 on the tracing page, a trace detail and a log detail |
1319
- | Filter lists | Allowed, Refused (403), Failing (500) | The filter bar's filter lists (analytics and tracing) |
1320
- | Tracing API list | Allowed, Refused (403), Failing (500) | The tracing API picker |
1321
- | Capability: dashboards.read, dashboards.write, logs.read, traces.read | on / off | The host's capabilities: which sections exist, in the nav and the routes |
1322
- | Dashboard with a logs widget | on / off | Adds a host widget backed by logs, for a dashboard mixing data kinds |
1329
+ | Control | Values | What it drives |
1330
+ | --------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
1331
+ | Page | Home, Dashboard, Logs, Log detail, Tracing, Trace detail | The page the reader opens (Home: the section root) |
1332
+ | Analytics | Allowed, Refused (403), Failing (500), Partly failing | Dashboard widgets, the logs histogram, the log detail chart; partly: the breakdowns fail, time series and totals load |
1333
+ | Failed refresh | on / off | Data loads, then every refresh fails: the Live pill turns amber |
1334
+ | Logs | Allowed, Refused (403), Failing (500) | The logs table, a log detail, the dashboard's logs widget |
1335
+ | Traces | Allowed, Refused (403), Failing (500) | The traces table and a trace detail |
1336
+ | API the reader may not see | on / off | The deliberate 404 on the tracing page, a trace detail and a log detail |
1337
+ | Filter lists | Allowed, Refused (403), Failing (500) | The filter bar's filter lists (analytics and tracing) |
1338
+ | Tracing API list | Allowed, Refused (403), Failing (500) | The tracing API picker |
1339
+ | Capability: dashboards.read, dashboards.write, logs.read, traces.read | on / off | The host's capabilities: which sections exist, in the nav and the routes |
1340
+ | Dashboard with a logs widget | on / off | Adds a host widget backed by logs, for a dashboard mixing data kinds |
1323
1341
 
1324
1342
  **Concurrent edits.** `DashboardConflictError` carries `currentDashboard`, the dashboard as it now stands in the store, and the editor renders it from there rather than fetching again. The author then picks one of three resolutions, and each comes back to this port:
1325
1343
 
@@ -0,0 +1,13 @@
1
+ import { LoadFailure } from './failure-wording';
2
+ export interface FailureDetailsSheetProps {
3
+ readonly failures: readonly LoadFailure[];
4
+ readonly open: boolean;
5
+ readonly onOpenChange: (open: boolean) => void;
6
+ }
7
+ /**
8
+ * The technical side of a failure, one step away from the page: each failed
9
+ * call with its status, the call, what the server said about it and when it
10
+ * failed, and a copy of exactly that as text for a support ticket.
11
+ */
12
+ export declare function FailureDetailsSheet({ failures, open, onOpenChange }: FailureDetailsSheetProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=FailureDetailsSheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FailureDetailsSheet.d.ts","sourceRoot":"","sources":["../../src/components/FailureDetailsSheet.tsx"],"names":[],"mappings":"AAYA,OAAO,EAML,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAcD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,wBAAwB,2CAkC7F"}
@@ -0,0 +1,40 @@
1
+ import { ReactNode } from 'react';
2
+ import { AccessDeniedStateVariant } from './AccessDeniedState';
3
+ import { LoadFailure } from './failure-wording';
4
+ /** The same three as a refusal: a page or a table's rows, a small box, one line next to a control. */
5
+ export type LoadFailedStateVariant = AccessDeniedStateVariant;
6
+ export interface LoadFailedStateProps {
7
+ /** What did not load, naming the data: "Couldn't load logs". */
8
+ readonly title: string;
9
+ /** The failures behind it, described on demand for support. */
10
+ readonly failures?: readonly LoadFailure[];
11
+ /**
12
+ * Given to a page-level state only: re-runs the page's failed loads, and
13
+ * adds the guidance that goes with it. One part of a page failing gets no
14
+ * retry: the next refresh asks again, and the rest of the page still works.
15
+ */
16
+ readonly onRetry?: () => void;
17
+ /**
18
+ * The data loads again on its own at each Live refresh (a query built on the
19
+ * Live window): the state counts down to the next one while Live is on.
20
+ * Leave it off for data Live never reloads, such as a log opened by id.
21
+ * @default false
22
+ */
23
+ readonly followsLive?: boolean;
24
+ /** Rendered next to the retry, e.g. a way back. Shown by the default form only, like a refusal's. */
25
+ readonly action?: ReactNode;
26
+ /** @default 'default' */
27
+ readonly variant?: LoadFailedStateVariant;
28
+ readonly className?: string;
29
+ }
30
+ /**
31
+ * What a screen shows in place of data that failed to load (5xx, network).
32
+ * Every failure in the library uses it, in the data's own place, so a failure
33
+ * never reads as an empty answer. The sibling of `AccessDeniedState`, laid out
34
+ * the same way so a failure and a refusal read alike: an icon, a title naming
35
+ * the data, one line under it. Neutral, nothing in red, and the technical
36
+ * details one step away: every form, down to a tile or a line next to a
37
+ * control, offers the same "View details" and its side panel.
38
+ */
39
+ export declare function LoadFailedState({ title, failures, onRetry, followsLive, action, variant, className, }: LoadFailedStateProps): import("react/jsx-runtime").JSX.Element;
40
+ //# sourceMappingURL=LoadFailedState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadFailedState.d.ts","sourceRoot":"","sources":["../../src/components/LoadFailedState.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAExD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjG,sGAAsG;AACtG,MAAM,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,yBAAyB;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAmB,EACnB,MAAM,EACN,OAAmB,EACnB,SAAS,GACV,EAAE,oBAAoB,2CAmBtB"}
@@ -7,9 +7,11 @@ export interface QueryErrorBannerProps {
7
7
  }
8
8
  /**
9
9
  * Inline error banner for a failed data query. Exposed with `role="alert"` so
10
- * assistive technologies announce the failure as soon as it renders. Shared by
11
- * the observability explorer pages so logs and traces surface query errors
12
- * identically.
10
+ * assistive technologies announce the failure as soon as it renders.
11
+ *
12
+ * The library's own pages no longer use it: they show `LoadFailedState` in the
13
+ * data's own place, so a failure never sits above an empty table. Kept for
14
+ * hosts that still render it.
13
15
  */
14
16
  export declare function QueryErrorBanner({ message, onRetry, className }: QueryErrorBannerProps): import("react/jsx-runtime").JSX.Element;
15
17
  //# sourceMappingURL=QueryErrorBanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QueryErrorBanner.d.ts","sourceRoot":"","sources":["../../src/components/QueryErrorBanner.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CAiBtF"}
1
+ {"version":3,"file":"QueryErrorBanner.d.ts","sourceRoot":"","sources":["../../src/components/QueryErrorBanner.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CAiBtF"}
@@ -0,0 +1,61 @@
1
+ import { DataKind } from './refusal-wording';
2
+ /** A failed load, with when it failed: what a failure state's details describe. */
3
+ export interface LoadFailure {
4
+ readonly error: unknown;
5
+ /** When the load failed, in epoch milliseconds, when known. */
6
+ readonly at?: number;
7
+ /**
8
+ * The same data is being loaded again right now (a retry, a Live refresh):
9
+ * the state says so while it waits, rather than looking unchanged.
10
+ */
11
+ readonly retrying?: boolean;
12
+ }
13
+ /**
14
+ * What a page-level failure state says under its title, next to its one "Try
15
+ * again", when nothing will load the data again on its own.
16
+ */
17
+ export declare const FAILURE_GUIDANCE = "Something went wrong. Try again in a moment.";
18
+ /**
19
+ * The title of a failure, naming what did not load: "Couldn't load analytics",
20
+ * or every kind once when several parts failed, "Couldn't load logs and
21
+ * analytics".
22
+ */
23
+ export declare function failureTitle(kinds: Iterable<DataKind>): string;
24
+ /** What is known of one failed call, for the details. */
25
+ export interface FailureFacts {
26
+ /** The HTTP status, absent when no response came back. */
27
+ readonly status?: number;
28
+ /** The call that failed, "POST /observability/logs/search", when known. */
29
+ readonly call?: string;
30
+ /**
31
+ * What went wrong in words: what the server said about it, or without a
32
+ * response, the error's own message (a network failure, a timeout, a host
33
+ * source's error).
34
+ */
35
+ readonly message?: string;
36
+ readonly at?: number;
37
+ }
38
+ /**
39
+ * Each distinct failed call, the latest when the same call failed several
40
+ * times. No request id: the sources read no response headers.
41
+ */
42
+ export declare function failureFacts(failures: readonly LoadFailure[]): FailureFacts[];
43
+ /** "HTTP 500", or "No response" when nothing came back. */
44
+ export declare function failureStatusLabel(status: number | undefined): string;
45
+ /**
46
+ * What the words of a failure are: what the server said in its answer, or,
47
+ * when no answer came, the error the call ended on ("Failed to fetch").
48
+ */
49
+ export declare function failureMessageLabel(status: number | undefined): string;
50
+ /** "Today, 10:42:13", or the date as well on another day. */
51
+ export declare function formatFailureTime(at: number, now?: number): string;
52
+ /**
53
+ * The technical details of one or several failures as text, for a support
54
+ * ticket: the status, the call and the time of each distinct failed call.
55
+ */
56
+ export declare function describeFailures(failures: readonly LoadFailure[]): string;
57
+ /** What a failure state says while the data is being loaded again. */
58
+ export declare const RETRYING = "Trying again\u2026";
59
+ /** What a failure state says while Live mode is about to load the data again. */
60
+ export declare function retryCountdown(seconds: number): string;
61
+ //# sourceMappingURL=failure-wording.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-wording.d.ts","sourceRoot":"","sources":["../../src/components/failure-wording.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,iDAAiD,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAE9D;AAYD,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;CACtB;AAqBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,YAAY,EAAE,CAQ7E;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAErE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEtE;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,CAI9E;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAEzE;AAED,sEAAsE;AACtE,eAAO,MAAM,QAAQ,uBAAkB,CAAC;AAExC,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -1,5 +1,8 @@
1
1
  export { AccessDeniedState } from './AccessDeniedState';
2
2
  export type { AccessDeniedStateProps, AccessDeniedStateVariant } from './AccessDeniedState';
3
+ export { LoadFailedState } from './LoadFailedState';
4
+ export type { LoadFailedStateProps, LoadFailedStateVariant } from './LoadFailedState';
5
+ export type { LoadFailure } from './failure-wording';
3
6
  export { QueryErrorBanner } from './QueryErrorBanner';
4
7
  export type { QueryErrorBannerProps } from './QueryErrorBanner';
5
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACtF,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,9 +1,14 @@
1
1
  /**
2
- * The kinds of data a reader may be refused, one per right: analytics
3
- * (`API_ANALYTICS`), logs and traces (`API_LOG`). A refusal names the kind, so
4
- * the reader knows which access to ask for.
2
+ * The kinds of data a screen reads, one per right: analytics
3
+ * (`API_ANALYTICS`), logs and traces (`API_LOG`). A refusal or a failure
4
+ * names the kind, so the reader knows which access to ask for, or what is
5
+ * missing from the screen.
5
6
  */
6
- export type RefusedDataKind = 'logs' | 'traces' | 'analytics';
7
+ export type DataKind = 'logs' | 'traces' | 'analytics';
8
+ /** The kinds of data a reader may be refused. */
9
+ export type RefusedDataKind = DataKind;
10
+ /** Every kind once, in a stable order: "logs, traces and analytics". */
11
+ export declare function listDataKinds(kinds: Iterable<DataKind>): string;
7
12
  /**
8
13
  * The title of a refusal: "No access to analytics", or every refused kind once,
9
14
  * "No access to logs and analytics", so asking for one of them is not mistaken
@@ -1 +1 @@
1
- {"version":3,"file":"refusal-wording.d.ts","sourceRoot":"","sources":["../../src/components/refusal-wording.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAK9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,CAMrE"}
1
+ {"version":3,"file":"refusal-wording.d.ts","sourceRoot":"","sources":["../../src/components/refusal-wording.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,iDAAiD;AACjD,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;AAKvC,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAK/D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,MAAM,CAErE"}