@localstack/appinspector-ui 1.0.29 → 1.0.31
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 +140 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +87 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/pages/spans-list-page.tsx
|
|
2
2
|
import { Box as Box7 } from "@mui/material";
|
|
3
|
-
import { useCallback as
|
|
3
|
+
import { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo5, useRef as useRef3, useState as useState5 } from "react";
|
|
4
4
|
import { useNavigate } from "react-router-dom";
|
|
5
5
|
|
|
6
6
|
// src/api/use-api.tsx
|
|
@@ -3476,6 +3476,28 @@ var useStatus = () => {
|
|
|
3476
3476
|
return { checking, checkStatus, error, status };
|
|
3477
3477
|
};
|
|
3478
3478
|
|
|
3479
|
+
// src/utils/use-search-param-codec.ts
|
|
3480
|
+
import { useCallback as useCallback5, useMemo as useMemo4 } from "react";
|
|
3481
|
+
import { useSearchParams } from "react-router-dom";
|
|
3482
|
+
var useSearchParamCodec = (key, codec) => {
|
|
3483
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
3484
|
+
const raw = searchParams.get(key) ?? void 0;
|
|
3485
|
+
const value = useMemo4(() => {
|
|
3486
|
+
return codec.decode(raw);
|
|
3487
|
+
}, [raw, codec]);
|
|
3488
|
+
const setValue = useCallback5(
|
|
3489
|
+
(next) => {
|
|
3490
|
+
setSearchParams((previous) => {
|
|
3491
|
+
const nextParams = new URLSearchParams(previous);
|
|
3492
|
+
nextParams.set(key, codec.encode(next));
|
|
3493
|
+
return nextParams;
|
|
3494
|
+
});
|
|
3495
|
+
},
|
|
3496
|
+
[key, codec, setSearchParams]
|
|
3497
|
+
);
|
|
3498
|
+
return [value, setValue];
|
|
3499
|
+
};
|
|
3500
|
+
|
|
3479
3501
|
// src/pages/spans-list-page.tsx
|
|
3480
3502
|
import { jsx as jsx130 } from "react/jsx-runtime";
|
|
3481
3503
|
var spansPerPageOptions = [25, 50, 100];
|
|
@@ -3486,10 +3508,30 @@ var SpansListPage = () => {
|
|
|
3486
3508
|
const hasFetched = useRef3(false);
|
|
3487
3509
|
const [filterWriteOperations, setFilterWriteOperations] = useLocalStorage("filterWriteOperations", true);
|
|
3488
3510
|
const mapPageToNextCursor = useRef3({});
|
|
3489
|
-
const [page, setPage] =
|
|
3490
|
-
|
|
3511
|
+
const [page, setPage] = useSearchParamCodec("page", {
|
|
3512
|
+
decode: (raw) => {
|
|
3513
|
+
const defaultPage = 0;
|
|
3514
|
+
if (!raw) {
|
|
3515
|
+
return defaultPage;
|
|
3516
|
+
}
|
|
3517
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3518
|
+
return Number.isNaN(parsed) || parsed < 0 ? defaultPage : parsed;
|
|
3519
|
+
},
|
|
3520
|
+
encode: (value) => value.toString()
|
|
3521
|
+
});
|
|
3522
|
+
const [pageSize, setPageSize] = useSearchParamCodec("pageSize", {
|
|
3523
|
+
decode: (raw) => {
|
|
3524
|
+
const defaultPageSize = 100;
|
|
3525
|
+
if (!raw) {
|
|
3526
|
+
return defaultPageSize;
|
|
3527
|
+
}
|
|
3528
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3529
|
+
return spansPerPageOptions.includes(parsed) ? parsed : defaultPageSize;
|
|
3530
|
+
},
|
|
3531
|
+
encode: (value) => value.toString()
|
|
3532
|
+
});
|
|
3491
3533
|
const [spanCount, setSpanCount] = useState5(0);
|
|
3492
|
-
const queryOptions =
|
|
3534
|
+
const queryOptions = useMemo5(() => {
|
|
3493
3535
|
return {
|
|
3494
3536
|
is_write_operation: filterWriteOperations ? true : void 0,
|
|
3495
3537
|
limit: pageSize,
|
|
@@ -3498,7 +3540,7 @@ var SpansListPage = () => {
|
|
|
3498
3540
|
}, [filterWriteOperations, pageSize, page]);
|
|
3499
3541
|
const [fetchError, setFetchError] = useState5();
|
|
3500
3542
|
const { checkStatus, error: statusError, status } = useStatus();
|
|
3501
|
-
const fetchSpans =
|
|
3543
|
+
const fetchSpans = useCallback6(async () => {
|
|
3502
3544
|
setLoading(true);
|
|
3503
3545
|
try {
|
|
3504
3546
|
const response = await api.getSpans(queryOptions);
|
|
@@ -3515,7 +3557,7 @@ var SpansListPage = () => {
|
|
|
3515
3557
|
setLoading(false);
|
|
3516
3558
|
}
|
|
3517
3559
|
}, [api, page, queryOptions]);
|
|
3518
|
-
const fetchSpansSync =
|
|
3560
|
+
const fetchSpansSync = useCallback6(() => {
|
|
3519
3561
|
void fetchSpans();
|
|
3520
3562
|
}, [fetchSpans]);
|
|
3521
3563
|
useEffect4(() => {
|
|
@@ -3530,11 +3572,16 @@ var SpansListPage = () => {
|
|
|
3530
3572
|
}, [fetchSpans]);
|
|
3531
3573
|
const navigate = useNavigate();
|
|
3532
3574
|
const { resolveLink } = useAppInspector();
|
|
3533
|
-
const navigateToSpan =
|
|
3575
|
+
const navigateToSpan = useCallback6((span) => {
|
|
3534
3576
|
const url = resolveLink({ to: "trace-graph", traceId: span.trace_id });
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3577
|
+
const searchParams = new URLSearchParams({
|
|
3578
|
+
page: String(page),
|
|
3579
|
+
pageSize: String(pageSize),
|
|
3580
|
+
spanId: span.span_id
|
|
3581
|
+
});
|
|
3582
|
+
navigate(`${url}?${searchParams.toString()}`);
|
|
3583
|
+
}, [navigate, resolveLink, page, pageSize]);
|
|
3584
|
+
const clearSpans = useCallback6(async () => {
|
|
3538
3585
|
setLoading(true);
|
|
3539
3586
|
try {
|
|
3540
3587
|
await api.deleteSpans();
|
|
@@ -3548,7 +3595,7 @@ var SpansListPage = () => {
|
|
|
3548
3595
|
setLoading(false);
|
|
3549
3596
|
}
|
|
3550
3597
|
}, [api, fetchSpans]);
|
|
3551
|
-
const handleRetry =
|
|
3598
|
+
const handleRetry = useCallback6(() => {
|
|
3552
3599
|
void checkStatus();
|
|
3553
3600
|
}, [checkStatus]);
|
|
3554
3601
|
const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
|
|
@@ -3608,12 +3655,12 @@ import { ArrowBack } from "@mui/icons-material";
|
|
|
3608
3655
|
import { Box as Box19, Button as Button5, Drawer, Paper as Paper2 } from "@mui/material";
|
|
3609
3656
|
import { styled } from "@mui/material/styles";
|
|
3610
3657
|
import { ReactFlowProvider } from "@xyflow/react";
|
|
3611
|
-
import { useCallback as
|
|
3612
|
-
import { useNavigate as useNavigate2, useParams, useSearchParams } from "react-router-dom";
|
|
3658
|
+
import { useCallback as useCallback8, useEffect as useEffect7, useState as useState10 } from "react";
|
|
3659
|
+
import { useNavigate as useNavigate2, useParams, useSearchParams as useSearchParams2 } from "react-router-dom";
|
|
3613
3660
|
|
|
3614
3661
|
// src/components/event-details/event-details.tsx
|
|
3615
3662
|
import { Box as Box15, Chip as Chip3, Divider as Divider2, Stack as Stack2, Typography as Typography9 } from "@mui/material";
|
|
3616
|
-
import { useMemo as
|
|
3663
|
+
import { useMemo as useMemo8 } from "react";
|
|
3617
3664
|
|
|
3618
3665
|
// src/utils/iam-utils.ts
|
|
3619
3666
|
function determinePermissionStatus(payload) {
|
|
@@ -3847,7 +3894,7 @@ import { Box as Box14 } from "@mui/material";
|
|
|
3847
3894
|
// src/components/event-details/event-detail.tsx
|
|
3848
3895
|
import { KeyboardArrowDown as KeyboardArrowDown2, KeyboardArrowRight as KeyboardArrowRight2 } from "@mui/icons-material";
|
|
3849
3896
|
import { Box as Box12, Grid as Grid3, IconButton as IconButton3, Typography as Typography7 } from "@mui/material";
|
|
3850
|
-
import { useEffect as useEffect5, useMemo as
|
|
3897
|
+
import { useEffect as useEffect5, useMemo as useMemo7, useRef as useRef4, useState as useState7 } from "react";
|
|
3851
3898
|
|
|
3852
3899
|
// src/components/status-icon.tsx
|
|
3853
3900
|
import { Cancel, CheckCircle, Error as Error2, Info, RemoveCircle } from "@mui/icons-material";
|
|
@@ -3998,7 +4045,7 @@ var IAMEventDetail = ({ event }) => {
|
|
|
3998
4045
|
// src/components/event-details/iam-permission-detail.tsx
|
|
3999
4046
|
import { KeyboardArrowDown, KeyboardArrowRight } from "@mui/icons-material";
|
|
4000
4047
|
import { Box as Box11, Chip as Chip2, IconButton as IconButton2, Typography as Typography6 } from "@mui/material";
|
|
4001
|
-
import { useMemo as
|
|
4048
|
+
import { useMemo as useMemo6, useState as useState6 } from "react";
|
|
4002
4049
|
import { jsx as jsx134, jsxs as jsxs125 } from "react/jsx-runtime";
|
|
4003
4050
|
var getChipColors = (status) => {
|
|
4004
4051
|
const isAllowed = status === "explicitly_allowed" || status === "implicitly_allowed";
|
|
@@ -4009,7 +4056,7 @@ var getChipColors = (status) => {
|
|
|
4009
4056
|
};
|
|
4010
4057
|
var IAMPermissionItem = ({ event }) => {
|
|
4011
4058
|
const [isOpen, setIsOpen] = useState6(false);
|
|
4012
|
-
const parsedData =
|
|
4059
|
+
const parsedData = useMemo6(() => {
|
|
4013
4060
|
const payloadString = event.attributes?.payload;
|
|
4014
4061
|
if (!payloadString) {
|
|
4015
4062
|
return;
|
|
@@ -4082,8 +4129,8 @@ var EventMessage = ({ event }) => {
|
|
|
4082
4129
|
const [isOpen, setIsOpen] = useState7(false);
|
|
4083
4130
|
const [isOverflowing, setIsOverflowing] = useState7(false);
|
|
4084
4131
|
const textReference = useRef4(null);
|
|
4085
|
-
const parsedMessage =
|
|
4086
|
-
const isIAMPolicyEvent =
|
|
4132
|
+
const parsedMessage = useMemo7(() => parseEventMessage(event), [event]);
|
|
4133
|
+
const isIAMPolicyEvent = useMemo7(
|
|
4087
4134
|
() => event.event_type === "iam.policy_evaluation" && event.attributes?.payload && typeof event.attributes.payload === "string",
|
|
4088
4135
|
[event]
|
|
4089
4136
|
);
|
|
@@ -4100,11 +4147,11 @@ var EventMessage = ({ event }) => {
|
|
|
4100
4147
|
window.removeEventListener("resize", checkOverflow);
|
|
4101
4148
|
};
|
|
4102
4149
|
}, [parsedMessage.headline]);
|
|
4103
|
-
const hasAdditionalContent =
|
|
4150
|
+
const hasAdditionalContent = useMemo7(
|
|
4104
4151
|
() => parsedMessage.message || parsedMessage.details || isIAMPolicyEvent,
|
|
4105
4152
|
[parsedMessage.message, parsedMessage.details, isIAMPolicyEvent]
|
|
4106
4153
|
);
|
|
4107
|
-
const shouldShowToggle =
|
|
4154
|
+
const shouldShowToggle = useMemo7(
|
|
4108
4155
|
() => isOverflowing || hasAdditionalContent,
|
|
4109
4156
|
[isOverflowing, hasAdditionalContent]
|
|
4110
4157
|
);
|
|
@@ -4325,7 +4372,7 @@ var EventSection = ({
|
|
|
4325
4372
|
// src/components/event-details/event-details.tsx
|
|
4326
4373
|
import { Fragment as Fragment6, jsx as jsx138, jsxs as jsxs129 } from "react/jsx-runtime";
|
|
4327
4374
|
var EventDetails = ({ onClose, selectedEvent }) => {
|
|
4328
|
-
const attributes =
|
|
4375
|
+
const attributes = useMemo8(() => {
|
|
4329
4376
|
const attributes2 = Object.entries(selectedEvent?.attributes ?? {});
|
|
4330
4377
|
return attributes2.filter(([key]) => key !== "localstack.aws.account_id" && key !== "localstack.aws.service");
|
|
4331
4378
|
}, [selectedEvent?.attributes]);
|
|
@@ -4425,7 +4472,7 @@ function renderKeyValue(key, value) {
|
|
|
4425
4472
|
import "@xyflow/react/dist/base.css";
|
|
4426
4473
|
import { Alert as Alert3, Button as Button4, useTheme as useTheme2 } from "@mui/material";
|
|
4427
4474
|
import { Background, ReactFlow, useReactFlow as useReactFlow2 } from "@xyflow/react";
|
|
4428
|
-
import { useCallback as
|
|
4475
|
+
import { useCallback as useCallback7, useEffect as useEffect6, useState as useState9 } from "react";
|
|
4429
4476
|
|
|
4430
4477
|
// src/components/trace-graph/service-node.tsx
|
|
4431
4478
|
import { Box as Box17, Stack as Stack3, Typography as Typography10 } from "@mui/material";
|
|
@@ -4436,10 +4483,10 @@ import { memo as memo2 } from "react";
|
|
|
4436
4483
|
// src/components/trace-graph/problem-indicator.tsx
|
|
4437
4484
|
import { Error as ErrorIcon2, Info as Info2, Warning as Warning2 } from "@mui/icons-material";
|
|
4438
4485
|
import { Box as Box16, Tooltip as Tooltip4 } from "@mui/material";
|
|
4439
|
-
import { useMemo as
|
|
4486
|
+
import { useMemo as useMemo9 } from "react";
|
|
4440
4487
|
import { jsx as jsx139 } from "react/jsx-runtime";
|
|
4441
4488
|
var ProblemIndicator = ({ error }) => {
|
|
4442
|
-
const icon =
|
|
4489
|
+
const icon = useMemo9(() => {
|
|
4443
4490
|
switch (error.level) {
|
|
4444
4491
|
case "error": {
|
|
4445
4492
|
return /* @__PURE__ */ jsx139(ErrorIcon2, { sx: { color: "#d32f2f", fontSize: "14px" } });
|
|
@@ -4452,7 +4499,7 @@ var ProblemIndicator = ({ error }) => {
|
|
|
4452
4499
|
}
|
|
4453
4500
|
}
|
|
4454
4501
|
}, [error.level]);
|
|
4455
|
-
const color =
|
|
4502
|
+
const color = useMemo9(() => {
|
|
4456
4503
|
switch (error.level) {
|
|
4457
4504
|
case "error": {
|
|
4458
4505
|
return "#d32f2f";
|
|
@@ -4795,7 +4842,7 @@ var TraceGraph = ({
|
|
|
4795
4842
|
const [edges, setEdges] = useState9([]);
|
|
4796
4843
|
const [initialViewSet, setInitialViewSet] = useState9(false);
|
|
4797
4844
|
const { fitView, setCenter } = useReactFlow2();
|
|
4798
|
-
const updateSelectedNode =
|
|
4845
|
+
const updateSelectedNode = useCallback7((nodeId) => {
|
|
4799
4846
|
const toSelect = new Set(nodeId ? [nodeId] : []);
|
|
4800
4847
|
setNodes((previousNodes) => {
|
|
4801
4848
|
return previousNodes.map((node) => ({ ...node, selected: toSelect.has(node.id) }));
|
|
@@ -4861,7 +4908,7 @@ var TraceGraph = ({
|
|
|
4861
4908
|
updateSelectedNode(initialFocusEventId);
|
|
4862
4909
|
}
|
|
4863
4910
|
}, [initialFocusEventId, updateSelectedNode]);
|
|
4864
|
-
const onNodeClick =
|
|
4911
|
+
const onNodeClick = useCallback7((_event, node) => {
|
|
4865
4912
|
onEventSelect(node.data.event);
|
|
4866
4913
|
updateSelectedNode(node.id);
|
|
4867
4914
|
}, [onEventSelect, updateSelectedNode]);
|
|
@@ -5031,13 +5078,13 @@ var TraceGraphView = ({
|
|
|
5031
5078
|
};
|
|
5032
5079
|
var TraceGraphPage = () => {
|
|
5033
5080
|
const { traceId } = useParams();
|
|
5034
|
-
const [searchParameters] =
|
|
5081
|
+
const [searchParameters] = useSearchParams2();
|
|
5035
5082
|
const spanId = searchParameters.get("spanId");
|
|
5036
5083
|
const api = useAppInspectorApi();
|
|
5037
5084
|
const [spans, setSpans] = useState10();
|
|
5038
5085
|
const [loading, setLoading] = useState10(false);
|
|
5039
5086
|
const [fetchError, setFetchError] = useState10();
|
|
5040
|
-
const fetchSpans =
|
|
5087
|
+
const fetchSpans = useCallback8(async () => {
|
|
5041
5088
|
setLoading(true);
|
|
5042
5089
|
try {
|
|
5043
5090
|
const response = await api.getSpans({
|
|
@@ -5059,7 +5106,7 @@ var TraceGraphPage = () => {
|
|
|
5059
5106
|
const [selectedEvent, setSelectedEvent] = useState10();
|
|
5060
5107
|
const [viewPortPixelWidth, setViewPortPixelWidth] = useState10(0);
|
|
5061
5108
|
const { checkStatus, error: statusError, status } = useStatus();
|
|
5062
|
-
const calculateDrawerWidth =
|
|
5109
|
+
const calculateDrawerWidth = useCallback8(() => {
|
|
5063
5110
|
const percentageMatch = /(\d+)%/.exec(DRAWER_WIDTH);
|
|
5064
5111
|
if (percentageMatch && open) {
|
|
5065
5112
|
const percentage = Number.parseInt(percentageMatch[1], 10);
|
|
@@ -5081,19 +5128,23 @@ var TraceGraphPage = () => {
|
|
|
5081
5128
|
clearTimeout(timeoutId);
|
|
5082
5129
|
};
|
|
5083
5130
|
}, [open, calculateDrawerWidth]);
|
|
5084
|
-
const handleEventSelect =
|
|
5131
|
+
const handleEventSelect = useCallback8((event) => {
|
|
5085
5132
|
setSelectedEvent(event);
|
|
5086
5133
|
setOpen(true);
|
|
5087
5134
|
}, []);
|
|
5088
|
-
const handleRetry =
|
|
5135
|
+
const handleRetry = useCallback8(() => {
|
|
5089
5136
|
void checkStatus();
|
|
5090
5137
|
}, [checkStatus]);
|
|
5091
5138
|
const navigate = useNavigate2();
|
|
5092
5139
|
const { resolveLink } = useAppInspector();
|
|
5093
|
-
const navigateToSpansList =
|
|
5140
|
+
const navigateToSpansList = useCallback8(() => {
|
|
5094
5141
|
const url = resolveLink({ to: "spans-list" });
|
|
5095
|
-
|
|
5096
|
-
|
|
5142
|
+
const searchParams = new URLSearchParams({
|
|
5143
|
+
page: searchParameters.get("page") ?? "",
|
|
5144
|
+
pageSize: searchParameters.get("pageSize") ?? ""
|
|
5145
|
+
});
|
|
5146
|
+
navigate(`${url}?${searchParams.toString()}`);
|
|
5147
|
+
}, [navigate, resolveLink, searchParameters]);
|
|
5097
5148
|
return /* @__PURE__ */ jsx143(
|
|
5098
5149
|
TraceGraphView,
|
|
5099
5150
|
{
|