@localstack/appinspector-ui 1.0.60 → 1.0.61

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.js CHANGED
@@ -58,13 +58,13 @@ var init_is_prop_valid_esm = __esm({
58
58
 
59
59
  // src/pages/spans-list-page.tsx
60
60
  import { Box as Box18 } from "@mui/material";
61
- import { useCallback as useCallback8, useState as useState12 } from "react";
61
+ import { useCallback as useCallback9, useState as useState13 } from "react";
62
62
 
63
63
  // src/components/spans-list/spans-list.tsx
64
64
  import { Alert, Box as Box4, Button as Button2 } from "@mui/material";
65
65
 
66
66
  // src/components/spans-list/spans-data-grid.tsx
67
- import { DeleteForeverOutlined } from "@mui/icons-material";
67
+ import { DeleteForeverOutlined, SwapVertOutlined } from "@mui/icons-material";
68
68
  import {
69
69
  Box as Box3,
70
70
  Button,
@@ -12145,6 +12145,16 @@ var newSpanBackgroundColor = {
12145
12145
  dark: "#887b02",
12146
12146
  light: "#ffde7b"
12147
12147
  };
12148
+ var LABEL_BEGINNING_OF_STREAM = "This is the beginning of the stream";
12149
+ var LABEL_END_OF_STREAM = "This is the end of the stream";
12150
+ var LABEL_NO_SPANS = "There are no spans";
12151
+ var LABEL_LOAD_OLDER = "Load older spans";
12152
+ var LABEL_LOAD_NEWER = "Load newer spans";
12153
+ var StreamBoundaryRow = ({ colSpan, label }) => /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsx124(TableCell, { colSpan, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ jsx124("span", { children: label }) }) });
12154
+ var LoadSpansRow = ({ colSpan, fetching, label, onFetch }) => /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsxs120(TableCell, { colSpan, sx: { textAlign: "center" }, children: [
12155
+ !fetching && /* @__PURE__ */ jsx124(Button, { onClick: onFetch, sx: { my: 1 }, children: label }),
12156
+ fetching && /* @__PURE__ */ jsx124(CircularProgress, { size: 24, sx: { m: 2 } })
12157
+ ] }) });
12148
12158
  var SpansDataGridRow = memo8(
12149
12159
  ({ row }) => {
12150
12160
  const theme = useTheme2();
@@ -12200,11 +12210,15 @@ var SpansDataGridRow = memo8(
12200
12210
  var SpansDataGrid = ({
12201
12211
  clearingSpans,
12202
12212
  fetchingBackward,
12213
+ fetchingForward,
12203
12214
  hasMoreBackward,
12204
12215
  hasMoreForward,
12205
12216
  onClearSpans,
12206
12217
  onFetchBackward,
12218
+ onFetchForward,
12219
+ onOrderChange,
12207
12220
  onSpanClick,
12221
+ order: order2,
12208
12222
  spans
12209
12223
  }) => {
12210
12224
  const columns = useMemo5(() => [
@@ -12294,6 +12308,23 @@ var SpansDataGrid = ({
12294
12308
  return /* @__PURE__ */ jsxs120(Fragment3, { children: [
12295
12309
  /* @__PURE__ */ jsx124(Grid, { item: true, xs: 12, children: /* @__PURE__ */ jsxs120(Box3, { sx: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
12296
12310
  /* @__PURE__ */ jsx124(Box3, { sx: { flexGrow: 1 } }),
12311
+ /* @__PURE__ */ jsx124(
12312
+ FormControlLabel,
12313
+ {
12314
+ control: /* @__PURE__ */ jsx124(
12315
+ Button,
12316
+ {
12317
+ onClick: () => {
12318
+ onOrderChange(order2 === "newest_first" ? "oldest_first" : "newest_first");
12319
+ },
12320
+ startIcon: /* @__PURE__ */ jsx124(SwapVertOutlined, {}),
12321
+ variant: "text",
12322
+ children: order2 === "newest_first" ? "Newest First" : "Oldest First"
12323
+ }
12324
+ ),
12325
+ label: ""
12326
+ }
12327
+ ),
12297
12328
  /* @__PURE__ */ jsx124(
12298
12329
  FormControlLabel,
12299
12330
  {
@@ -12351,21 +12382,30 @@ var SpansDataGrid = ({
12351
12382
  }) }),
12352
12383
  /* @__PURE__ */ jsxs120(TableBody, { children: [
12353
12384
  spans === void 0 && /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsx124(TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ jsx124(CircularProgress, { size: 48, sx: { m: 4 } }) }) }),
12354
- spans?.length === 0 && /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsx124(TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ jsx124("span", { children: "There are no spans" }) }) }),
12355
- hasRows && !hasMoreBackward && /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsx124(TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ jsx124("span", { children: "This is the beginning of the stream" }) }) }),
12356
- hasRows && hasMoreBackward && /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsxs120(TableCell, { colSpan: columnCount, sx: { textAlign: "center" }, children: [
12357
- !fetchingBackward && /* @__PURE__ */ jsx124(
12358
- Button,
12359
- {
12360
- onClick: onFetchBackward,
12361
- sx: { my: 1 },
12362
- children: "Load older spans"
12385
+ spans?.length === 0 && /* @__PURE__ */ jsx124(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_NO_SPANS }),
12386
+ order2 === "newest_first" && /* @__PURE__ */ jsxs120(Fragment3, { children: [
12387
+ hasRows && hasMoreForward && /* @__PURE__ */ jsx124(LoadSpansRow, { colSpan: columnCount, fetching: fetchingForward, label: LABEL_LOAD_NEWER, onFetch: onFetchForward }),
12388
+ hasRows && !hasMoreForward && /* @__PURE__ */ jsx124(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM }),
12389
+ hasRows && /* @__PURE__ */ jsx124(AnimatePresence, { initial: false, children: (() => {
12390
+ const reversed = [];
12391
+ for (let index2 = rows.length - 1; index2 >= 0; index2--) {
12392
+ const row = rows.at(index2);
12393
+ reversed.push(
12394
+ /* @__PURE__ */ jsx124(SpansDataGridRow, { row }, row.original.span_id)
12395
+ );
12363
12396
  }
12364
- ),
12365
- fetchingBackward && /* @__PURE__ */ jsx124(CircularProgress, { size: 24, sx: { m: 2 } })
12366
- ] }) }),
12367
- hasRows && /* @__PURE__ */ jsx124(AnimatePresence, { initial: false, children: rows.map((row) => /* @__PURE__ */ jsx124(SpansDataGridRow, { row }, row.original.span_id)) }),
12368
- hasRows && !hasMoreForward && /* @__PURE__ */ jsx124(TableRow, { children: /* @__PURE__ */ jsx124(TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ jsx124("span", { children: "This is the end of the stream" }) }) })
12397
+ return reversed;
12398
+ })() }),
12399
+ hasRows && hasMoreBackward && /* @__PURE__ */ jsx124(LoadSpansRow, { colSpan: columnCount, fetching: fetchingBackward, label: LABEL_LOAD_OLDER, onFetch: onFetchBackward }),
12400
+ hasRows && !hasMoreBackward && /* @__PURE__ */ jsx124(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM })
12401
+ ] }),
12402
+ order2 === "oldest_first" && /* @__PURE__ */ jsxs120(Fragment3, { children: [
12403
+ hasRows && !hasMoreBackward && /* @__PURE__ */ jsx124(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM }),
12404
+ hasRows && hasMoreBackward && /* @__PURE__ */ jsx124(LoadSpansRow, { colSpan: columnCount, fetching: fetchingBackward, label: LABEL_LOAD_OLDER, onFetch: onFetchBackward }),
12405
+ hasRows && /* @__PURE__ */ jsx124(AnimatePresence, { initial: false, children: rows.map((row) => /* @__PURE__ */ jsx124(SpansDataGridRow, { row }, row.original.span_id)) }),
12406
+ hasRows && hasMoreForward && /* @__PURE__ */ jsx124(LoadSpansRow, { colSpan: columnCount, fetching: fetchingForward, label: LABEL_LOAD_NEWER, onFetch: onFetchForward }),
12407
+ hasRows && !hasMoreForward && /* @__PURE__ */ jsx124(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM })
12408
+ ] })
12369
12409
  ] })
