@localstack/appinspector-ui 1.0.143 → 1.0.145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +343 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +417 -159
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2480,6 +2480,9 @@ var SPANS_LIST_PAGE_TEST_ID = "spans-list-page";
|
|
|
2480
2480
|
var TRACE_GRAPH_PAGE_TEST_ID = "trace-graph-page";
|
|
2481
2481
|
var VIEW_SPAN_DETAILS_TEST_ID = "view-span-details";
|
|
2482
2482
|
var SPANS_DATA_GRID_ROW_TEST_ID = "spans-data-grid-row";
|
|
2483
|
+
var SPANS_SEARCH_INPUT_TEST_ID = "spans-search-input";
|
|
2484
|
+
var SPANS_SEARCH_CLEAR_TEST_ID = "spans-search-clear";
|
|
2485
|
+
var SPANS_SEARCH_NO_MATCH_TEST_ID = "spans-search-no-match";
|
|
2483
2486
|
var EVENT_DETAILS_SECTION_BASIC_INFORMATION_TEST_ID = "event-details-section-basic-information";
|
|
2484
2487
|
var EVENT_DETAILS_SERVICE_NAME_TEST_ID = "event-details-service-name";
|
|
2485
2488
|
var EVENT_DETAILS_OPERATION_NAME_TEST_ID = "event-details-operation-name";
|
|
@@ -2512,6 +2515,7 @@ var EMULATOR_VERSION_BANNER_TEST_ID = "emulator-version-banner";
|
|
|
2512
2515
|
// src/utils/emulator-version.ts
|
|
2513
2516
|
var import_semver = __toESM(require_semver2(), 1);
|
|
2514
2517
|
var MINIMUM_EMULATOR_VERSION = "2026.4.0";
|
|
2518
|
+
var MIN_EMULATOR_VERSION_FOR_SEARCH = "2026.6.0";
|
|
2515
2519
|
function checkEmulatorVersion(version, now = /* @__PURE__ */ new Date()) {
|
|
2516
2520
|
if (!version) return "error";
|
|
2517
2521
|
const coerced = import_semver.default.coerce(version);
|
|
@@ -2522,6 +2526,13 @@ function checkEmulatorVersion(version, now = /* @__PURE__ */ new Date()) {
|
|
|
2522
2526
|
if (ageInMonths >= 3) return "warning";
|
|
2523
2527
|
return "ok";
|
|
2524
2528
|
}
|
|
2529
|
+
function emulatorSupportsSearch(version) {
|
|
2530
|
+
if (!version) return false;
|
|
2531
|
+
const coerced = import_semver.default.coerce(version);
|
|
2532
|
+
const minimum = import_semver.default.coerce(MIN_EMULATOR_VERSION_FOR_SEARCH);
|
|
2533
|
+
if (!coerced || !minimum) return false;
|
|
2534
|
+
return import_semver.default.gte(coerced, minimum);
|
|
2535
|
+
}
|
|
2525
2536
|
function getVersionAgeInMonths(year, month, now = /* @__PURE__ */ new Date()) {
|
|
2526
2537
|
const versionDate = new Date(year, month - 1, 1);
|
|
2527
2538
|
return (now.getTime() - versionDate.getTime()) / (1e3 * 60 * 60 * 24 * 30.44);
|
|
@@ -15273,13 +15284,14 @@ function parseIAMEvent(payloadString) {
|
|
|
15273
15284
|
|
|
15274
15285
|
// src/components/cells/status-cell.tsx
|
|
15275
15286
|
var import_jsx_runtime124 = require("react/jsx-runtime");
|
|
15276
|
-
var StatusIcon = ({ errorLevel, spanStatusCode }) => {
|
|
15287
|
+
var StatusIcon = ({ errorLevel, operationStatus, spanStatusCode }) => {
|
|
15277
15288
|
switch (errorLevel) {
|
|
15278
15289
|
case ErrorLevel.ERROR: {
|
|
15279
15290
|
return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.Cancel, { sx: { color: "red" } });
|
|
15280
15291
|
}
|
|
15281
15292
|
case ErrorLevel.IAM_PERMISSION: {
|
|
15282
|
-
|
|
15293
|
+
const isDenial = operationStatus ? operationStatus === "iam_explicit_deny" || operationStatus === "iam_implicit_deny" : spanStatusCode === 2;
|
|
15294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.GppBad, { sx: { color: isDenial ? "red" : "warning.main" } });
|
|
15283
15295
|
}
|
|
15284
15296
|
case ErrorLevel.WARNING: {
|
|
15285
15297
|
return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.Error, { sx: { color: "orange" } });
|
|
@@ -15290,6 +15302,22 @@ var StatusIcon = ({ errorLevel, spanStatusCode }) => {
|
|
|
15290
15302
|
}
|
|
15291
15303
|
};
|
|
15292
15304
|
var calculateHighestErrorLevel = (span) => {
|
|
15305
|
+
if (span.operation_status) {
|
|
15306
|
+
switch (span.operation_status) {
|
|
15307
|
+
case "error": {
|
|
15308
|
+
return ErrorLevel.ERROR;
|
|
15309
|
+
}
|
|
15310
|
+
case "iam_explicit_deny":
|
|
15311
|
+
case "iam_explicit_warn":
|
|
15312
|
+
case "iam_implicit_deny":
|
|
15313
|
+
case "iam_implicit_warn": {
|
|
15314
|
+
return ErrorLevel.IAM_PERMISSION;
|
|
15315
|
+
}
|
|
15316
|
+
default: {
|
|
15317
|
+
return ErrorLevel.OK;
|
|
15318
|
+
}
|
|
15319
|
+
}
|
|
15320
|
+
}
|
|
15293
15321
|
const hasIamDenial = span.events.some((event) => {
|
|
15294
15322
|
if (!event.event_type?.toLowerCase().includes("iam")) return false;
|
|
15295
15323
|
if (typeof event.attributes?.payload !== "string") return false;
|
|
@@ -15333,7 +15361,7 @@ var buildTooltipContent = (span) => {
|
|
|
15333
15361
|
var StatusIconWithTooltip = ({ span }) => {
|
|
15334
15362
|
const errorLevel = calculateHighestErrorLevel(span);
|
|
15335
15363
|
if (errorLevel !== ErrorLevel.ERROR && errorLevel !== ErrorLevel.IAM_PERMISSION) return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_jsx_runtime124.Fragment, {});
|
|
15336
|
-
return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Tooltip, { title: buildTooltipContent(span), children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Box, { sx: { alignItems: "center", cursor: "default", display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StatusIcon, { errorLevel, spanStatusCode: span.status_code }) }) });
|
|
15364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Tooltip, { title: buildTooltipContent(span), children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Box, { sx: { alignItems: "center", cursor: "default", display: "flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StatusIcon, { errorLevel, operationStatus: span.operation_status, spanStatusCode: span.status_code }) }) });
|
|
15337
15365
|
};
|
|
15338
15366
|
|
|
15339
15367
|
// src/components/spans-list/span-count-badge.tsx
|
|
@@ -15357,7 +15385,7 @@ var StatRow = ({ label, value }) => /* @__PURE__ */ (0, import_jsx_runtime125.js
|
|
|
15357
15385
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { color: "text.secondary", sx: { mr: 4 }, variant: "caption", children: label }),
|
|
15358
15386
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { fontWeight: 600, variant: "body2", children: fmtLimit(value) })
|
|
15359
15387
|
] });
|
|
15360
|
-
var SpanCountBadge = ({ licenseLimit, systemLimit, totalCount, visibleCount }) => {
|
|
15388
|
+
var SpanCountBadge = ({ licenseLimit, searchActive = false, systemLimit, totalCount, visibleCount }) => {
|
|
15361
15389
|
const [anchorElement, setAnchorElement] = (0, import_react36.useState)();
|
|
15362
15390
|
const bindingLimit = resolveBindingLimit(systemLimit, licenseLimit);
|
|
15363
15391
|
if (totalCount === void 0 && bindingLimit === void 0) {
|
|
@@ -15372,7 +15400,7 @@ var SpanCountBadge = ({ licenseLimit, systemLimit, totalCount, visibleCount }) =
|
|
|
15372
15400
|
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Skeleton, { sx: { minWidth: 120 } }) : /* @__PURE__ */ (0, import_jsx_runtime125.jsxs)(import_material5.Box, { sx: { alignItems: "baseline", display: "flex", gap: 0.5 }, children: [
|
|
15373
15401
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { color: "text.secondary", variant: "caption", children: "Showing" }),
|
|
15374
15402
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { variant: "body2", children: visibleCount === void 0 ? "\u2014" : fmt(visibleCount) }),
|
|
15375
|
-
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { color: "text.secondary", variant: "caption", children: `of ${totalCount === void 0 ? "-" : fmt(totalCount)} operations` })
|
|
15403
|
+
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Typography, { color: "text.secondary", variant: "caption", children: `of ${totalCount === void 0 ? "-" : fmt(totalCount)} ${searchActive ? "matches" : "operations"}` })
|
|
15376
15404
|
] }),
|
|
15377
15405
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Tooltip, { title: "Operation count details", children: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(
|
|
15378
15406
|
import_material5.IconButton,
|
|
@@ -15411,7 +15439,7 @@ var SpanCountBadge = ({ licenseLimit, systemLimit, totalCount, visibleCount }) =
|
|
|
15411
15439
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(
|
|
15412
15440
|
StatRow,
|
|
15413
15441
|
{
|
|
15414
|
-
label: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Tooltip, { placement: "left", title: "The total number of operations stored on the server.", children: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Box, { component: "span", sx: { borderBottom: "1px dashed", borderColor: "text.secondary", cursor: "help" }, children: "Total stored" }) }),
|
|
15442
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Tooltip, { placement: "left", title: searchActive ? "The total number of operations matching the search." : "The total number of operations stored on the server.", children: /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Box, { component: "span", sx: { borderBottom: "1px dashed", borderColor: "text.secondary", cursor: "help" }, children: searchActive ? "Total matches" : "Total stored" }) }),
|
|
15415
15443
|
value: totalCount
|
|
15416
15444
|
}
|
|
15417
15445
|
)
|
|
@@ -15478,9 +15506,55 @@ var newSpanBackgroundColor = {
|
|
|
15478
15506
|
var LABEL_BEGINNING_OF_STREAM = "This is the beginning of the stream";
|
|
15479
15507
|
var LABEL_END_OF_STREAM = "This is the end of the stream";
|
|
15480
15508
|
var LABEL_NO_SPANS = "There are no operations";
|
|
15509
|
+
var SEARCH_MAX_LENGTH = 512;
|
|
15510
|
+
var SEARCH_DEBOUNCE_MS = 300;
|
|
15481
15511
|
var STICK_TO_EDGE_THRESHOLD_PX = 4;
|
|
15482
15512
|
var StreamBoundaryRow = ({ colSpan, label }) => /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableCell, { colSpan, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)("span", { children: label }) }) });
|
|
15483
15513
|
var LoadingRow = ({ colSpan }) => /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableCell, { colSpan, sx: { textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.CircularProgress, { size: 24, sx: { m: 2 } }) }) });
|
|
15514
|
+
var NoMatchRow = ({
|
|
15515
|
+
colSpan,
|
|
15516
|
+
onClearSearch,
|
|
15517
|
+
term
|
|
15518
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableCell, { colSpan, "data-testid": SPANS_SEARCH_NO_MATCH_TEST_ID, sx: { textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_material6.Box, { sx: { alignItems: "center", display: "flex", flexDirection: "column", gap: 1, py: 3 }, children: [
|
|
15519
|
+
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { sx: { fontStyle: "italic" }, variant: "body2", children: `No operations match \u201C${term}\u201D` }),
|
|
15520
|
+
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Button, { onClick: onClearSearch, size: "small", variant: "text", children: "Clear search" })
|
|
15521
|
+
] }) }) });
|
|
15522
|
+
var SpansSearchField = ({ onChange, onClear, searchSupported, value }) => {
|
|
15523
|
+
const field = /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15524
|
+
import_material6.TextField,
|
|
15525
|
+
{
|
|
15526
|
+
disabled: !searchSupported,
|
|
15527
|
+
inputProps: {
|
|
15528
|
+
"aria-label": "Search operations",
|
|
15529
|
+
"data-testid": SPANS_SEARCH_INPUT_TEST_ID,
|
|
15530
|
+
"maxLength": SEARCH_MAX_LENGTH
|
|
15531
|
+
},
|
|
15532
|
+
InputProps: {
|
|
15533
|
+
endAdornment: value ? /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.InputAdornment, { position: "end", children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15534
|
+
import_material6.IconButton,
|
|
15535
|
+
{
|
|
15536
|
+
"aria-label": "Clear search",
|
|
15537
|
+
"data-testid": SPANS_SEARCH_CLEAR_TEST_ID,
|
|
15538
|
+
edge: "end",
|
|
15539
|
+
onClick: onClear,
|
|
15540
|
+
size: "small",
|
|
15541
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_icons_material3.Close, { sx: { fontSize: 16 } })
|
|
15542
|
+
}
|
|
15543
|
+
) }) : void 0,
|
|
15544
|
+
startAdornment: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.InputAdornment, { position: "start", children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_icons_material3.Search, { sx: { fontSize: 18 } }) })
|
|
15545
|
+
},
|
|
15546
|
+
onChange: (event) => {
|
|
15547
|
+
onChange(event.target.value);
|
|
15548
|
+
},
|
|
15549
|
+
placeholder: "Search operations\u2026",
|
|
15550
|
+
size: "small",
|
|
15551
|
+
sx: { minWidth: 260 },
|
|
15552
|
+
value
|
|
15553
|
+
}
|
|
15554
|
+
);
|
|
15555
|
+
if (searchSupported) return field;
|
|
15556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Tooltip, { title: `Search requires LocalStack \u2265 ${MIN_EMULATOR_VERSION_FOR_SEARCH}`, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)("span", { children: field }) });
|
|
15557
|
+
};
|
|
15484
15558
|
var SpansDataGridRow = (0, import_react37.memo)(
|
|
15485
15559
|
({ isNew, onSpanClick, row }) => {
|
|
15486
15560
|
const theme = (0, import_material6.useTheme)();
|
|
@@ -15548,13 +15622,35 @@ var SpansDataGrid = ({
|
|
|
15548
15622
|
licenseLimit,
|
|
15549
15623
|
onClearSpans,
|
|
15550
15624
|
onOrderChange,
|
|
15625
|
+
onSearchChange,
|
|
15551
15626
|
onSpanClick,
|
|
15552
15627
|
order: order2,
|
|
15628
|
+
search,
|
|
15629
|
+
searching,
|
|
15630
|
+
searchSupported,
|
|
15553
15631
|
spans,
|
|
15554
15632
|
systemLimit,
|
|
15555
15633
|
totalCount,
|
|
15556
15634
|
warningCount
|
|
15557
15635
|
}) => {
|
|
15636
|
+
const searchActive = search.length > 0;
|
|
15637
|
+
const [searchDraft, setSearchDraft] = (0, import_react37.useState)(search);
|
|
15638
|
+
(0, import_react37.useEffect)(() => {
|
|
15639
|
+
const handle = setTimeout(() => {
|
|
15640
|
+
onSearchChange(searchDraft);
|
|
15641
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
15642
|
+
return () => {
|
|
15643
|
+
clearTimeout(handle);
|
|
15644
|
+
};
|
|
15645
|
+
}, [searchDraft, onSearchChange]);
|
|
15646
|
+
const handleClearSearch = (0, import_react37.useCallback)(() => {
|
|
15647
|
+
setSearchDraft("");
|
|
15648
|
+
onSearchChange("");
|
|
15649
|
+
}, [onSearchChange]);
|
|
15650
|
+
const handleClearSpans = (0, import_react37.useCallback)(() => {
|
|
15651
|
+
setSearchDraft("");
|
|
15652
|
+
onClearSpans();
|
|
15653
|
+
}, [onClearSpans]);
|
|
15558
15654
|
const columns = (0, import_react37.useMemo)(() => [
|
|
15559
15655
|
columnHelper.accessor("startTime", {
|
|
15560
15656
|
cell: (props) => /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(ResponsiveTimestampCell, { date: props.getValue() }),
|
|
@@ -15577,7 +15673,13 @@ var SpansDataGrid = ({
|
|
|
15577
15673
|
if (!props.row.original.parent_service_name || !props.row.original.parent_resource_name) {
|
|
15578
15674
|
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { sx: { fontStyle: "italic" }, variant: "body2", children: "External producer" });
|
|
15579
15675
|
}
|
|
15580
|
-
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15677
|
+
ServiceCell,
|
|
15678
|
+
{
|
|
15679
|
+
resource: props.row.original.parent_resource_name,
|
|
15680
|
+
service: props.row.original.parent_service_name
|
|
15681
|
+
}
|
|
15682
|
+
);
|
|
15581
15683
|
},
|
|
15582
15684
|
header: "Producer",
|
|
15583
15685
|
id: "producer",
|
|
@@ -15688,14 +15790,40 @@ var SpansDataGrid = ({
|
|
|
15688
15790
|
}, [order2, spans?.length, lastSpanId]);
|
|
15689
15791
|
return /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15690
15792
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Grid, { item: true, xs: 12, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_material6.Box, { sx: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
|
|
15691
|
-
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15692
|
-
|
|
15793
|
+
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15794
|
+
SpansSearchField,
|
|
15795
|
+
{
|
|
15796
|
+
onChange: setSearchDraft,
|
|
15797
|
+
onClear: handleClearSearch,
|
|
15798
|
+
searchSupported,
|
|
15799
|
+
value: searchDraft
|
|
15800
|
+
}
|
|
15801
|
+
),
|
|
15802
|
+
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15803
|
+
SpanCountBadge,
|
|
15804
|
+
{
|
|
15805
|
+
licenseLimit,
|
|
15806
|
+
searchActive,
|
|
15807
|
+
systemLimit,
|
|
15808
|
+
totalCount,
|
|
15809
|
+
visibleCount: spans?.length
|
|
15810
|
+
}
|
|
15811
|
+
),
|
|
15812
|
+
!searchActive && errorCount !== void 0 && errorCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15693
15813
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "text.disabled", sx: { mr: 0.5 }, variant: "body2", children: "\u2014" }),
|
|
15694
15814
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Tooltip, { title: "Number of errors detected across all operations", children: /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(
|
|
15695
15815
|
import_material6.Box,
|
|
15696
15816
|
{
|
|
15697
15817
|
"data-testid": ERROR_COUNT_TEST_ID,
|
|
15698
|
-
sx: {
|
|
15818
|
+
sx: {
|
|
15819
|
+
alignItems: "center",
|
|
15820
|
+
borderBottom: "1px dotted",
|
|
15821
|
+
borderColor: "error.main",
|
|
15822
|
+
cursor: "help",
|
|
15823
|
+
display: "flex",
|
|
15824
|
+
gap: 0.5,
|
|
15825
|
+
mb: "-1px"
|
|
15826
|
+
},
|
|
15699
15827
|
children: [
|
|
15700
15828
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "error", variant: "body2", children: errorCount.toLocaleString() }),
|
|
15701
15829
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "error", variant: "caption", children: errorCount === 1 ? "error" : "errors" })
|
|
@@ -15703,13 +15831,21 @@ var SpansDataGrid = ({
|
|
|
15703
15831
|
}
|
|
15704
15832
|
) })
|
|
15705
15833
|
] }),
|
|
15706
|
-
warningCount !== void 0 && warningCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15834
|
+
!searchActive && warningCount !== void 0 && warningCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15707
15835
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "text.disabled", sx: { mr: 0.5 }, variant: "body2", children: "\u2014" }),
|
|
15708
15836
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Tooltip, { title: "Number of warnings detected across all operations", children: /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(
|
|
15709
15837
|
import_material6.Box,
|
|
15710
15838
|
{
|
|
15711
15839
|
"data-testid": WARNING_COUNT_TEST_ID,
|
|
15712
|
-
sx: {
|
|
15840
|
+
sx: {
|
|
15841
|
+
alignItems: "center",
|
|
15842
|
+
borderBottom: "1px dotted",
|
|
15843
|
+
borderColor: "warning.main",
|
|
15844
|
+
cursor: "help",
|
|
15845
|
+
display: "flex",
|
|
15846
|
+
gap: 0.5,
|
|
15847
|
+
mb: "-1px"
|
|
15848
|
+
},
|
|
15713
15849
|
children: [
|
|
15714
15850
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "warning.main", variant: "body2", children: warningCount.toLocaleString() }),
|
|
15715
15851
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.Typography, { color: "warning.main", variant: "caption", children: warningCount === 1 ? "warning" : "warnings" })
|
|
@@ -15725,7 +15861,7 @@ var SpansDataGrid = ({
|
|
|
15725
15861
|
import_material6.Button,
|
|
15726
15862
|
{
|
|
15727
15863
|
"data-testid": CLEAR_SPANS_TEST_ID,
|
|
15728
|
-
onClick:
|
|
15864
|
+
onClick: handleClearSpans,
|
|
15729
15865
|
startIcon: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_icons_material3.DeleteForeverOutlined, {}),
|
|
15730
15866
|
children: "Clear Operations"
|
|
15731
15867
|
}
|
|
@@ -15778,31 +15914,71 @@ var SpansDataGrid = ({
|
|
|
15778
15914
|
)) }, headerGroup.id);
|
|
15779
15915
|
}) }),
|
|
15780
15916
|
/* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_material6.TableBody, { children: [
|
|
15781
|
-
(spans === void 0 || clearingSpans) && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.CircularProgress, { size: 48, sx: { m: 4 } }) }) }),
|
|
15782
|
-
!clearingSpans && spans?.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_NO_SPANS }),
|
|
15917
|
+
(spans === void 0 || clearingSpans || searching) && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.CircularProgress, { size: 48, sx: { m: 4 } }) }) }),
|
|
15918
|
+
!clearingSpans && !searching && spans?.length === 0 && (searchActive ? /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(NoMatchRow, { colSpan: columnCount, onClearSearch: handleClearSearch, term: search }) : /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_NO_SPANS })),
|
|
15783
15919
|
!clearingSpans && order2 === "newest_first" && /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15784
15920
|
hasRows && hasMoreForward && fetchingForward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(LoadingRow, { colSpan: columnCount }),
|
|
15785
15921
|
hasRows && !hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM }),
|
|
15786
|
-
hasRows && paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15922
|
+
hasRows && paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15923
|
+
import_material6.TableCell,
|
|
15924
|
+
{
|
|
15925
|
+
colSpan: columnCount,
|
|
15926
|
+
sx: { border: 0, height: paddingTop, p: 0 }
|
|
15927
|
+
}
|
|
15928
|
+
) }),
|
|
15787
15929
|
hasRows && virtualItems.map((virtualItem) => {
|
|
15788
15930
|
const row = displayRows[virtualItem.index];
|
|
15789
15931
|
const isNew = !(seenSpanIdsRef.current?.has(row.original.span_id) ?? false);
|
|
15790
|
-
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15933
|
+
SpansDataGridRow,
|
|
15934
|
+
{
|
|
15935
|
+
isNew,
|
|
15936
|
+
onSpanClick,
|
|
15937
|
+
row
|
|
15938
|
+
},
|
|
15939
|
+
row.original.span_id
|
|
15940
|
+
);
|
|
15791
15941
|
}),
|
|
15792
|
-
hasRows && paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15942
|
+
hasRows && paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15943
|
+
import_material6.TableCell,
|
|
15944
|
+
{
|
|
15945
|
+
colSpan: columnCount,
|
|
15946
|
+
sx: { border: 0, height: paddingBottom, p: 0 }
|
|
15947
|
+
}
|
|
15948
|
+
) }),
|
|
15793
15949
|
hasRows && hasMoreBackward && fetchingBackward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(LoadingRow, { colSpan: columnCount }),
|
|
15794
15950
|
hasRows && !hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM })
|
|
15795
15951
|
] }),
|
|
15796
15952
|
!clearingSpans && order2 === "oldest_first" && /* @__PURE__ */ (0, import_jsx_runtime126.jsxs)(import_jsx_runtime126.Fragment, { children: [
|
|
15797
15953
|
hasRows && !hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM }),
|
|
15798
15954
|
hasRows && hasMoreBackward && fetchingBackward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(LoadingRow, { colSpan: columnCount }),
|
|
15799
|
-
hasRows && paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15955
|
+
hasRows && paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15956
|
+
import_material6.TableCell,
|
|
15957
|
+
{
|
|
15958
|
+
colSpan: columnCount,
|
|
15959
|
+
sx: { border: 0, height: paddingTop, p: 0 }
|
|
15960
|
+
}
|
|
15961
|
+
) }),
|
|
15800
15962
|
hasRows && virtualItems.map((virtualItem) => {
|
|
15801
15963
|
const row = displayRows[virtualItem.index];
|
|
15802
15964
|
const isNew = !(seenSpanIdsRef.current?.has(row.original.span_id) ?? false);
|
|
15803
|
-
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15966
|
+
SpansDataGridRow,
|
|
15967
|
+
{
|
|
15968
|
+
isNew,
|
|
15969
|
+
onSpanClick,
|
|
15970
|
+
row
|
|
15971
|
+
},
|
|
15972
|
+
row.original.span_id
|
|
15973
|
+
);
|
|
15804
15974
|
}),
|
|
15805
|
-
hasRows && paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15975
|
+
hasRows && paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_material6.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(
|
|
15976
|
+
import_material6.TableCell,
|
|
15977
|
+
{
|
|
15978
|
+
colSpan: columnCount,
|
|
15979
|
+
sx: { border: 0, height: paddingBottom, p: 0 }
|
|
15980
|
+
}
|
|
15981
|
+
) }),
|
|
15806
15982
|
hasRows && hasMoreForward && fetchingForward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(LoadingRow, { colSpan: columnCount }),
|
|
15807
15983
|
hasRows && !hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM })
|
|
15808
15984
|
] })
|
|
@@ -15843,8 +16019,12 @@ var SpansList = (props) => {
|
|
|
15843
16019
|
licenseLimit: props.licenseLimit,
|
|
15844
16020
|
onClearSpans: props.onClearSpans,
|
|
15845
16021
|
onOrderChange: props.onOrderChange,
|
|
16022
|
+
onSearchChange: props.onSearchChange,
|
|
15846
16023
|
onSpanClick: props.onSpanClick,
|
|
15847
16024
|
order: props.order,
|
|
16025
|
+
search: props.search,
|
|
16026
|
+
searching: props.searching,
|
|
16027
|
+
searchSupported: props.searchSupported,
|
|
15848
16028
|
spans: props.spans,
|
|
15849
16029
|
systemLimit: props.systemLimit,
|
|
15850
16030
|
totalCount: props.totalCount,
|
|
@@ -16255,6 +16435,7 @@ var createPaginationBuffer = (options) => {
|
|
|
16255
16435
|
let hasMoreBackward = void 0;
|
|
16256
16436
|
let fetchingForward = false;
|
|
16257
16437
|
let fetchingBackward = false;
|
|
16438
|
+
let abortController;
|
|
16258
16439
|
const reportDataChange = () => {
|
|
16259
16440
|
options.onDataChange({
|
|
16260
16441
|
hasMoreBackward: hasMoreBackward ?? false,
|
|
@@ -16278,25 +16459,40 @@ var createPaginationBuffer = (options) => {
|
|
|
16278
16459
|
if (hasMoreForward === true) {
|
|
16279
16460
|
return;
|
|
16280
16461
|
}
|
|
16462
|
+
const controller = new AbortController();
|
|
16463
|
+
abortController = controller;
|
|
16281
16464
|
fetchingForward = true;
|
|
16282
16465
|
reportStatusChange();
|
|
16283
16466
|
try {
|
|
16284
|
-
const newPage = await fetchPage(nextForwardToken);
|
|
16467
|
+
const newPage = await fetchPage(nextForwardToken, controller.signal);
|
|
16468
|
+
if (controller.signal.aborted) {
|
|
16469
|
+
return;
|
|
16470
|
+
}
|
|
16285
16471
|
hasMoreForward = newPage.items.length > 0;
|
|
16286
16472
|
reportDataChange();
|
|
16287
16473
|
} catch (error) {
|
|
16474
|
+
if (controller.signal.aborted) {
|
|
16475
|
+
return;
|
|
16476
|
+
}
|
|
16288
16477
|
reportError(error instanceof Error ? error : new Error("Failed to fetch forward page", { cause: error }));
|
|
16289
16478
|
} finally {
|
|
16290
|
-
|
|
16291
|
-
|
|
16479
|
+
if (!controller.signal.aborted) {
|
|
16480
|
+
fetchingForward = false;
|
|
16481
|
+
reportStatusChange();
|
|
16482
|
+
runPostFetchActions();
|
|
16483
|
+
}
|
|
16292
16484
|
}
|
|
16293
|
-
runPostFetchActions();
|
|
16294
16485
|
};
|
|
16295
16486
|
const fetchForward = async () => {
|
|
16487
|
+
const controller = new AbortController();
|
|
16488
|
+
abortController = controller;
|
|
16296
16489
|
fetchingForward = true;
|
|
16297
16490
|
reportStatusChange();
|
|
16298
16491
|
try {
|
|
16299
|
-
const newPage = await fetchPage(nextForwardToken);
|
|
16492
|
+
const newPage = await fetchPage(nextForwardToken, controller.signal);
|
|
16493
|
+
if (controller.signal.aborted) {
|
|
16494
|
+
return;
|
|
16495
|
+
}
|
|
16300
16496
|
if (options.sortComparator === void 0) {
|
|
16301
16497
|
items = [...items ?? [], ...newPage.items];
|
|
16302
16498
|
} else {
|
|
@@ -16312,18 +16508,28 @@ var createPaginationBuffer = (options) => {
|
|
|
16312
16508
|
nextBackwardToken ??= newPage.nextBackwardToken;
|
|
16313
16509
|
reportDataChange();
|
|
16314
16510
|
} catch (error) {
|
|
16511
|
+
if (controller.signal.aborted) {
|
|
16512
|
+
return;
|
|
16513
|
+
}
|
|
16315
16514
|
reportError(error instanceof Error ? error : new Error("Failed to fetch forward page", { cause: error }));
|
|
16316
16515
|
} finally {
|
|
16317
|
-
|
|
16318
|
-
|
|
16516
|
+
if (!controller.signal.aborted) {
|
|
16517
|
+
fetchingForward = false;
|
|
16518
|
+
reportStatusChange();
|
|
16519
|
+
runPostFetchActions();
|
|
16520
|
+
}
|
|
16319
16521
|
}
|
|
16320
|
-
runPostFetchActions();
|
|
16321
16522
|
};
|
|
16322
16523
|
const fetchBackward = async () => {
|
|
16524
|
+
const controller = new AbortController();
|
|
16525
|
+
abortController = controller;
|
|
16323
16526
|
fetchingBackward = true;
|
|
16324
16527
|
reportStatusChange();
|
|
16325
16528
|
try {
|
|
16326
|
-
const newPage = await fetchPage(nextBackwardToken);
|
|
16529
|
+
const newPage = await fetchPage(nextBackwardToken, controller.signal);
|
|
16530
|
+
if (controller.signal.aborted) {
|
|
16531
|
+
return;
|
|
16532
|
+
}
|
|
16327
16533
|
if (options.sortComparator === void 0) {
|
|
16328
16534
|
items = [...newPage.items, ...items ?? []];
|
|
16329
16535
|
} else {
|
|
@@ -16339,12 +16545,17 @@ var createPaginationBuffer = (options) => {
|
|
|
16339
16545
|
nextForwardToken ??= newPage.nextForwardToken;
|
|
16340
16546
|
reportDataChange();
|
|
16341
16547
|
} catch (error) {
|
|
16548
|
+
if (controller.signal.aborted) {
|
|
16549
|
+
return;
|
|
16550
|
+
}
|
|
16342
16551
|
reportError(error instanceof Error ? error : new Error("Failed to fetch forward page", { cause: error }));
|
|
16343
16552
|
} finally {
|
|
16344
|
-
|
|
16345
|
-
|
|
16553
|
+
if (!controller.signal.aborted) {
|
|
16554
|
+
fetchingBackward = false;
|
|
16555
|
+
reportStatusChange();
|
|
16556
|
+
runPostFetchActions();
|
|
16557
|
+
}
|
|
16346
16558
|
}
|
|
16347
|
-
runPostFetchActions();
|
|
16348
16559
|
};
|
|
16349
16560
|
const runPostFetchActions = () => {
|
|
16350
16561
|
if (fetchBackwardLater) {
|
|
@@ -16369,11 +16580,16 @@ var createPaginationBuffer = (options) => {
|
|
|
16369
16580
|
void checkIfThereAreMoreItemsForward();
|
|
16370
16581
|
},
|
|
16371
16582
|
clear: () => {
|
|
16583
|
+
abortController?.abort();
|
|
16584
|
+
abortController = void 0;
|
|
16585
|
+
fetchingForward = false;
|
|
16586
|
+
fetchingBackward = false;
|
|
16372
16587
|
items = [];
|
|
16373
16588
|
hasMoreBackward = void 0;
|
|
16374
16589
|
nextBackwardToken = void 0;
|
|
16375
16590
|
hasMoreForward = void 0;
|
|
16376
16591
|
nextForwardToken = void 0;
|
|
16592
|
+
reportStatusChange();
|
|
16377
16593
|
reportDataChange();
|
|
16378
16594
|
},
|
|
16379
16595
|
fetchBackward: async () => {
|
|
@@ -16609,9 +16825,9 @@ var createApiClient = ({ localstackEndpoint }) => {
|
|
|
16609
16825
|
const endpoint = buildEventsEndpoint(iamEventsRequest);
|
|
16610
16826
|
return makeRequest({ endpoint, localstackEndpoint });
|
|
16611
16827
|
},
|
|
16612
|
-
getSpans: async (request) => {
|
|
16828
|
+
getSpans: async (request, options) => {
|
|
16613
16829
|
const endpoint = buildSpansEndpoint(request);
|
|
16614
|
-
const response = await makeRequest({ endpoint, localstackEndpoint });
|
|
16830
|
+
const response = await makeRequest({ endpoint, localstackEndpoint, request: { signal: options?.signal } });
|
|
16615
16831
|
return {
|
|
16616
16832
|
...response,
|
|
16617
16833
|
spans: response.spans.map((span) => ({
|
|
@@ -18701,45 +18917,11 @@ var useSpans = () => {
|
|
|
18701
18917
|
const [fetchError, setFetchError] = (0, import_react46.useState)();
|
|
18702
18918
|
const [fetchingForward, setFetchingForward] = (0, import_react46.useState)(false);
|
|
18703
18919
|
const [fetchingBackward, setFetchingBackward] = (0, import_react46.useState)(false);
|
|
18704
|
-
const
|
|
18705
|
-
|
|
18706
|
-
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
});
|
|
18710
|
-
setTotalCount(response.pagination.total_count);
|
|
18711
|
-
setLicenseLimit(response.limits.span_count_limit_license);
|
|
18712
|
-
setSystemLimit(response.limits.span_count_limit_system);
|
|
18713
|
-
setErrorCount(response.error_count);
|
|
18714
|
-
setWarningCount(response.warning_count);
|
|
18715
|
-
return {
|
|
18716
|
-
hasMoreBackward: response.pagination.has_prev,
|
|
18717
|
-
hasMoreForward: response.pagination.has_next,
|
|
18718
|
-
items: response.spans,
|
|
18719
|
-
nextBackwardToken: response.pagination.prev_cursor ?? void 0,
|
|
18720
|
-
nextForwardToken: response.pagination.next_cursor ?? void 0
|
|
18721
|
-
};
|
|
18722
|
-
},
|
|
18723
|
-
onDataChange: ({ hasMoreBackward: hasMoreBackward2, hasMoreForward: hasMoreForward2, items }) => {
|
|
18724
|
-
setFetchError(void 0);
|
|
18725
|
-
setSpans(items);
|
|
18726
|
-
setHasMoreBackward(hasMoreBackward2);
|
|
18727
|
-
setHasMoreForward(hasMoreForward2);
|
|
18728
|
-
},
|
|
18729
|
-
onError: (error) => {
|
|
18730
|
-
setFetchError(error);
|
|
18731
|
-
},
|
|
18732
|
-
onStatusChange(status) {
|
|
18733
|
-
setFetchingBackward(status.fetchingBackward);
|
|
18734
|
-
setFetchingForward(status.fetchingForward);
|
|
18735
|
-
},
|
|
18736
|
-
// The spans endpoint is sorted by span ingestion time, which might differ from
|
|
18737
|
-
// the span timestamp. In order to accomodate for this, we will sort the spans
|
|
18738
|
-
// in the frontend with the following sort comparator.
|
|
18739
|
-
sortComparator(a3, b3) {
|
|
18740
|
-
return a3.start_time_unix_nano < b3.start_time_unix_nano ? -1 : 1;
|
|
18741
|
-
}
|
|
18742
|
-
}));
|
|
18920
|
+
const [search, setSearch] = (0, import_react46.useState)("");
|
|
18921
|
+
const searchRef = (0, import_react46.useRef)("");
|
|
18922
|
+
const [searching, setSearching] = (0, import_react46.useState)(false);
|
|
18923
|
+
const searchSeqRef = (0, import_react46.useRef)(0);
|
|
18924
|
+
const paginationBufferRef = (0, import_react46.useRef)();
|
|
18743
18925
|
const [totalCount, setTotalCount] = (0, import_react46.useState)();
|
|
18744
18926
|
const [licenseLimit, setLicenseLimit] = (0, import_react46.useState)();
|
|
18745
18927
|
const [systemLimit, setSystemLimit] = (0, import_react46.useState)();
|
|
@@ -18748,14 +18930,71 @@ var useSpans = () => {
|
|
|
18748
18930
|
const [hasMoreBackward, setHasMoreBackward] = (0, import_react46.useState)();
|
|
18749
18931
|
const [hasMoreForward, setHasMoreForward] = (0, import_react46.useState)();
|
|
18750
18932
|
const fetchForward = (0, import_react46.useCallback)(() => {
|
|
18751
|
-
void paginationBufferRef.current
|
|
18933
|
+
void paginationBufferRef.current?.fetchForward();
|
|
18752
18934
|
}, []);
|
|
18753
18935
|
const fetchBackward = (0, import_react46.useCallback)(() => {
|
|
18754
|
-
void paginationBufferRef.current
|
|
18936
|
+
void paginationBufferRef.current?.fetchBackward();
|
|
18937
|
+
}, []);
|
|
18938
|
+
const applySearch = (0, import_react46.useCallback)((term) => {
|
|
18939
|
+
const normalized = term.trim();
|
|
18940
|
+
if (normalized === searchRef.current) {
|
|
18941
|
+
return;
|
|
18942
|
+
}
|
|
18943
|
+
searchRef.current = normalized;
|
|
18944
|
+
setSearch(normalized);
|
|
18945
|
+
const seq = ++searchSeqRef.current;
|
|
18946
|
+
setSearching(true);
|
|
18947
|
+
paginationBufferRef.current?.clear();
|
|
18948
|
+
void paginationBufferRef.current?.fetchForward().finally(() => {
|
|
18949
|
+
if (searchSeqRef.current === seq) {
|
|
18950
|
+
setSearching(false);
|
|
18951
|
+
}
|
|
18952
|
+
});
|
|
18755
18953
|
}, []);
|
|
18756
18954
|
(0, import_react46.useEffect)(() => {
|
|
18757
|
-
|
|
18758
|
-
|
|
18955
|
+
const buffer = createPaginationBuffer({
|
|
18956
|
+
async fetchPage(token, signal) {
|
|
18957
|
+
const response = await api.getSpans({
|
|
18958
|
+
limit: PAGE_SIZE,
|
|
18959
|
+
pagination_token: token,
|
|
18960
|
+
search: searchRef.current || void 0
|
|
18961
|
+
}, { signal });
|
|
18962
|
+
setTotalCount(response.pagination.total_count);
|
|
18963
|
+
setLicenseLimit(response.limits.span_count_limit_license);
|
|
18964
|
+
setSystemLimit(response.limits.span_count_limit_system);
|
|
18965
|
+
setErrorCount(response.error_count);
|
|
18966
|
+
setWarningCount(response.warning_count);
|
|
18967
|
+
return {
|
|
18968
|
+
hasMoreBackward: response.pagination.has_prev,
|
|
18969
|
+
hasMoreForward: response.pagination.has_next,
|
|
18970
|
+
items: response.spans,
|
|
18971
|
+
nextBackwardToken: response.pagination.prev_cursor ?? void 0,
|
|
18972
|
+
nextForwardToken: response.pagination.next_cursor ?? void 0
|
|
18973
|
+
};
|
|
18974
|
+
},
|
|
18975
|
+
onDataChange: ({ hasMoreBackward: hasMoreBackward2, hasMoreForward: hasMoreForward2, items }) => {
|
|
18976
|
+
setFetchError(void 0);
|
|
18977
|
+
setSpans(items);
|
|
18978
|
+
setHasMoreBackward(hasMoreBackward2);
|
|
18979
|
+
setHasMoreForward(hasMoreForward2);
|
|
18980
|
+
},
|
|
18981
|
+
onError: (error) => {
|
|
18982
|
+
setFetchError(error);
|
|
18983
|
+
},
|
|
18984
|
+
onStatusChange(status) {
|
|
18985
|
+
setFetchingBackward(status.fetchingBackward);
|
|
18986
|
+
setFetchingForward(status.fetchingForward);
|
|
18987
|
+
},
|
|
18988
|
+
// The spans endpoint is sorted by span ingestion time, which might differ from
|
|
18989
|
+
// the span timestamp. In order to accomodate for this, we will sort the spans
|
|
18990
|
+
// in the frontend with the following sort comparator.
|
|
18991
|
+
sortComparator(a3, b3) {
|
|
18992
|
+
return a3.start_time_unix_nano < b3.start_time_unix_nano ? -1 : 1;
|
|
18993
|
+
}
|
|
18994
|
+
});
|
|
18995
|
+
paginationBufferRef.current = buffer;
|
|
18996
|
+
void buffer.fetchForward();
|
|
18997
|
+
}, [api]);
|
|
18759
18998
|
const [clearingSpans, setClearingSpans] = (0, import_react46.useState)(false);
|
|
18760
18999
|
const clearSpans = (0, import_react46.useCallback)(async () => {
|
|
18761
19000
|
if (clearingSpans) {
|
|
@@ -18765,8 +19004,11 @@ var useSpans = () => {
|
|
|
18765
19004
|
try {
|
|
18766
19005
|
await api.deleteSpans();
|
|
18767
19006
|
setTotalCount(void 0);
|
|
18768
|
-
|
|
18769
|
-
|
|
19007
|
+
searchRef.current = "";
|
|
19008
|
+
setSearch("");
|
|
19009
|
+
setSearching(false);
|
|
19010
|
+
paginationBufferRef.current?.clear();
|
|
19011
|
+
await paginationBufferRef.current?.fetchForward();
|
|
18770
19012
|
} catch (error) {
|
|
18771
19013
|
console.error("Failed to delete spans:", error);
|
|
18772
19014
|
setFetchError(error instanceof Error ? error : new Error("Failed to delete spans", { cause: error }));
|
|
@@ -18776,12 +19018,12 @@ var useSpans = () => {
|
|
|
18776
19018
|
}, [clearingSpans, api]);
|
|
18777
19019
|
(0, import_react46.useEffect)(() => {
|
|
18778
19020
|
if (hasMoreForward === true && !fetchingForward) {
|
|
18779
|
-
void paginationBufferRef.current
|
|
19021
|
+
void paginationBufferRef.current?.fetchForward();
|
|
18780
19022
|
}
|
|
18781
19023
|
}, [hasMoreForward, fetchingForward]);
|
|
18782
19024
|
(0, import_react46.useEffect)(() => {
|
|
18783
19025
|
if (hasMoreBackward === true && !fetchingBackward && !fetchingForward) {
|
|
18784
|
-
void paginationBufferRef.current
|
|
19026
|
+
void paginationBufferRef.current?.fetchBackward();
|
|
18785
19027
|
}
|
|
18786
19028
|
}, [hasMoreBackward, fetchingBackward, fetchingForward]);
|
|
18787
19029
|
useSpansWebSocket({
|
|
@@ -18792,7 +19034,7 @@ var useSpans = () => {
|
|
|
18792
19034
|
return;
|
|
18793
19035
|
}
|
|
18794
19036
|
if (!hasMoreForward) {
|
|
18795
|
-
void paginationBufferRef.current
|
|
19037
|
+
void paginationBufferRef.current?.fetchForward();
|
|
18796
19038
|
}
|
|
18797
19039
|
},
|
|
18798
19040
|
onOpen: () => {
|
|
@@ -18816,6 +19058,9 @@ var useSpans = () => {
|
|
|
18816
19058
|
hasMoreBackward,
|
|
18817
19059
|
hasMoreForward,
|
|
18818
19060
|
licenseLimit,
|
|
19061
|
+
search,
|
|
19062
|
+
searching,
|
|
19063
|
+
setSearch: applySearch,
|
|
18819
19064
|
spans,
|
|
18820
19065
|
systemLimit,
|
|
18821
19066
|
totalCount,
|
|
@@ -19816,7 +20061,7 @@ var AddBox = "M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.
|
|
|
19816
20061
|
var Check2 = "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z";
|
|
19817
20062
|
var ChevronRight = "M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z";
|
|
19818
20063
|
var CircularArrows = "M 12 2 C 10.615 1.998 9.214625 2.2867656 7.890625 2.8847656 L 8.9003906 4.6328125 C 9.9043906 4.2098125 10.957 3.998 12 4 C 15.080783 4 17.738521 5.7633175 19.074219 8.3222656 L 17.125 9 L 21.25 11 L 22.875 7 L 20.998047 7.6523438 C 19.377701 4.3110398 15.95585 2 12 2 z M 6.5097656 4.4882812 L 2.2324219 5.0820312 L 3.734375 6.3808594 C 1.6515335 9.4550558 1.3615962 13.574578 3.3398438 17 C 4.0308437 18.201 4.9801562 19.268234 6.1601562 20.115234 L 7.1699219 18.367188 C 6.3019219 17.710187 5.5922656 16.904 5.0722656 16 C 3.5320014 13.332354 3.729203 10.148679 5.2773438 7.7128906 L 6.8398438 9.0625 L 6.5097656 4.4882812 z M 19.929688 13 C 19.794687 14.08 19.450734 15.098 18.927734 16 C 17.386985 18.668487 14.531361 20.090637 11.646484 19.966797 L 12.035156 17.9375 L 8.2402344 20.511719 L 10.892578 23.917969 L 11.265625 21.966797 C 14.968963 22.233766 18.681899 20.426323 20.660156 17 C 21.355156 15.801 21.805219 14.445 21.949219 13 L 19.929688 13 z";
|
|
19819
|
-
var
|
|
20064
|
+
var Close2 = "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z";
|
|
19820
20065
|
var ContentCopy2 = "M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z";
|
|
19821
20066
|
var Edit = "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z";
|
|
19822
20067
|
var ExpandMore = "M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z";
|
|
@@ -19847,7 +20092,7 @@ var CircularArrowsIcon = (props) => {
|
|
|
19847
20092
|
};
|
|
19848
20093
|
var CloseIcon = (props) => {
|
|
19849
20094
|
return /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(BaseIcon, {
|
|
19850
|
-
d:
|
|
20095
|
+
d: Close2,
|
|
19851
20096
|
...props
|
|
19852
20097
|
});
|
|
19853
20098
|
};
|
|
@@ -31532,14 +31777,16 @@ var ServiceNode = (0, import_react56.memo)(({ data, selected }) => {
|
|
|
31532
31777
|
const theme = (0, import_material19.useTheme)();
|
|
31533
31778
|
const [isHovered, setIsHovered] = (0, import_react56.useState)(false);
|
|
31534
31779
|
const nodeRef = (0, import_react56.useRef)(null);
|
|
31535
|
-
const
|
|
31536
|
-
const
|
|
31780
|
+
const { operation_status } = data.event;
|
|
31781
|
+
const hasPermissionEventsLegacy = (0, import_react56.useMemo)(
|
|
31537
31782
|
() => data.event.events.some(
|
|
31538
31783
|
(event) => event.event_type === "iam.policy_evaluation" && event.name === "iam.policy.denied"
|
|
31539
31784
|
),
|
|
31540
31785
|
[data.event.events]
|
|
31541
31786
|
);
|
|
31542
|
-
const
|
|
31787
|
+
const isError = operation_status ? operation_status === "error" || operation_status === "iam_explicit_deny" || operation_status === "iam_implicit_deny" : data.event.status_code === 2;
|
|
31788
|
+
const isWarning = operation_status ? operation_status === "iam_explicit_warn" || operation_status === "iam_implicit_warn" : !isError && data.event.status_code === 1 && hasPermissionEventsLegacy;
|
|
31789
|
+
const hasPermissionEvents = operation_status ? operation_status.startsWith("iam_") : hasPermissionEventsLegacy;
|
|
31543
31790
|
const outlineColor = isError ? theme.palette.error.main : isWarning ? theme.palette.warning.main : void 0;
|
|
31544
31791
|
const sharedBoxSx = {
|
|
31545
31792
|
backgroundColor: theme.palette.background.paper,
|
|
@@ -32095,6 +32342,9 @@ var SpansListPage = () => {
|
|
|
32095
32342
|
hasMoreBackward,
|
|
32096
32343
|
hasMoreForward,
|
|
32097
32344
|
licenseLimit,
|
|
32345
|
+
search,
|
|
32346
|
+
searching,
|
|
32347
|
+
setSearch,
|
|
32098
32348
|
spans,
|
|
32099
32349
|
systemLimit,
|
|
32100
32350
|
totalCount,
|
|
@@ -32106,6 +32356,7 @@ var SpansListPage = () => {
|
|
|
32106
32356
|
}, [clearSpans]);
|
|
32107
32357
|
const localstackVersion = status?.localstackVersion ?? (statusError instanceof AppInspectorNotFoundError ? statusError.localstackVersion : void 0);
|
|
32108
32358
|
const versionCompatibility = checkEmulatorVersion(localstackVersion);
|
|
32359
|
+
const searchSupported = emulatorSupportsSearch(localstackVersion);
|
|
32109
32360
|
const [bannerDismissed, setBannerDismissed] = (0, import_react63.useState)(false);
|
|
32110
32361
|
const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
|
|
32111
32362
|
const [selectedTraceId, setSelectedTraceId] = (0, import_react63.useState)();
|
|
@@ -32222,8 +32473,12 @@ var SpansListPage = () => {
|
|
|
32222
32473
|
onClearSpans: clearSpansSync,
|
|
32223
32474
|
onFetchForward: fetchForward,
|
|
32224
32475
|
onOrderChange: setOrder,
|
|
32476
|
+
onSearchChange: setSearch,
|
|
32225
32477
|
onSpanClick: navigateToSpan,
|
|
32226
32478
|
order: order2,
|
|
32479
|
+
search,
|
|
32480
|
+
searching,
|
|
32481
|
+
searchSupported,
|
|
32227
32482
|
spans,
|
|
32228
32483
|
systemLimit,
|
|
32229
32484
|
totalCount,
|