12370
12410
  ]
12371
12411
  }
@@ -12402,7 +12442,9 @@ var SpansList = (props) => {
12402
12442
  onClearSpans: props.onClearSpans,
12403
12443
  onFetchBackward: props.onFetchBackward,
12404
12444
  onFetchForward: props.onFetchForward,
12445
+ onOrderChange: props.onOrderChange,
12405
12446
  onSpanClick: props.onSpanClick,
12447
+ order: props.order,
12406
12448
  refetching: props.refetching,
12407
12449
  spans: props.spans
12408
12450
  }
@@ -12707,8 +12749,53 @@ var StatusMessage = ({
12707
12749
  return /* @__PURE__ */ jsx126(Fragment4, {});
12708
12750
  };
12709
12751
 
12752
+ // src/hooks/use-local-storage.tsx
12753
+ import { useCallback as useCallback3, useEffect as useEffect11, useState as useState4 } from "react";
12754
+ function useLocalStorage(key, initialValue) {
12755
+ const [storedValue, setStoredValue] = useState4(() => {
12756
+ try {
12757
+ const item = globalThis.localStorage.getItem(key);
12758
+ return item ? JSON.parse(item) : initialValue;
12759
+ } catch (error) {
12760
+ console.error(`Error reading localStorage key "${key}":`, error);
12761
+ return initialValue;
12762
+ }
12763
+ });
12764
+ const setValue = useCallback3((value) => {
12765
+ try {
12766
+ setStoredValue((previousState) => {
12767
+ const next = typeof value === "function" ? value(previousState) : value;
12768
+ globalThis.localStorage.setItem(key, JSON.stringify(next));
12769
+ globalThis.dispatchEvent(new StorageEvent("storage", {
12770
+ key,
12771
+ newValue: JSON.stringify(next)
12772
+ }));
12773
+ return next;
12774
+ });
12775
+ } catch (error) {
12776
+ console.error(`Error setting localStorage key "${key}":`, error);
12777
+ }
12778
+ }, [key]);
12779
+ useEffect11(() => {
12780
+ const handleStorageChange = (event) => {
12781
+ if (event.key === key && event.newValue !== null) {
12782
+ try {
12783
+ setStoredValue(JSON.parse(event.newValue));
12784
+ } catch (error) {
12785
+ console.error(`Error parsing localStorage key "${key}":`, error);
12786
+ }
12787
+ }
12788
+ };
12789
+ globalThis.addEventListener("storage", handleStorageChange);
12790
+ return () => {
12791
+ globalThis.removeEventListener("storage", handleStorageChange);
12792
+ };
12793
+ }, [key]);
12794
+ return [storedValue, setValue];
12795
+ }
12796
+
12710
12797
  // src/hooks/use-spans.ts
12711
- import { useCallback as useCallback6, useEffect as useEffect13, useRef as useRef10, useState as useState6 } from "react";
12798
+ import { useCallback as useCallback7, useEffect as useEffect14, useRef as useRef10, useState as useState7 } from "react";
12712
12799
 
12713
12800
  // src/api/use-api.tsx
12714
12801
  import { createContext as createContext7, useContext as useContext14 } from "react";
@@ -12726,15 +12813,15 @@ var useAppInspectorApi = () => {
12726
12813
  };
12727
12814
 
12728
12815
  // src/hooks/use-status.tsx
12729
- import { useCallback as useCallback3, useEffect as useEffect11, useRef as useRef8, useState as useState4 } from "react";
12816
+ import { useCallback as useCallback4, useEffect as useEffect12, useRef as useRef8, useState as useState5 } from "react";
12730
12817
  var useStatus = () => {
12731
12818
  const api = useAppInspectorApi();
12732
- const [checking, setChecking] = useState4(true);
12733
- const [status, setStatus] = useState4();
12734
- const [error, setError] = useState4();
12819
+ const [checking, setChecking] = useState5(true);
12820
+ const [status, setStatus] = useState5();
12821
+ const [error, setError] = useState5();
12735
12822
  const hasFetchedReference = useRef8(false);
12736
12823
  const abortControllerReference = useRef8(null);
12737
- const checkStatus = useCallback3(async () => {
12824
+ const checkStatus = useCallback4(async () => {
12738
12825
  if (abortControllerReference.current !== null) {
12739
12826
  abortControllerReference.current.abort();
12740
12827
  }
@@ -12758,7 +12845,7 @@ var useStatus = () => {
12758
12845
  }
12759
12846
  }
12760
12847
  }, [api]);
12761
- useEffect11(() => {
12848
+ useEffect12(() => {
12762
12849
  if (!hasFetchedReference.current) {
12763
12850
  hasFetchedReference.current = true;
12764
12851
  void checkStatus();
@@ -12916,11 +13003,11 @@ var createPaginationBuffer = (options) => {
12916
13003
  };
12917
13004
 
12918
13005
  // src/hooks/use-spans-ws.tsx
12919
- import { useCallback as useCallback5, useEffect as useEffect12, useRef as useRef9, useState as useState5 } from "react";
13006
+ import { useCallback as useCallback6, useEffect as useEffect13, useRef as useRef9, useState as useState6 } from "react";
12920
13007
 
12921
13008
  // src/context.tsx
12922
13009
  import { createContext as createContext8, useContext as useContext15 } from "react";
12923
- import { useCallback as useCallback4, useMemo as useMemo6 } from "react";
13010
+ import { useCallback as useCallback5, useMemo as useMemo6 } from "react";
12924
13011
 
12925
13012
  // src/utils/time.ts
12926
13013
  function unixNanoToDate(unixNanoString) {
@@ -13125,7 +13212,7 @@ var AppInspectorContextProvider = (props) => {
13125
13212
  const api = useMemo6(() => {
13126
13213
  return false ? createApiClientMock() : createApiClient({ localstackEndpoint: props.localstackEndpoint });
13127
13214
  }, [props.localstackEndpoint]);
13128
- const resolveLink = useCallback4(
13215
+ const resolveLink = useCallback5(
13129
13216
  (options) => {
13130
13217
  if (options.to === "settings") {
13131
13218
  return `${props.routePrefix}/settings`;
@@ -13152,14 +13239,14 @@ var AppInspectorContextProvider = (props) => {
13152
13239
  function useSpansWebSocket(options) {
13153
13240
  const { onMessage } = options;
13154
13241
  const onMessageRef = useRef9(onMessage);
13155
- useEffect12(() => {
13242
+ useEffect13(() => {
13156
13243
  onMessageRef.current = onMessage;
13157
13244
  }, [onMessage]);
13158
- const [connected, setConnected] = useState5(false);
13245
+ const [connected, setConnected] = useState6(false);
13159
13246
  const wsRef = useRef9(void 0);
13160
13247
  const reconnectRef = useRef9(void 0);
13161
13248
  const { localstackEndpoint } = useAppInspector();
13162
- const connect = useCallback5(() => {
13249
+ const connect = useCallback6(() => {
13163
13250
  if (wsRef.current !== void 0) return;
13164
13251
  const url = new URL(getAppInspectorApiUrl(localstackEndpoint, API_ENDPOINTS.WEBSOCKET_SPANS));
13165
13252
  url.protocol = globalThis.location.protocol === "https:" ? "wss" : "ws";
@@ -13185,7 +13272,7 @@ function useSpansWebSocket(options) {
13185
13272
  }
13186
13273
  });
13187
13274
  }, [localstackEndpoint]);
13188
- useEffect12(() => {
13275
+ useEffect13(() => {
13189
13276
  connect();
13190
13277
  return () => {
13191
13278
  if (reconnectRef.current !== void 0) clearTimeout(reconnectRef.current);
@@ -13205,11 +13292,11 @@ function useSpansWebSocket(options) {
13205
13292
  var PAGE_SIZE = 30;
13206
13293
  var useSpans = () => {
13207
13294
  const api = useAppInspectorApi();
13208
- const [spans, setSpans] = useState6();
13209
- const [fetchError, setFetchError] = useState6();
13210
- const [fetchingForward, setFetchingForward] = useState6(false);
13211
- const [fetchingBackward, setFetchingBackward] = useState6(false);
13212
- const [refetching, setRefetching] = useState6(false);
13295
+ const [spans, setSpans] = useState7();
13296
+ const [fetchError, setFetchError] = useState7();
13297
+ const [fetchingForward, setFetchingForward] = useState7(false);
13298
+ const [fetchingBackward, setFetchingBackward] = useState7(false);
13299
+ const [refetching, setRefetching] = useState7(false);
13213
13300
  const paginationBuffer = useRef10(createPaginationBuffer({
13214
13301
  async fetchPage(token) {
13215
13302
  const response = await api.getSpans({
@@ -13245,20 +13332,20 @@ var useSpans = () => {
13245
13332
  return a2.start_time_unix_nano < b2.start_time_unix_nano ? -1 : 1;
13246
13333
  }
13247
13334
  }));
13248
- const [hasMoreBackward, setHasMoreBackward] = useState6();
13249
- const [hasMoreForward, setHasMoreForward] = useState6();
13250
- const fetchForward = useCallback6(() => {
13335
+ const [hasMoreBackward, setHasMoreBackward] = useState7();
13336
+ const [hasMoreForward, setHasMoreForward] = useState7();
13337
+ const fetchForward = useCallback7(() => {
13251
13338
  paginationBuffer.current.fetchForward();
13252
13339
  }, []);
13253
- const fetchBackward = useCallback6(() => {
13340
+ const fetchBackward = useCallback7(() => {
13254
13341
  paginationBuffer.current.fetchBackward();
13255
13342
  }, []);
13256
- useEffect13(() => {
13343
+ useEffect14(() => {
13257
13344
  fetchForward();
13258
13345
  }, [fetchForward]);
13259
13346
  const { checkStatus, error: statusError, status } = useStatus();
13260
- const [clearingSpans, setClearingSpans] = useState6(false);
13261
- const clearSpans = useCallback6(async () => {
13347
+ const [clearingSpans, setClearingSpans] = useState7(false);
13348
+ const clearSpans = useCallback7(async () => {
13262
13349
  setClearingSpans(true);
13263
13350
  try {
13264
13351
  await api.deleteSpans();
@@ -13298,7 +13385,7 @@ import { ArrowBack } from "@mui/icons-material";
13298
13385
  import { Box as Box17, Button as Button5, Drawer, Paper as Paper2 } from "@mui/material";
13299
13386
  import { styled } from "@mui/material/styles";
13300
13387
  import { ReactFlowProvider } from "@xyflow/react";
13301
- import { useCallback as useCallback7, useEffect as useEffect16, useRef as useRef12, useState as useState11 } from "react";
13388
+ import { useCallback as useCallback8, useEffect as useEffect17, useRef as useRef12, useState as useState12 } from "react";
13302
13389
 
13303
13390
  // src/components/event-details/event-details.tsx
13304
13391
  import { Box as Box13, Chip as Chip3, Divider as Divider2, Stack, Typography as Typography9 } from "@mui/material";
@@ -13536,7 +13623,7 @@ import { Box as Box12 } from "@mui/material";
13536
13623
  // src/components/event-details/event-detail.tsx
13537
13624
  import { KeyboardArrowDown as KeyboardArrowDown2, KeyboardArrowRight as KeyboardArrowRight2 } from "@mui/icons-material";
13538
13625
  import { Box as Box10, Grid as Grid3, IconButton as IconButton3, Typography as Typography7 } from "@mui/material";
13539
- import { useEffect as useEffect14, useMemo as useMemo8, useRef as useRef11, useState as useState8 } from "react";
13626
+ import { useEffect as useEffect15, useMemo as useMemo8, useRef as useRef11, useState as useState9 } from "react";
13540
13627
 
13541
13628
  // src/components/status-icon.tsx
13542
13629
  import { Cancel, CheckCircle, Error as Error2, Info, RemoveCircle } from "@mui/icons-material";
@@ -13687,7 +13774,7 @@ var IAMEventDetail = ({ event }) => {
13687
13774
  // src/components/event-details/iam-permission-detail.tsx
13688
13775
  import { KeyboardArrowDown, KeyboardArrowRight } from "@mui/icons-material";
13689
13776
  import { Box as Box9, Chip as Chip2, IconButton as IconButton2, Typography as Typography6 } from "@mui/material";
13690
- import { useMemo as useMemo7, useState as useState7 } from "react";
13777
+ import { useMemo as useMemo7, useState as useState8 } from "react";
13691
13778
  import { jsx as jsx132, jsxs as jsxs125 } from "react/jsx-runtime";
13692
13779
  var getChipColors = (status) => {
13693
13780
  const isAllowed = status === "explicitly_allowed" || status === "implicitly_allowed";
@@ -13697,7 +13784,7 @@ var getChipColors = (status) => {
13697
13784
  };
13698
13785
  };
13699
13786
  var IAMPermissionItem = ({ event }) => {
13700
- const [isOpen, setIsOpen] = useState7(false);
13787
+ const [isOpen, setIsOpen] = useState8(false);
13701
13788
  const parsedData = useMemo7(() => {
13702
13789
  const payloadString = event.attributes?.payload;
13703
13790
  if (!payloadString) {
@@ -13768,15 +13855,15 @@ var DetailRow2 = ({ content, label }) => /* @__PURE__ */ jsxs126(Grid3, { contai
13768
13855
  ) : content })
13769
13856
  ] });
13770
13857
  var EventMessage = ({ event }) => {
13771
- const [isOpen, setIsOpen] = useState8(false);
13772
- const [isOverflowing, setIsOverflowing] = useState8(false);
13858
+ const [isOpen, setIsOpen] = useState9(false);
13859
+ const [isOverflowing, setIsOverflowing] = useState9(false);
13773
13860
  const textReference = useRef11(null);
13774
13861
  const parsedMessage = useMemo8(() => parseEventMessage(event), [event]);
13775
13862
  const isIAMPolicyEvent = useMemo8(
13776
13863
  () => event.event_type === "iam.policy_evaluation" && event.attributes?.payload && typeof event.attributes.payload === "string",
13777
13864
  [event]
13778
13865
  );
13779
- useEffect14(() => {
13866
+ useEffect15(() => {
13780
13867
  const checkOverflow = () => {
13781
13868
  const element = textReference.current;
13782
13869
  if (element) {
@@ -13935,10 +14022,10 @@ var EventDetail = ({
13935
14022
  // src/components/event-details/toggle-section.tsx
13936
14023
  import { KeyboardArrowDown as KeyboardArrowDown3, KeyboardArrowRight as KeyboardArrowRight3 } from "@mui/icons-material";
13937
14024
  import { Box as Box11, Typography as Typography8 } from "@mui/material";
13938
- import { useState as useState9 } from "react";
14025
+ import { useState as useState10 } from "react";
13939
14026
  import { jsx as jsx134, jsxs as jsxs127 } from "react/jsx-runtime";
13940
14027
  var ToggleSection = ({ children, headline, initialOpen = true }) => {
13941
- const [isOpen, setIsOpen] = useState9(initialOpen);
14028
+ const [isOpen, setIsOpen] = useState10(initialOpen);
13942
14029
  return /* @__PURE__ */ jsxs127(Box11, { sx: { mt: 4 }, children: [
13943
14030
  /* @__PURE__ */ jsx134(
13944
14031
  Box11,
@@ -14138,7 +14225,7 @@ function renderKeyValue(key, value) {
14138
14225
  import "@xyflow/react/dist/base.css";
14139
14226
  import { Alert as Alert3, Button as Button4, useTheme as useTheme3 } from "@mui/material";
14140
14227
  import { Background, ReactFlow, useNodesState } from "@xyflow/react";
14141
- import { useEffect as useEffect15, useState as useState10 } from "react";
14228
+ import { useEffect as useEffect16, useState as useState11 } from "react";
14142
14229
 
14143
14230
  // src/components/trace-graph/service-node.tsx
14144
14231
  import { Box as Box15, Stack as Stack2, Typography as Typography10 } from "@mui/material";
@@ -14489,8 +14576,8 @@ var TraceGraph = ({
14489
14576
  spans
14490
14577
  }) => {
14491
14578
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
14492
- const [edges, setEdges] = useState10([]);
14493
- useEffect15(() => {
14579
+ const [edges, setEdges] = useState11([]);
14580
+ useEffect16(() => {
14494
14581
  const spansMap = /* @__PURE__ */ new Map();
14495
14582
  const rootSpans = [];
14496
14583
  for (const span of spans.data ?? []) {
@@ -14734,10 +14821,10 @@ async function fetchConnectedTraces(api, traceIds, allSpans = /* @__PURE__ */ ne
14734
14821
  }
14735
14822
  var TraceGraphPage = ({ onClose, spanId, traceId }) => {
14736
14823
  const api = useAppInspectorApi();
14737
- const [spans, setSpans] = useState11();
14738
- const [loading, setLoading] = useState11(false);
14739
- const [fetchError, setFetchError] = useState11();
14740
- const fetchSpans = useCallback7(async () => {
14824
+ const [spans, setSpans] = useState12();
14825
+ const [loading, setLoading] = useState12(false);
14826
+ const [fetchError, setFetchError] = useState12();
14827
+ const fetchSpans = useCallback8(async () => {
14741
14828
  setLoading(true);
14742
14829
  try {
14743
14830
  const spans2 = await fetchConnectedTraces(api, [traceId]);
@@ -14750,28 +14837,28 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
14750
14837
  setLoading(false);
14751
14838
  }
14752
14839
  }, [api, traceId]);
14753
- useEffect16(() => {
14840
+ useEffect17(() => {
14754
14841
  void fetchSpans();
14755
14842
  }, [fetchSpans]);
14756
- const [open, setOpen] = useState11(true);
14757
- const [selectedEvent, setSelectedEvent] = useState11(() => spans?.find((span) => span.span_id === spanId));
14843
+ const [open, setOpen] = useState12(true);
14844
+ const [selectedEvent, setSelectedEvent] = useState12(() => spans?.find((span) => span.span_id === spanId));
14758
14845
  const spansReference = useRef12();
14759
- useEffect16(() => {
14846
+ useEffect17(() => {
14760
14847
  if (!spansReference.current && spans) {
14761
14848
  setSelectedEvent(spans.find((span) => span.span_id === spanId));
14762
14849
  spansReference.current = spans;
14763
14850
  }
14764
14851
  }, [spans, setSelectedEvent, spanId]);
14765
14852
  const { checkStatus, error: statusError, status } = useStatus();
14766
- const handleEventSelect = useCallback7((spanId2) => {
14853
+ const handleEventSelect = useCallback8((spanId2) => {
14767
14854
  const span = spans?.find((s) => s.span_id === spanId2);
14768
14855
  setSelectedEvent(span);
14769
14856
  setOpen(true);
14770
14857
  }, [spans]);
14771
- const handleRetry = useCallback7(() => {
14858
+ const handleRetry = useCallback8(() => {
14772
14859
  void checkStatus();
14773
14860
  }, [checkStatus]);
14774
- const navigateToSpansList = useCallback7(() => {
14861
+ const navigateToSpansList = useCallback8(() => {
14775
14862
  onClose?.();
14776
14863
  }, [onClose]);
14777
14864
  return /* @__PURE__ */ jsx141(
@@ -14816,16 +14903,17 @@ var SpansListPage = () => {
14816
14903
  status,
14817
14904
  statusError
14818
14905
  } = useSpans();
14819
- const clearSpansSync = useCallback8(() => {
14906
+ const clearSpansSync = useCallback9(() => {
14820
14907
  void clearSpans();
14821
14908
  }, [clearSpans]);
14822
- const [selectedTraceId, setSelectedTraceId] = useState12();
14823
- const [selectedSpanId, setSelectedSpanId] = useState12();
14824
- const navigateToSpan = useCallback8((span) => {
14909
+ const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
14910
+ const [selectedTraceId, setSelectedTraceId] = useState13();
14911
+ const [selectedSpanId, setSelectedSpanId] = useState13();
14912
+ const navigateToSpan = useCallback9((span) => {
14825
14913
  setSelectedTraceId(span.trace_id);
14826
14914
  setSelectedSpanId(span.span_id);
14827
14915
  }, []);
14828
- const handleRetry = useCallback8(() => {
14916
+ const handleRetry = useCallback9(() => {
14829
14917
  void checkStatus();
14830
14918
  }, [checkStatus]);
14831
14919
  const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
@@ -14864,7 +14952,9 @@ var SpansListPage = () => {
14864
14952
  onClearSpans: clearSpansSync,
14865
14953
  onFetchBackward: fetchBackward,
14866
14954
  onFetchForward: fetchForward,
14955
+ onOrderChange: setOrder,
14867
14956
  onSpanClick: navigateToSpan,
14957
+ order: order2,
14868
14958
  refetching,
14869
14959
  spans
14870
14960
  }