@localstack/appinspector-ui 1.0.0-dev-dc58bc41 → 1.0.0-dev-f55daae2
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 +545 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +526 -160
- 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
|
-
import { Box as
|
|
3
|
-
import { useCallback as
|
|
2
|
+
import { Box as Box6 } from "@mui/material";
|
|
3
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
|
|
4
4
|
import { useNavigate } from "react-router-dom";
|
|
5
5
|
|
|
6
6
|
// src/api/use-api.tsx
|
|
@@ -108,7 +108,7 @@ function unixNanoToDate(unixNanoString) {
|
|
|
108
108
|
|
|
109
109
|
// src/components/cells/responsive-timestamp-cell.tsx
|
|
110
110
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
111
|
-
var ResponsiveTimestampCell = ({ value }) => {
|
|
111
|
+
var ResponsiveTimestampCell = ({ locale, value }) => {
|
|
112
112
|
const [columnWidth, setColumnWidth] = useState(0);
|
|
113
113
|
const cellReference = useRef(null);
|
|
114
114
|
useEffect(() => {
|
|
@@ -134,35 +134,41 @@ var ResponsiveTimestampCell = ({ value }) => {
|
|
|
134
134
|
const date = unixNanoToDate(value);
|
|
135
135
|
if (!date) return;
|
|
136
136
|
if (columnWidth < 100) {
|
|
137
|
-
|
|
137
|
+
const formatter = new Intl.DateTimeFormat(locale, {
|
|
138
138
|
hour: "2-digit",
|
|
139
139
|
hour12: false,
|
|
140
140
|
minute: "2-digit",
|
|
141
141
|
second: "2-digit"
|
|
142
142
|
});
|
|
143
|
+
return formatter.format(date);
|
|
143
144
|
} else if (columnWidth < 160) {
|
|
144
|
-
const
|
|
145
|
+
const formatter = new Intl.DateTimeFormat(locale, {
|
|
145
146
|
hour: "2-digit",
|
|
146
147
|
hour12: false,
|
|
147
148
|
minute: "2-digit",
|
|
148
149
|
second: "2-digit"
|
|
149
150
|
});
|
|
151
|
+
const timeString = formatter.format(date);
|
|
150
152
|
const ms = date.getMilliseconds().toString().padStart(3, "0");
|
|
151
153
|
return `${timeString}:${ms}`;
|
|
152
154
|
} else {
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
const dateFormatter = new Intl.DateTimeFormat(locale, {
|
|
156
|
+
day: "2-digit",
|
|
157
|
+
month: "2-digit",
|
|
158
|
+
year: "numeric"
|
|
159
|
+
});
|
|
160
|
+
const timeFormatter = new Intl.DateTimeFormat(locale, {
|
|
157
161
|
hour: "2-digit",
|
|
158
162
|
hour12: false,
|
|
159
163
|
minute: "2-digit",
|
|
160
164
|
second: "2-digit"
|
|
161
165
|
});
|
|
166
|
+
const dateString = dateFormatter.format(date);
|
|
167
|
+
const timeString = timeFormatter.format(date);
|
|
162
168
|
const ms = date.getMilliseconds().toString().padStart(3, "0");
|
|
163
|
-
return `${
|
|
169
|
+
return `${dateString} - ${timeString}:${ms}`;
|
|
164
170
|
}
|
|
165
|
-
}, [value, columnWidth]);
|
|
171
|
+
}, [value, columnWidth, locale]);
|
|
166
172
|
if (!formattedTime) return /* @__PURE__ */ jsx2("span", { children: "N/A" });
|
|
167
173
|
return /* @__PURE__ */ jsx2("div", { ref: cellReference, style: { width: "100%" }, children: formattedTime });
|
|
168
174
|
};
|
|
@@ -2839,24 +2845,298 @@ var SpansList = (props) => {
|
|
|
2839
2845
|
] });
|
|
2840
2846
|
};
|
|
2841
2847
|
|
|
2842
|
-
// src/
|
|
2843
|
-
import
|
|
2844
|
-
import
|
|
2848
|
+
// src/components/status-message/status-message.tsx
|
|
2849
|
+
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
|
2850
|
+
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
|
2851
|
+
import { Alert as Alert2, AlertTitle, Box as Box5, Button as Button3, Link, Typography as Typography3 } from "@mui/material";
|
|
2852
|
+
|
|
2853
|
+
// src/api/errors.ts
|
|
2854
|
+
var AppInspectorNotFoundError = class extends Error {
|
|
2855
|
+
constructor(message, cause) {
|
|
2856
|
+
super(message);
|
|
2857
|
+
this.name = "AppInspectorNotFoundError";
|
|
2858
|
+
this.cause = cause;
|
|
2859
|
+
}
|
|
2860
|
+
};
|
|
2861
|
+
var ConnectionError = class extends Error {
|
|
2862
|
+
constructor(message, cause) {
|
|
2863
|
+
super(message);
|
|
2864
|
+
this.name = "ConnectionError";
|
|
2865
|
+
this.cause = cause;
|
|
2866
|
+
}
|
|
2867
|
+
};
|
|
2845
2868
|
|
|
2846
2869
|
// src/config.ts
|
|
2847
2870
|
var APPINSPECTOR_API_PREFIX = "/_localstack/appinspector";
|
|
2848
2871
|
var API_VERSION = "v1";
|
|
2849
2872
|
var API_ENDPOINTS = {
|
|
2873
|
+
ROOT: "/",
|
|
2850
2874
|
SPANS: "/traces/*/spans",
|
|
2875
|
+
STATUS: "/status",
|
|
2851
2876
|
TRACES: "/traces"
|
|
2852
2877
|
};
|
|
2853
|
-
var
|
|
2878
|
+
var getApiV1Endpoint = (endpoint) => {
|
|
2854
2879
|
return `/${API_VERSION}${endpoint}`;
|
|
2855
2880
|
};
|
|
2881
|
+
var getApiEndpoint = (endpoint) => {
|
|
2882
|
+
if (endpoint === API_ENDPOINTS.ROOT || endpoint === API_ENDPOINTS.STATUS) {
|
|
2883
|
+
return endpoint;
|
|
2884
|
+
}
|
|
2885
|
+
return getApiV1Endpoint(endpoint);
|
|
2886
|
+
};
|
|
2856
2887
|
var getAppInspectorApiUrl = (localstackEndpoint, endpoint) => {
|
|
2857
2888
|
return `${localstackEndpoint}${APPINSPECTOR_API_PREFIX}${getApiEndpoint(endpoint)}`;
|
|
2858
2889
|
};
|
|
2859
2890
|
|
|
2891
|
+
// src/components/status-message/status-message.tsx
|
|
2892
|
+
import { jsx as jsx126, jsxs as jsxs122 } from "react/jsx-runtime";
|
|
2893
|
+
var StatusMessage = ({
|
|
2894
|
+
error,
|
|
2895
|
+
onRetry,
|
|
2896
|
+
status
|
|
2897
|
+
}) => {
|
|
2898
|
+
if (error instanceof AppInspectorNotFoundError) {
|
|
2899
|
+
return /* @__PURE__ */ jsx126(
|
|
2900
|
+
Box5,
|
|
2901
|
+
{
|
|
2902
|
+
sx: {
|
|
2903
|
+
alignItems: "center",
|
|
2904
|
+
display: "flex",
|
|
2905
|
+
flexDirection: "column",
|
|
2906
|
+
gap: 2,
|
|
2907
|
+
justifyContent: "center",
|
|
2908
|
+
p: 4
|
|
2909
|
+
},
|
|
2910
|
+
children: /* @__PURE__ */ jsxs122(
|
|
2911
|
+
Alert2,
|
|
2912
|
+
{
|
|
2913
|
+
icon: /* @__PURE__ */ jsx126(ErrorOutlineIcon, { fontSize: "large" }),
|
|
2914
|
+
severity: "error",
|
|
2915
|
+
sx: { maxWidth: 600, width: "100%" },
|
|
2916
|
+
children: [
|
|
2917
|
+
/* @__PURE__ */ jsx126(AlertTitle, { sx: { fontWeight: "bold" }, children: "App Inspector Not Available" }),
|
|
2918
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 2 }, variant: "body2", children: "The App Inspector extension is not licensed or not enabled in LocalStack." }),
|
|
2919
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1 }, variant: "body2", children: /* @__PURE__ */ jsx126("strong", { children: "To enable App Inspector:" }) }),
|
|
2920
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1 }, variant: "body2", children: "Set the environment variable and restart LocalStack:" }),
|
|
2921
|
+
/* @__PURE__ */ jsx126(
|
|
2922
|
+
Box5,
|
|
2923
|
+
{
|
|
2924
|
+
component: "pre",
|
|
2925
|
+
sx: {
|
|
2926
|
+
backgroundColor: "rgba(0, 0, 0, 0.05)",
|
|
2927
|
+
borderRadius: 1,
|
|
2928
|
+
fontSize: "0.875rem",
|
|
2929
|
+
p: 1
|
|
2930
|
+
},
|
|
2931
|
+
children: "APPINSPECTOR=1"
|
|
2932
|
+
}
|
|
2933
|
+
),
|
|
2934
|
+
/* @__PURE__ */ jsxs122(Typography3, { sx: { fontStyle: "italic", mb: 1, mt: 2 }, variant: "body2", children: [
|
|
2935
|
+
"Runtime changes can be made via endpoint",
|
|
2936
|
+
" ",
|
|
2937
|
+
/* @__PURE__ */ jsxs122("code", { children: [
|
|
2938
|
+
APPINSPECTOR_API_PREFIX,
|
|
2939
|
+
"/status"
|
|
2940
|
+
] }),
|
|
2941
|
+
". For persistent default state across restarts, adjust the",
|
|
2942
|
+
/* @__PURE__ */ jsx126("code", { children: "APPINSPECTOR" }),
|
|
2943
|
+
" ",
|
|
2944
|
+
"environment variable."
|
|
2945
|
+
] }),
|
|
2946
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1, mt: 2 }, variant: "body2", children: /* @__PURE__ */ jsx126("strong", { children: "For more information:" }) }),
|
|
2947
|
+
/* @__PURE__ */ jsx126(
|
|
2948
|
+
Link,
|
|
2949
|
+
{
|
|
2950
|
+
href: "https://docs.localstack.cloud/user-guide/tools/application-inspector/",
|
|
2951
|
+
rel: "noopener noreferrer",
|
|
2952
|
+
target: "_blank",
|
|
2953
|
+
children: "App Inspector Documentation"
|
|
2954
|
+
}
|
|
2955
|
+
),
|
|
2956
|
+
onRetry && /* @__PURE__ */ jsx126(Box5, { sx: { display: "flex", justifyContent: "flex-start", mt: 2 }, children: /* @__PURE__ */ jsx126(
|
|
2957
|
+
Button3,
|
|
2958
|
+
{
|
|
2959
|
+
"aria-label": "Check App Inspector status again",
|
|
2960
|
+
onClick: onRetry,
|
|
2961
|
+
variant: "outlined",
|
|
2962
|
+
children: "Check Again"
|
|
2963
|
+
}
|
|
2964
|
+
) })
|
|
2965
|
+
]
|
|
2966
|
+
}
|
|
2967
|
+
)
|
|
2968
|
+
}
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
if (error instanceof ConnectionError) {
|
|
2972
|
+
return /* @__PURE__ */ jsx126(
|
|
2973
|
+
Box5,
|
|
2974
|
+
{
|
|
2975
|
+
sx: {
|
|
2976
|
+
alignItems: "center",
|
|
2977
|
+
display: "flex",
|
|
2978
|
+
flexDirection: "column",
|
|
2979
|
+
gap: 2,
|
|
2980
|
+
justifyContent: "center",
|
|
2981
|
+
p: 4
|
|
2982
|
+
},
|
|
2983
|
+
children: /* @__PURE__ */ jsxs122(
|
|
2984
|
+
Alert2,
|
|
2985
|
+
{
|
|
2986
|
+
icon: /* @__PURE__ */ jsx126(ErrorOutlineIcon, { fontSize: "large" }),
|
|
2987
|
+
severity: "error",
|
|
2988
|
+
sx: { maxWidth: 600, width: "100%" },
|
|
2989
|
+
children: [
|
|
2990
|
+
/* @__PURE__ */ jsx126(AlertTitle, { sx: { fontWeight: "bold" }, children: "Connection Error" }),
|
|
2991
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 2 }, variant: "body2", children: "Failed to connect to LocalStack. Please ensure LocalStack is running and accessible." }),
|
|
2992
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1 }, variant: "body2", children: /* @__PURE__ */ jsx126("strong", { children: "To start LocalStack:" }) }),
|
|
2993
|
+
/* @__PURE__ */ jsx126(
|
|
2994
|
+
Box5,
|
|
2995
|
+
{
|
|
2996
|
+
component: "pre",
|
|
2997
|
+
sx: {
|
|
2998
|
+
backgroundColor: "rgba(0, 0, 0, 0.05)",
|
|
2999
|
+
borderRadius: 1,
|
|
3000
|
+
fontSize: "0.875rem",
|
|
3001
|
+
p: 1
|
|
3002
|
+
},
|
|
3003
|
+
children: "localstack start"
|
|
3004
|
+
}
|
|
3005
|
+
),
|
|
3006
|
+
onRetry && /* @__PURE__ */ jsx126(Box5, { sx: { display: "flex", justifyContent: "flex-start", mt: 2 }, children: /* @__PURE__ */ jsx126(
|
|
3007
|
+
Button3,
|
|
3008
|
+
{
|
|
3009
|
+
"aria-label": "Retry connection to LocalStack",
|
|
3010
|
+
onClick: onRetry,
|
|
3011
|
+
variant: "outlined",
|
|
3012
|
+
children: "Retry Connection"
|
|
3013
|
+
}
|
|
3014
|
+
) })
|
|
3015
|
+
]
|
|
3016
|
+
}
|
|
3017
|
+
)
|
|
3018
|
+
}
|
|
3019
|
+
);
|
|
3020
|
+
}
|
|
3021
|
+
if (status?.status === "DISABLED") {
|
|
3022
|
+
return /* @__PURE__ */ jsx126(
|
|
3023
|
+
Box5,
|
|
3024
|
+
{
|
|
3025
|
+
sx: {
|
|
3026
|
+
alignItems: "center",
|
|
3027
|
+
display: "flex",
|
|
3028
|
+
flexDirection: "column",
|
|
3029
|
+
gap: 2,
|
|
3030
|
+
justifyContent: "center",
|
|
3031
|
+
p: 4
|
|
3032
|
+
},
|
|
3033
|
+
children: /* @__PURE__ */ jsxs122(
|
|
3034
|
+
Alert2,
|
|
3035
|
+
{
|
|
3036
|
+
icon: /* @__PURE__ */ jsx126(InfoOutlinedIcon, { fontSize: "large" }),
|
|
3037
|
+
severity: "warning",
|
|
3038
|
+
sx: { maxWidth: 600, width: "100%" },
|
|
3039
|
+
children: [
|
|
3040
|
+
/* @__PURE__ */ jsx126(AlertTitle, { sx: { fontWeight: "bold" }, children: "App Inspector is Disabled" }),
|
|
3041
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 2 }, variant: "body2", children: "App Inspector is currently disabled. Please enable it to view traces and spans." }),
|
|
3042
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1 }, variant: "body2", children: /* @__PURE__ */ jsx126("strong", { children: "To enable App Inspector at runtime:" }) }),
|
|
3043
|
+
/* @__PURE__ */ jsx126(
|
|
3044
|
+
Box5,
|
|
3045
|
+
{
|
|
3046
|
+
component: "pre",
|
|
3047
|
+
sx: {
|
|
3048
|
+
backgroundColor: "rgba(0, 0, 0, 0.05)",
|
|
3049
|
+
borderRadius: 1,
|
|
3050
|
+
fontSize: "0.875rem",
|
|
3051
|
+
overflowX: "auto",
|
|
3052
|
+
p: 1
|
|
3053
|
+
},
|
|
3054
|
+
children: `curl -X PUT http://localhost:4566${APPINSPECTOR_API_PREFIX}/status \\
|
|
3055
|
+
-H "Content-Type: application/json" \\
|
|
3056
|
+
-d '{"status": "ENABLED"}'`
|
|
3057
|
+
}
|
|
3058
|
+
),
|
|
3059
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1, mt: 2 }, variant: "body2", children: /* @__PURE__ */ jsx126("strong", { children: "To enable App Inspector persistently across restarts:" }) }),
|
|
3060
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 1 }, variant: "body2", children: "Set the environment variable:" }),
|
|
3061
|
+
/* @__PURE__ */ jsx126(
|
|
3062
|
+
Box5,
|
|
3063
|
+
{
|
|
3064
|
+
component: "pre",
|
|
3065
|
+
sx: {
|
|
3066
|
+
backgroundColor: "rgba(0, 0, 0, 0.05)",
|
|
3067
|
+
borderRadius: 1,
|
|
3068
|
+
fontSize: "0.875rem",
|
|
3069
|
+
p: 1
|
|
3070
|
+
},
|
|
3071
|
+
children: "APPINSPECTOR=1"
|
|
3072
|
+
}
|
|
3073
|
+
),
|
|
3074
|
+
Boolean(status.note) && /* @__PURE__ */ jsx126(Typography3, { sx: { display: "block", fontStyle: "italic", mt: 2 }, variant: "caption", children: status.note }),
|
|
3075
|
+
onRetry && /* @__PURE__ */ jsx126(Box5, { sx: { display: "flex", justifyContent: "flex-start", mt: 2 }, children: /* @__PURE__ */ jsx126(
|
|
3076
|
+
Button3,
|
|
3077
|
+
{
|
|
3078
|
+
"aria-label": "Check if App Inspector is enabled",
|
|
3079
|
+
onClick: onRetry,
|
|
3080
|
+
variant: "outlined",
|
|
3081
|
+
children: "Check Status Again"
|
|
3082
|
+
}
|
|
3083
|
+
) })
|
|
3084
|
+
]
|
|
3085
|
+
}
|
|
3086
|
+
)
|
|
3087
|
+
}
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
3090
|
+
if (error) {
|
|
3091
|
+
return /* @__PURE__ */ jsx126(
|
|
3092
|
+
Box5,
|
|
3093
|
+
{
|
|
3094
|
+
sx: {
|
|
3095
|
+
alignItems: "center",
|
|
3096
|
+
display: "flex",
|
|
3097
|
+
flexDirection: "column",
|
|
3098
|
+
gap: 2,
|
|
3099
|
+
justifyContent: "center",
|
|
3100
|
+
p: 4
|
|
3101
|
+
},
|
|
3102
|
+
children: /* @__PURE__ */ jsxs122(
|
|
3103
|
+
Alert2,
|
|
3104
|
+
{
|
|
3105
|
+
icon: /* @__PURE__ */ jsx126(ErrorOutlineIcon, { fontSize: "large" }),
|
|
3106
|
+
severity: "error",
|
|
3107
|
+
sx: { maxWidth: 600, width: "100%" },
|
|
3108
|
+
children: [
|
|
3109
|
+
/* @__PURE__ */ jsx126(AlertTitle, { sx: { fontWeight: "bold" }, children: "Error" }),
|
|
3110
|
+
/* @__PURE__ */ jsx126(Typography3, { sx: { mb: 2 }, variant: "body2", children: error.message }),
|
|
3111
|
+
onRetry && /* @__PURE__ */ jsx126(Box5, { sx: { display: "flex", justifyContent: "flex-start", mt: 2 }, children: /* @__PURE__ */ jsx126(
|
|
3112
|
+
Button3,
|
|
3113
|
+
{
|
|
3114
|
+
"aria-label": "Retry operation",
|
|
3115
|
+
onClick: onRetry,
|
|
3116
|
+
variant: "outlined",
|
|
3117
|
+
children: "Retry"
|
|
3118
|
+
}
|
|
3119
|
+
) })
|
|
3120
|
+
]
|
|
3121
|
+
}
|
|
3122
|
+
)
|
|
3123
|
+
}
|
|
3124
|
+
);
|
|
3125
|
+
}
|
|
3126
|
+
return;
|
|
3127
|
+
};
|
|
3128
|
+
|
|
3129
|
+
// src/context.tsx
|
|
3130
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
3131
|
+
import { useCallback as useCallback2, useMemo as useMemo3 } from "react";
|
|
3132
|
+
|
|
3133
|
+
// src/constants/error-messages.ts
|
|
3134
|
+
var ERROR_MESSAGES = {
|
|
3135
|
+
APP_INSPECTOR_DISABLED: "App Inspector is currently disabled.",
|
|
3136
|
+
APP_INSPECTOR_NOT_FOUND: "App Inspector extension not found. Please ensure App Inspector is licensed and enabled.",
|
|
3137
|
+
CONNECTION_FAILED: "Failed to connect to LocalStack. Please ensure LocalStack is running and accessible."
|
|
3138
|
+
};
|
|
3139
|
+
|
|
2860
3140
|
// src/api/client.ts
|
|
2861
3141
|
var apiLogger = createScopedLogger("API");
|
|
2862
3142
|
var makeRequest = async (options) => {
|
|
@@ -2870,10 +3150,23 @@ var makeRequest = async (options) => {
|
|
|
2870
3150
|
headers
|
|
2871
3151
|
});
|
|
2872
3152
|
if (!response.ok) {
|
|
3153
|
+
if (response.status === 404) {
|
|
3154
|
+
throw new AppInspectorNotFoundError(
|
|
3155
|
+
ERROR_MESSAGES.APP_INSPECTOR_NOT_FOUND,
|
|
3156
|
+
new Error(`404 from ${url}: ${response.statusText}`)
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
2873
3159
|
throw new Error(`API request failed: ${response.status.toString()} ${response.statusText}`);
|
|
2874
3160
|
}
|
|
2875
3161
|
return await response.json();
|
|
2876
3162
|
} catch (error) {
|
|
3163
|
+
if (error instanceof TypeError) {
|
|
3164
|
+
const message = error.message.toLowerCase();
|
|
3165
|
+
const isNetworkError = message.includes("fetch") || message.includes("network") || message.includes("failed to fetch");
|
|
3166
|
+
if (isNetworkError) {
|
|
3167
|
+
throw new ConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
2877
3170
|
if (error instanceof Error) {
|
|
2878
3171
|
throw error;
|
|
2879
3172
|
}
|
|
@@ -2913,12 +3206,18 @@ var createApiClient = ({ localstackEndpoint }) => {
|
|
|
2913
3206
|
getSpans: async (request) => {
|
|
2914
3207
|
const endpoint = buildSpansEndpoint(request);
|
|
2915
3208
|
return makeRequest({ endpoint, localstackEndpoint });
|
|
3209
|
+
},
|
|
3210
|
+
getStatus: async () => {
|
|
3211
|
+
return makeRequest({
|
|
3212
|
+
endpoint: API_ENDPOINTS.STATUS,
|
|
3213
|
+
localstackEndpoint
|
|
3214
|
+
});
|
|
2916
3215
|
}
|
|
2917
3216
|
};
|
|
2918
3217
|
};
|
|
2919
3218
|
|
|
2920
3219
|
// src/context.tsx
|
|
2921
|
-
import { jsx as
|
|
3220
|
+
import { jsx as jsx127 } from "react/jsx-runtime";
|
|
2922
3221
|
var AppInspectorContext = createContext2(void 0);
|
|
2923
3222
|
var useAppInspector = () => {
|
|
2924
3223
|
const context = useContext2(AppInspectorContext);
|
|
@@ -2931,7 +3230,7 @@ var AppInspectorContextProvider = (props) => {
|
|
|
2931
3230
|
const api = useMemo3(() => {
|
|
2932
3231
|
return false ? createApiClientMock() : createApiClient({ localstackEndpoint: props.localstackEndpoint });
|
|
2933
3232
|
}, [props.localstackEndpoint]);
|
|
2934
|
-
return /* @__PURE__ */
|
|
3233
|
+
return /* @__PURE__ */ jsx127(ApiProvider, { api, children: /* @__PURE__ */ jsx127(
|
|
2935
3234
|
AppInspectorContext.Provider,
|
|
2936
3235
|
{
|
|
2937
3236
|
value: {
|
|
@@ -2955,17 +3254,60 @@ var AppInspectorContextProvider = (props) => {
|
|
|
2955
3254
|
) });
|
|
2956
3255
|
};
|
|
2957
3256
|
|
|
3257
|
+
// src/hooks/use-status.tsx
|
|
3258
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
|
|
3259
|
+
var useStatus = () => {
|
|
3260
|
+
const api = useAppInspectorApi();
|
|
3261
|
+
const [checking, setChecking] = useState3(true);
|
|
3262
|
+
const [status, setStatus] = useState3();
|
|
3263
|
+
const [error, setError] = useState3();
|
|
3264
|
+
const hasFetchedReference = useRef2(false);
|
|
3265
|
+
const abortControllerReference = useRef2(null);
|
|
3266
|
+
const checkStatus = useCallback3(async () => {
|
|
3267
|
+
if (abortControllerReference.current) {
|
|
3268
|
+
abortControllerReference.current.abort();
|
|
3269
|
+
}
|
|
3270
|
+
const abortController = new AbortController();
|
|
3271
|
+
abortControllerReference.current = abortController;
|
|
3272
|
+
setChecking(true);
|
|
3273
|
+
try {
|
|
3274
|
+
const response = await api.getStatus();
|
|
3275
|
+
if (!abortController.signal.aborted) {
|
|
3276
|
+
setStatus(response);
|
|
3277
|
+
setError(void 0);
|
|
3278
|
+
}
|
|
3279
|
+
} catch (error_) {
|
|
3280
|
+
if (!abortController.signal.aborted) {
|
|
3281
|
+
setError(error_ instanceof Error ? error_ : new Error("Unknown error"));
|
|
3282
|
+
setStatus(void 0);
|
|
3283
|
+
}
|
|
3284
|
+
} finally {
|
|
3285
|
+
if (!abortController.signal.aborted) {
|
|
3286
|
+
setChecking(false);
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
}, [api]);
|
|
3290
|
+
useEffect2(() => {
|
|
3291
|
+
if (!hasFetchedReference.current) {
|
|
3292
|
+
hasFetchedReference.current = true;
|
|
3293
|
+
void checkStatus();
|
|
3294
|
+
}
|
|
3295
|
+
}, [checkStatus]);
|
|
3296
|
+
return { checking, checkStatus, error, status };
|
|
3297
|
+
};
|
|
3298
|
+
|
|
2958
3299
|
// src/pages/spans-list-page.tsx
|
|
2959
|
-
import { jsx as
|
|
3300
|
+
import { jsx as jsx128 } from "react/jsx-runtime";
|
|
2960
3301
|
var MAX_WIDTH = 1400;
|
|
2961
3302
|
var SpansListPage = () => {
|
|
2962
3303
|
const api = useAppInspectorApi();
|
|
2963
|
-
const [spans, setSpans] =
|
|
2964
|
-
const [loading, setLoading] =
|
|
2965
|
-
const hasFetched =
|
|
2966
|
-
const [filterWriteOperations, setFilterWriteOperations] =
|
|
2967
|
-
const [fetchError, setFetchError] =
|
|
2968
|
-
const
|
|
3304
|
+
const [spans, setSpans] = useState4();
|
|
3305
|
+
const [loading, setLoading] = useState4(false);
|
|
3306
|
+
const hasFetched = useRef3(false);
|
|
3307
|
+
const [filterWriteOperations, setFilterWriteOperations] = useState4(true);
|
|
3308
|
+
const [fetchError, setFetchError] = useState4();
|
|
3309
|
+
const { checkStatus, error: statusError, status } = useStatus();
|
|
3310
|
+
const fetchSpans = useCallback4(async () => {
|
|
2969
3311
|
setLoading(true);
|
|
2970
3312
|
try {
|
|
2971
3313
|
const response = await api.getSpans({
|
|
@@ -2981,25 +3323,26 @@ var SpansListPage = () => {
|
|
|
2981
3323
|
setLoading(false);
|
|
2982
3324
|
}
|
|
2983
3325
|
}, [api, filterWriteOperations]);
|
|
2984
|
-
const fetchSpansSync =
|
|
3326
|
+
const fetchSpansSync = useCallback4(() => {
|
|
2985
3327
|
void fetchSpans();
|
|
2986
3328
|
}, [fetchSpans]);
|
|
2987
|
-
|
|
3329
|
+
useEffect3(() => {
|
|
2988
3330
|
if (hasFetched.current) return;
|
|
3331
|
+
if (status?.status !== "ENABLED") return;
|
|
2989
3332
|
hasFetched.current = true;
|
|
2990
3333
|
void fetchSpans();
|
|
2991
|
-
}, [fetchSpans]);
|
|
2992
|
-
|
|
3334
|
+
}, [fetchSpans, status]);
|
|
3335
|
+
useEffect3(() => {
|
|
2993
3336
|
if (!hasFetched.current) return;
|
|
2994
3337
|
void fetchSpans();
|
|
2995
3338
|
}, [fetchSpans]);
|
|
2996
3339
|
const navigate = useNavigate();
|
|
2997
3340
|
const { resolveLink } = useAppInspector();
|
|
2998
|
-
const navigateToSpan =
|
|
3341
|
+
const navigateToSpan = useCallback4((span) => {
|
|
2999
3342
|
const url = resolveLink({ to: "trace-graph", traceId: span.trace_id });
|
|
3000
3343
|
navigate(`${url}?spanId=${span.span_id}`);
|
|
3001
3344
|
}, [navigate, resolveLink]);
|
|
3002
|
-
const clearSpans =
|
|
3345
|
+
const clearSpans = useCallback4(async () => {
|
|
3003
3346
|
setLoading(true);
|
|
3004
3347
|
try {
|
|
3005
3348
|
await api.deleteSpans();
|
|
@@ -3013,8 +3356,12 @@ var SpansListPage = () => {
|
|
|
3013
3356
|
setLoading(false);
|
|
3014
3357
|
}
|
|
3015
3358
|
}, [api, fetchSpans]);
|
|
3016
|
-
|
|
3017
|
-
|
|
3359
|
+
const handleRetry = useCallback4(() => {
|
|
3360
|
+
void checkStatus();
|
|
3361
|
+
}, [checkStatus]);
|
|
3362
|
+
const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
|
|
3363
|
+
return /* @__PURE__ */ jsx128(
|
|
3364
|
+
Box6,
|
|
3018
3365
|
{
|
|
3019
3366
|
"data-testid": "spans-list-page",
|
|
3020
3367
|
sx: {
|
|
@@ -3024,8 +3371,8 @@ var SpansListPage = () => {
|
|
|
3024
3371
|
height: "100vh",
|
|
3025
3372
|
width: "100%"
|
|
3026
3373
|
},
|
|
3027
|
-
children: /* @__PURE__ */
|
|
3028
|
-
|
|
3374
|
+
children: /* @__PURE__ */ jsx128(
|
|
3375
|
+
Box6,
|
|
3029
3376
|
{
|
|
3030
3377
|
sx: {
|
|
3031
3378
|
display: "flex",
|
|
@@ -3034,7 +3381,14 @@ var SpansListPage = () => {
|
|
|
3034
3381
|
maxWidth: MAX_WIDTH,
|
|
3035
3382
|
width: "100%"
|
|
3036
3383
|
},
|
|
3037
|
-
children: /* @__PURE__ */
|
|
3384
|
+
children: shouldShowStatusMessage ? /* @__PURE__ */ jsx128(
|
|
3385
|
+
StatusMessage,
|
|
3386
|
+
{
|
|
3387
|
+
error: statusError,
|
|
3388
|
+
onRetry: handleRetry,
|
|
3389
|
+
status
|
|
3390
|
+
}
|
|
3391
|
+
) : /* @__PURE__ */ jsx128(
|
|
3038
3392
|
SpansList,
|
|
3039
3393
|
{
|
|
3040
3394
|
filterWriteOperations,
|
|
@@ -3064,22 +3418,22 @@ var SpansListPage = () => {
|
|
|
3064
3418
|
};
|
|
3065
3419
|
|
|
3066
3420
|
// src/pages/trace-graph.tsx
|
|
3067
|
-
import { Box as
|
|
3421
|
+
import { Box as Box12, Drawer, Paper as Paper2 } from "@mui/material";
|
|
3068
3422
|
import { styled } from "@mui/material/styles";
|
|
3069
3423
|
import { ReactFlowProvider } from "@xyflow/react";
|
|
3070
|
-
import { useCallback as
|
|
3424
|
+
import { useCallback as useCallback7, useEffect as useEffect5, useState as useState7 } from "react";
|
|
3071
3425
|
import { useParams, useSearchParams } from "react-router-dom";
|
|
3072
3426
|
|
|
3073
3427
|
// src/components/event-details/event-details.tsx
|
|
3074
|
-
import { Box as
|
|
3428
|
+
import { Box as Box9, Chip, Divider, Stack, Typography as Typography6 } from "@mui/material";
|
|
3075
3429
|
|
|
3076
3430
|
// src/components/event-details/event-details-header.tsx
|
|
3077
3431
|
import { Close } from "@mui/icons-material";
|
|
3078
|
-
import { Box as
|
|
3079
|
-
import { jsx as
|
|
3432
|
+
import { Box as Box7, IconButton, Typography as Typography4 } from "@mui/material";
|
|
3433
|
+
import { jsx as jsx129, jsxs as jsxs123 } from "react/jsx-runtime";
|
|
3080
3434
|
var EventDetailsHeader = ({ event, onClose }) => {
|
|
3081
|
-
return /* @__PURE__ */
|
|
3082
|
-
|
|
3435
|
+
return /* @__PURE__ */ jsxs123(
|
|
3436
|
+
Box7,
|
|
3083
3437
|
{
|
|
3084
3438
|
sx: {
|
|
3085
3439
|
alignItems: "center",
|
|
@@ -3090,16 +3444,16 @@ var EventDetailsHeader = ({ event, onClose }) => {
|
|
|
3090
3444
|
p: 2
|
|
3091
3445
|
},
|
|
3092
3446
|
children: [
|
|
3093
|
-
/* @__PURE__ */
|
|
3094
|
-
/* @__PURE__ */
|
|
3095
|
-
/* @__PURE__ */
|
|
3447
|
+
/* @__PURE__ */ jsxs123(Box7, { children: [
|
|
3448
|
+
/* @__PURE__ */ jsx129(Typography4, { sx: { fontWeight: 600 }, variant: "h6", children: "Event Details" }),
|
|
3449
|
+
/* @__PURE__ */ jsxs123(Typography4, { color: "text.secondary", variant: "body2", children: [
|
|
3096
3450
|
event.service_name,
|
|
3097
3451
|
" ",
|
|
3098
3452
|
"-",
|
|
3099
3453
|
event.operation_name
|
|
3100
3454
|
] })
|
|
3101
3455
|
] }),
|
|
3102
|
-
onClose && /* @__PURE__ */
|
|
3456
|
+
onClose && /* @__PURE__ */ jsx129(IconButton, { onClick: onClose, size: "small", children: /* @__PURE__ */ jsx129(Close, {}) })
|
|
3103
3457
|
]
|
|
3104
3458
|
}
|
|
3105
3459
|
);
|
|
@@ -3107,14 +3461,14 @@ var EventDetailsHeader = ({ event, onClose }) => {
|
|
|
3107
3461
|
|
|
3108
3462
|
// src/components/event-details/toggle-section.tsx
|
|
3109
3463
|
import { KeyboardArrowDown, KeyboardArrowRight } from "@mui/icons-material";
|
|
3110
|
-
import { Box as
|
|
3111
|
-
import { useState as
|
|
3112
|
-
import { jsx as
|
|
3464
|
+
import { Box as Box8, Typography as Typography5 } from "@mui/material";
|
|
3465
|
+
import { useState as useState5 } from "react";
|
|
3466
|
+
import { jsx as jsx130, jsxs as jsxs124 } from "react/jsx-runtime";
|
|
3113
3467
|
var ToggleSection = ({ children, headline, initialOpen = true }) => {
|
|
3114
|
-
const [isOpen, setIsOpen] =
|
|
3115
|
-
return /* @__PURE__ */
|
|
3116
|
-
/* @__PURE__ */
|
|
3117
|
-
|
|
3468
|
+
const [isOpen, setIsOpen] = useState5(initialOpen);
|
|
3469
|
+
return /* @__PURE__ */ jsxs124(Box8, { sx: { mt: 4 }, children: [
|
|
3470
|
+
/* @__PURE__ */ jsx130(
|
|
3471
|
+
Box8,
|
|
3118
3472
|
{
|
|
3119
3473
|
onClick: () => {
|
|
3120
3474
|
setIsOpen(!isOpen);
|
|
@@ -3123,8 +3477,8 @@ var ToggleSection = ({ children, headline, initialOpen = true }) => {
|
|
|
3123
3477
|
cursor: "pointer",
|
|
3124
3478
|
mb: 1
|
|
3125
3479
|
},
|
|
3126
|
-
children: /* @__PURE__ */
|
|
3127
|
-
|
|
3480
|
+
children: /* @__PURE__ */ jsxs124(
|
|
3481
|
+
Box8,
|
|
3128
3482
|
{
|
|
3129
3483
|
role: "button",
|
|
3130
3484
|
sx: {
|
|
@@ -3133,73 +3487,73 @@ var ToggleSection = ({ children, headline, initialOpen = true }) => {
|
|
|
3133
3487
|
gap: 1
|
|
3134
3488
|
},
|
|
3135
3489
|
children: [
|
|
3136
|
-
/* @__PURE__ */
|
|
3137
|
-
isOpen ? /* @__PURE__ */
|
|
3490
|
+
/* @__PURE__ */ jsx130(Typography5, { sx: { fontWeight: 600 }, variant: "subtitle2", children: headline }),
|
|
3491
|
+
isOpen ? /* @__PURE__ */ jsx130(KeyboardArrowDown, { sx: { color: "text.secondary", height: 20, width: 20 } }) : /* @__PURE__ */ jsx130(KeyboardArrowRight, { sx: { color: "text.secondary", height: 20, width: 20 } })
|
|
3138
3492
|
]
|
|
3139
3493
|
}
|
|
3140
3494
|
)
|
|
3141
3495
|
}
|
|
3142
3496
|
),
|
|
3143
|
-
isOpen && /* @__PURE__ */
|
|
3497
|
+
isOpen && /* @__PURE__ */ jsx130(Box8, { children })
|
|
3144
3498
|
] });
|
|
3145
3499
|
};
|
|
3146
3500
|
|
|
3147
3501
|
// src/components/event-details/event-details.tsx
|
|
3148
|
-
import { Fragment as Fragment2, jsx as
|
|
3502
|
+
import { Fragment as Fragment2, jsx as jsx131, jsxs as jsxs125 } from "react/jsx-runtime";
|
|
3149
3503
|
var EventDetails = ({ selectedEvent }) => {
|
|
3150
3504
|
if (!selectedEvent) {
|
|
3151
|
-
return /* @__PURE__ */
|
|
3505
|
+
return /* @__PURE__ */ jsx131(Box9, { sx: { p: 3, textAlign: "center" }, children: /* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "body2", children: "Select an event to view details" }) });
|
|
3152
3506
|
}
|
|
3153
|
-
return /* @__PURE__ */
|
|
3154
|
-
/* @__PURE__ */
|
|
3155
|
-
/* @__PURE__ */
|
|
3156
|
-
/* @__PURE__ */
|
|
3157
|
-
/* @__PURE__ */
|
|
3158
|
-
/* @__PURE__ */
|
|
3159
|
-
/* @__PURE__ */
|
|
3507
|
+
return /* @__PURE__ */ jsxs125(Box9, { "data-testid": "event-details", sx: { display: "flex", flexDirection: "column", height: "100%" }, children: [
|
|
3508
|
+
/* @__PURE__ */ jsx131(EventDetailsHeader, { event: selectedEvent }),
|
|
3509
|
+
/* @__PURE__ */ jsx131(Box9, { sx: { flexGrow: 1, overflow: "auto", p: 2 }, children: /* @__PURE__ */ jsxs125(Stack, { spacing: 2, children: [
|
|
3510
|
+
/* @__PURE__ */ jsx131(ToggleSection, { headline: "Basic Information", children: /* @__PURE__ */ jsxs125(Stack, { spacing: 1, children: [
|
|
3511
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3512
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Span ID" }),
|
|
3513
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.span_id })
|
|
3160
3514
|
] }),
|
|
3161
|
-
/* @__PURE__ */
|
|
3162
|
-
/* @__PURE__ */
|
|
3163
|
-
/* @__PURE__ */
|
|
3515
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3516
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Trace ID" }),
|
|
3517
|
+
/* @__PURE__ */ jsx131(Typography6, { sx: { fontFamily: "monospace", fontSize: "0.85rem" }, variant: "body2", children: selectedEvent.trace_id })
|
|
3164
3518
|
] }),
|
|
3165
|
-
/* @__PURE__ */
|
|
3166
|
-
/* @__PURE__ */
|
|
3167
|
-
/* @__PURE__ */
|
|
3519
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3520
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Operation" }),
|
|
3521
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.operation_name })
|
|
3168
3522
|
] })
|
|
3169
3523
|
] }) }),
|
|
3170
|
-
/* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3172
|
-
/* @__PURE__ */
|
|
3173
|
-
/* @__PURE__ */
|
|
3174
|
-
/* @__PURE__ */
|
|
3524
|
+
/* @__PURE__ */ jsx131(Divider, {}),
|
|
3525
|
+
/* @__PURE__ */ jsx131(ToggleSection, { headline: "Service Information", children: /* @__PURE__ */ jsxs125(Stack, { spacing: 1, children: [
|
|
3526
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3527
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Service" }),
|
|
3528
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.service_name })
|
|
3175
3529
|
] }),
|
|
3176
|
-
/* @__PURE__ */
|
|
3177
|
-
/* @__PURE__ */
|
|
3178
|
-
/* @__PURE__ */
|
|
3530
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3531
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Resource" }),
|
|
3532
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.resource_name })
|
|
3179
3533
|
] }),
|
|
3180
|
-
selectedEvent.region && /* @__PURE__ */
|
|
3181
|
-
/* @__PURE__ */
|
|
3182
|
-
/* @__PURE__ */
|
|
3534
|
+
selectedEvent.region && /* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3535
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Region" }),
|
|
3536
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.region })
|
|
3183
3537
|
] })
|
|
3184
3538
|
] }) }),
|
|
3185
|
-
/* @__PURE__ */
|
|
3186
|
-
/* @__PURE__ */
|
|
3187
|
-
/* @__PURE__ */
|
|
3188
|
-
/* @__PURE__ */
|
|
3189
|
-
/* @__PURE__ */
|
|
3539
|
+
/* @__PURE__ */ jsx131(Divider, {}),
|
|
3540
|
+
/* @__PURE__ */ jsx131(ToggleSection, { headline: "Timing", children: /* @__PURE__ */ jsxs125(Stack, { spacing: 1, children: [
|
|
3541
|
+
/* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3542
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Start Time" }),
|
|
3543
|
+
/* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: unixNanoToDate(selectedEvent.start_time_unix_nano)?.toISOString() })
|
|
3190
3544
|
] }),
|
|
3191
|
-
selectedEvent.end_time_unix_nano && /* @__PURE__ */
|
|
3192
|
-
/* @__PURE__ */
|
|
3193
|
-
/* @__PURE__ */
|
|
3545
|
+
selectedEvent.end_time_unix_nano && /* @__PURE__ */ jsxs125(Box9, { children: [
|
|
3546
|
+
/* @__PURE__ */ jsx131(Typography6, { color: "text.secondary", variant: "caption", children: "Duration" }),
|
|
3547
|
+
/* @__PURE__ */ jsxs125(Typography6, { variant: "body2", children: [
|
|
3194
3548
|
((BigInt(selectedEvent.end_time_unix_nano) - BigInt(selectedEvent.start_time_unix_nano)) / BigInt("1000000")).toString(),
|
|
3195
3549
|
" ",
|
|
3196
3550
|
"ms"
|
|
3197
3551
|
] })
|
|
3198
3552
|
] })
|
|
3199
3553
|
] }) }),
|
|
3200
|
-
/* @__PURE__ */
|
|
3201
|
-
/* @__PURE__ */
|
|
3202
|
-
/* @__PURE__ */
|
|
3554
|
+
/* @__PURE__ */ jsx131(Divider, {}),
|
|
3555
|
+
/* @__PURE__ */ jsx131(ToggleSection, { headline: "Status", children: /* @__PURE__ */ jsxs125(Stack, { direction: "row", spacing: 1, children: [
|
|
3556
|
+
/* @__PURE__ */ jsx131(
|
|
3203
3557
|
Chip,
|
|
3204
3558
|
{
|
|
3205
3559
|
color: selectedEvent.status_code === 0 ? "success" : "error",
|
|
@@ -3207,11 +3561,11 @@ var EventDetails = ({ selectedEvent }) => {
|
|
|
3207
3561
|
size: "small"
|
|
3208
3562
|
}
|
|
3209
3563
|
),
|
|
3210
|
-
selectedEvent.status_message && /* @__PURE__ */
|
|
3564
|
+
selectedEvent.status_message && /* @__PURE__ */ jsx131(Typography6, { variant: "body2", children: selectedEvent.status_message })
|
|
3211
3565
|
] }) }),
|
|
3212
|
-
selectedEvent.attributes && Object.keys(selectedEvent.attributes).length > 0 && /* @__PURE__ */
|
|
3213
|
-
/* @__PURE__ */
|
|
3214
|
-
/* @__PURE__ */
|
|
3566
|
+
selectedEvent.attributes && Object.keys(selectedEvent.attributes).length > 0 && /* @__PURE__ */ jsxs125(Fragment2, { children: [
|
|
3567
|
+
/* @__PURE__ */ jsx131(Divider, {}),
|
|
3568
|
+
/* @__PURE__ */ jsx131(ToggleSection, { headline: "Attributes", children: /* @__PURE__ */ jsx131(Box9, { sx: { backgroundColor: "#f5f5f5", borderRadius: 1, p: 1 }, children: /* @__PURE__ */ jsx131("pre", { style: { fontSize: "0.85rem", margin: 0, overflow: "auto" }, children: JSON.stringify(selectedEvent.attributes, void 0, 2) }) }) })
|
|
3215
3569
|
] })
|
|
3216
3570
|
] }) })
|
|
3217
3571
|
] });
|
|
@@ -3219,32 +3573,32 @@ var EventDetails = ({ selectedEvent }) => {
|
|
|
3219
3573
|
|
|
3220
3574
|
// src/components/trace-graph/trace-graph.tsx
|
|
3221
3575
|
import "@xyflow/react/dist/base.css";
|
|
3222
|
-
import { Alert as
|
|
3576
|
+
import { Alert as Alert3, Button as Button4 } from "@mui/material";
|
|
3223
3577
|
import { Background, Controls, ReactFlow, useReactFlow, useStoreApi } from "@xyflow/react";
|
|
3224
|
-
import { useCallback as
|
|
3578
|
+
import { useCallback as useCallback6, useEffect as useEffect4, useState as useState6 } from "react";
|
|
3225
3579
|
|
|
3226
3580
|
// src/components/trace-graph/service-node.tsx
|
|
3227
|
-
import { Box as
|
|
3581
|
+
import { Box as Box11, Stack as Stack2, Typography as Typography7 } from "@mui/material";
|
|
3228
3582
|
import "@xyflow/react/dist/style.css";
|
|
3229
3583
|
import { Handle, Position } from "@xyflow/react";
|
|
3230
|
-
import { memo, useCallback as
|
|
3584
|
+
import { memo, useCallback as useCallback5 } from "react";
|
|
3231
3585
|
|
|
3232
3586
|
// src/components/trace-graph/problem-indicator.tsx
|
|
3233
3587
|
import { Error as ErrorIcon, Info, Warning } from "@mui/icons-material";
|
|
3234
|
-
import { Box as
|
|
3588
|
+
import { Box as Box10, Tooltip as Tooltip2 } from "@mui/material";
|
|
3235
3589
|
import { useMemo as useMemo4 } from "react";
|
|
3236
|
-
import { jsx as
|
|
3590
|
+
import { jsx as jsx132 } from "react/jsx-runtime";
|
|
3237
3591
|
var ProblemIndicator = ({ error }) => {
|
|
3238
3592
|
const icon = useMemo4(() => {
|
|
3239
3593
|
switch (error.level) {
|
|
3240
3594
|
case "error": {
|
|
3241
|
-
return /* @__PURE__ */
|
|
3595
|
+
return /* @__PURE__ */ jsx132(ErrorIcon, { sx: { color: "#d32f2f", fontSize: "14px" } });
|
|
3242
3596
|
}
|
|
3243
3597
|
case "warning": {
|
|
3244
|
-
return /* @__PURE__ */
|
|
3598
|
+
return /* @__PURE__ */ jsx132(Warning, { sx: { color: "#ff9800", fontSize: "14px" } });
|
|
3245
3599
|
}
|
|
3246
3600
|
default: {
|
|
3247
|
-
return /* @__PURE__ */
|
|
3601
|
+
return /* @__PURE__ */ jsx132(Info, { sx: { color: "#2196f3", fontSize: "14px" } });
|
|
3248
3602
|
}
|
|
3249
3603
|
}
|
|
3250
3604
|
}, [error.level]);
|
|
@@ -3261,8 +3615,8 @@ var ProblemIndicator = ({ error }) => {
|
|
|
3261
3615
|
}
|
|
3262
3616
|
}
|
|
3263
3617
|
}, [error.level]);
|
|
3264
|
-
return /* @__PURE__ */
|
|
3265
|
-
|
|
3618
|
+
return /* @__PURE__ */ jsx132(Tooltip2, { arrow: true, title: error.message ?? "Issue detected", children: /* @__PURE__ */ jsx132(
|
|
3619
|
+
Box10,
|
|
3266
3620
|
{
|
|
3267
3621
|
sx: {
|
|
3268
3622
|
alignItems: "center",
|
|
@@ -3281,17 +3635,17 @@ var ProblemIndicator = ({ error }) => {
|
|
|
3281
3635
|
};
|
|
3282
3636
|
|
|
3283
3637
|
// src/components/trace-graph/service-node.tsx
|
|
3284
|
-
import { jsx as
|
|
3638
|
+
import { jsx as jsx133, jsxs as jsxs126 } from "react/jsx-runtime";
|
|
3285
3639
|
var handleStyle = {
|
|
3286
3640
|
backgroundColor: "white",
|
|
3287
3641
|
borderColor: "lightgray",
|
|
3288
3642
|
opacity: 0
|
|
3289
3643
|
};
|
|
3290
3644
|
var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
3291
|
-
const handleClick =
|
|
3645
|
+
const handleClick = useCallback5(() => {
|
|
3292
3646
|
data.onEventSelect(data.event);
|
|
3293
3647
|
}, [data]);
|
|
3294
|
-
const handleKeyPress =
|
|
3648
|
+
const handleKeyPress = useCallback5(
|
|
3295
3649
|
(event) => {
|
|
3296
3650
|
if (event.key === "Enter" || event.key === " ") {
|
|
3297
3651
|
handleClick();
|
|
@@ -3300,9 +3654,9 @@ var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
|
3300
3654
|
[handleClick]
|
|
3301
3655
|
);
|
|
3302
3656
|
const hasErrors = (data.event.errors && data.event.errors.length > 0) ?? false;
|
|
3303
|
-
return /* @__PURE__ */
|
|
3304
|
-
/* @__PURE__ */
|
|
3305
|
-
|
|
3657
|
+
return /* @__PURE__ */ jsxs126(Box11, { sx: { maxWidth: 200 }, children: [
|
|
3658
|
+
/* @__PURE__ */ jsxs126(
|
|
3659
|
+
Box11,
|
|
3306
3660
|
{
|
|
3307
3661
|
onClick: handleClick,
|
|
3308
3662
|
onKeyPress: handleKeyPress,
|
|
@@ -3324,9 +3678,9 @@ var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
|
3324
3678
|
},
|
|
3325
3679
|
tabIndex: 0,
|
|
3326
3680
|
children: [
|
|
3327
|
-
/* @__PURE__ */
|
|
3328
|
-
/* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
3681
|
+
/* @__PURE__ */ jsx133(Handle, { position: Position.Left, style: handleStyle, type: "target" }),
|
|
3682
|
+
/* @__PURE__ */ jsx133(Handle, { position: Position.Right, style: handleStyle, type: "source" }),
|
|
3683
|
+
/* @__PURE__ */ jsx133(
|
|
3330
3684
|
ServiceCell,
|
|
3331
3685
|
{
|
|
3332
3686
|
borderColor: selected ? "black" : "lightgray",
|
|
@@ -3340,7 +3694,7 @@ var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
|
3340
3694
|
]
|
|
3341
3695
|
}
|
|
3342
3696
|
),
|
|
3343
|
-
/* @__PURE__ */
|
|
3697
|
+
/* @__PURE__ */ jsxs126(
|
|
3344
3698
|
Stack2,
|
|
3345
3699
|
{
|
|
3346
3700
|
alignItems: "center",
|
|
@@ -3351,7 +3705,7 @@ var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
|
3351
3705
|
mt: 0.5
|
|
3352
3706
|
},
|
|
3353
3707
|
children: [
|
|
3354
|
-
hasErrors && /* @__PURE__ */
|
|
3708
|
+
hasErrors && /* @__PURE__ */ jsx133(
|
|
3355
3709
|
Stack2,
|
|
3356
3710
|
{
|
|
3357
3711
|
direction: "row",
|
|
@@ -3360,11 +3714,11 @@ var ServiceNode = memo(function ServiceNode2({ data, selected }) {
|
|
|
3360
3714
|
flexWrap: "wrap",
|
|
3361
3715
|
gap: "2px"
|
|
3362
3716
|
},
|
|
3363
|
-
children: data.event.errors?.map((error) => /* @__PURE__ */
|
|
3717
|
+
children: data.event.errors?.map((error) => /* @__PURE__ */ jsx133(ProblemIndicator, { error }, error.span_id))
|
|
3364
3718
|
}
|
|
3365
3719
|
),
|
|
3366
|
-
/* @__PURE__ */
|
|
3367
|
-
|
|
3720
|
+
/* @__PURE__ */ jsx133(
|
|
3721
|
+
Typography7,
|
|
3368
3722
|
{
|
|
3369
3723
|
sx: {
|
|
3370
3724
|
fontSize: "0.9rem",
|
|
@@ -3477,7 +3831,7 @@ var calculateCenterX = (focusNodeX, viewPortPixelWidth, minX, maxX) => {
|
|
|
3477
3831
|
};
|
|
3478
3832
|
|
|
3479
3833
|
// src/components/trace-graph/trace-graph.tsx
|
|
3480
|
-
import { Fragment as Fragment3, jsx as
|
|
3834
|
+
import { Fragment as Fragment3, jsx as jsx134, jsxs as jsxs127 } from "react/jsx-runtime";
|
|
3481
3835
|
var nodeTypes = {
|
|
3482
3836
|
service: ServiceNode
|
|
3483
3837
|
};
|
|
@@ -3487,15 +3841,15 @@ var TraceGraph = ({
|
|
|
3487
3841
|
traceId,
|
|
3488
3842
|
viewPortPixelWidth
|
|
3489
3843
|
}) => {
|
|
3490
|
-
const [nodes, setNodes] =
|
|
3491
|
-
const [edges, setEdges] =
|
|
3492
|
-
const [isLoading, setIsLoading] =
|
|
3493
|
-
const [initialViewSet, setInitialViewSet] =
|
|
3844
|
+
const [nodes, setNodes] = useState6([]);
|
|
3845
|
+
const [edges, setEdges] = useState6([]);
|
|
3846
|
+
const [isLoading, setIsLoading] = useState6(true);
|
|
3847
|
+
const [initialViewSet, setInitialViewSet] = useState6(false);
|
|
3494
3848
|
const { fitView, setCenter } = useReactFlow();
|
|
3495
3849
|
const store = useStoreApi();
|
|
3496
3850
|
const api = useAppInspectorApi();
|
|
3497
|
-
const [fetchError, setFetchError] =
|
|
3498
|
-
const updateSelectedNode =
|
|
3851
|
+
const [fetchError, setFetchError] = useState6();
|
|
3852
|
+
const updateSelectedNode = useCallback6(
|
|
3499
3853
|
(nodeId) => {
|
|
3500
3854
|
const { addSelectedNodes } = store.getState();
|
|
3501
3855
|
if (nodeId) {
|
|
@@ -3507,7 +3861,7 @@ var TraceGraph = ({
|
|
|
3507
3861
|
},
|
|
3508
3862
|
[nodes, store]
|
|
3509
3863
|
);
|
|
3510
|
-
const fetchTrace =
|
|
3864
|
+
const fetchTrace = useCallback6(async () => {
|
|
3511
3865
|
setIsLoading(true);
|
|
3512
3866
|
try {
|
|
3513
3867
|
const response = await api.getSpans({ trace_id: traceId });
|
|
@@ -3550,13 +3904,13 @@ var TraceGraph = ({
|
|
|
3550
3904
|
setIsLoading(false);
|
|
3551
3905
|
}
|
|
3552
3906
|
}, [api, traceId, onEventSelect]);
|
|
3553
|
-
const fetchTraceSync =
|
|
3907
|
+
const fetchTraceSync = useCallback6(() => {
|
|
3554
3908
|
void fetchTrace();
|
|
3555
3909
|
}, [fetchTrace]);
|
|
3556
|
-
|
|
3910
|
+
useEffect4(() => {
|
|
3557
3911
|
fetchTraceSync();
|
|
3558
3912
|
}, [fetchTraceSync]);
|
|
3559
|
-
|
|
3913
|
+
useEffect4(() => {
|
|
3560
3914
|
const shouldSetInitialView = !isLoading && nodes.length > 0 && !initialViewSet;
|
|
3561
3915
|
if (shouldSetInitialView) {
|
|
3562
3916
|
if (initialFocusEventId) {
|
|
@@ -3576,20 +3930,20 @@ var TraceGraph = ({
|
|
|
3576
3930
|
setInitialViewSet(true);
|
|
3577
3931
|
}
|
|
3578
3932
|
}, [isLoading, nodes, initialFocusEventId, viewPortPixelWidth, setCenter, fitView, onEventSelect, initialViewSet]);
|
|
3579
|
-
|
|
3933
|
+
useEffect4(() => {
|
|
3580
3934
|
if (initialFocusEventId) {
|
|
3581
3935
|
updateSelectedNode(initialFocusEventId);
|
|
3582
3936
|
}
|
|
3583
3937
|
}, [initialFocusEventId, updateSelectedNode]);
|
|
3584
|
-
const onNodeClick =
|
|
3938
|
+
const onNodeClick = useCallback6((_event, node) => {
|
|
3585
3939
|
onEventSelect(node.data.event);
|
|
3586
3940
|
updateSelectedNode(node.id);
|
|
3587
3941
|
}, [onEventSelect, updateSelectedNode]);
|
|
3588
|
-
return /* @__PURE__ */
|
|
3589
|
-
fetchError && /* @__PURE__ */
|
|
3590
|
-
|
|
3942
|
+
return /* @__PURE__ */ jsxs127(Fragment3, { children: [
|
|
3943
|
+
fetchError && /* @__PURE__ */ jsxs127(
|
|
3944
|
+
Alert3,
|
|
3591
3945
|
{
|
|
3592
|
-
action: /* @__PURE__ */
|
|
3946
|
+
action: /* @__PURE__ */ jsx134(Button4, { onClick: fetchTraceSync, children: "Retry" }),
|
|
3593
3947
|
severity: "error",
|
|
3594
3948
|
children: [
|
|
3595
3949
|
"Unexpected error:",
|
|
@@ -3598,7 +3952,7 @@ var TraceGraph = ({
|
|
|
3598
3952
|
]
|
|
3599
3953
|
}
|
|
3600
3954
|
),
|
|
3601
|
-
/* @__PURE__ */
|
|
3955
|
+
/* @__PURE__ */ jsxs127(
|
|
3602
3956
|
ReactFlow,
|
|
3603
3957
|
{
|
|
3604
3958
|
"data-testid": "trace-graph",
|
|
@@ -3612,8 +3966,8 @@ var TraceGraph = ({
|
|
|
3612
3966
|
onNodeClick,
|
|
3613
3967
|
selectNodesOnDrag: false,
|
|
3614
3968
|
children: [
|
|
3615
|
-
/* @__PURE__ */
|
|
3616
|
-
/* @__PURE__ */
|
|
3969
|
+
/* @__PURE__ */ jsx134(Controls, { showInteractive: false }),
|
|
3970
|
+
/* @__PURE__ */ jsx134(Background, {})
|
|
3617
3971
|
]
|
|
3618
3972
|
}
|
|
3619
3973
|
)
|
|
@@ -3621,7 +3975,7 @@ var TraceGraph = ({
|
|
|
3621
3975
|
};
|
|
3622
3976
|
|
|
3623
3977
|
// src/pages/trace-graph.tsx
|
|
3624
|
-
import { jsx as
|
|
3978
|
+
import { Fragment as Fragment4, jsx as jsx135, jsxs as jsxs128 } from "react/jsx-runtime";
|
|
3625
3979
|
var HEADER_HEIGHT = 56;
|
|
3626
3980
|
var DRAWER_WIDTH = "35%";
|
|
3627
3981
|
var Main = styled("main", { shouldForwardProp: (property) => property !== "open" })(({ open, theme }) => ({
|
|
@@ -3657,10 +4011,11 @@ var TraceGraphPage = () => {
|
|
|
3657
4011
|
const { traceId } = useParams();
|
|
3658
4012
|
const [searchParameters] = useSearchParams();
|
|
3659
4013
|
const spanId = searchParameters.get("spanId");
|
|
3660
|
-
const [open, setOpen] =
|
|
3661
|
-
const [selectedEvent, setSelectedEvent] =
|
|
3662
|
-
const [viewPortPixelWidth, setViewPortPixelWidth] =
|
|
3663
|
-
const
|
|
4014
|
+
const [open, setOpen] = useState7(true);
|
|
4015
|
+
const [selectedEvent, setSelectedEvent] = useState7();
|
|
4016
|
+
const [viewPortPixelWidth, setViewPortPixelWidth] = useState7(0);
|
|
4017
|
+
const { checkStatus, error: statusError, status } = useStatus();
|
|
4018
|
+
const calculateDrawerWidth = useCallback7(() => {
|
|
3664
4019
|
const percentageMatch = /(\d+)%/.exec(DRAWER_WIDTH);
|
|
3665
4020
|
if (percentageMatch && open) {
|
|
3666
4021
|
const percentage = Number.parseInt(percentageMatch[1], 10);
|
|
@@ -3668,7 +4023,7 @@ var TraceGraphPage = () => {
|
|
|
3668
4023
|
}
|
|
3669
4024
|
return 0;
|
|
3670
4025
|
}, [open]);
|
|
3671
|
-
|
|
4026
|
+
useEffect5(() => {
|
|
3672
4027
|
const updateViewportWidth = () => {
|
|
3673
4028
|
const totalWidth = window.innerWidth;
|
|
3674
4029
|
const drawerPixelWidth = open ? calculateDrawerWidth() : 0;
|
|
@@ -3682,12 +4037,16 @@ var TraceGraphPage = () => {
|
|
|
3682
4037
|
clearTimeout(timeoutId);
|
|
3683
4038
|
};
|
|
3684
4039
|
}, [open, calculateDrawerWidth]);
|
|
3685
|
-
const handleEventSelect =
|
|
4040
|
+
const handleEventSelect = useCallback7((event) => {
|
|
3686
4041
|
setSelectedEvent(event);
|
|
3687
4042
|
setOpen(true);
|
|
3688
4043
|
}, []);
|
|
3689
|
-
|
|
3690
|
-
|
|
4044
|
+
const handleRetry = useCallback7(() => {
|
|
4045
|
+
void checkStatus();
|
|
4046
|
+
}, [checkStatus]);
|
|
4047
|
+
const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
|
|
4048
|
+
return /* @__PURE__ */ jsx135(
|
|
4049
|
+
Box12,
|
|
3691
4050
|
{
|
|
3692
4051
|
"data-testid": "trace-graph-page",
|
|
3693
4052
|
sx: {
|
|
@@ -3697,7 +4056,7 @@ var TraceGraphPage = () => {
|
|
|
3697
4056
|
height: "100vh",
|
|
3698
4057
|
overflow: "hidden"
|
|
3699
4058
|
},
|
|
3700
|
-
children: /* @__PURE__ */
|
|
4059
|
+
children: /* @__PURE__ */ jsx135(
|
|
3701
4060
|
Paper2,
|
|
3702
4061
|
{
|
|
3703
4062
|
sx: {
|
|
@@ -3707,15 +4066,22 @@ var TraceGraphPage = () => {
|
|
|
3707
4066
|
position: "relative",
|
|
3708
4067
|
width: "100%"
|
|
3709
4068
|
},
|
|
3710
|
-
children:
|
|
3711
|
-
|
|
3712
|
-
|
|
4069
|
+
children: shouldShowStatusMessage ? /* @__PURE__ */ jsx135(
|
|
4070
|
+
StatusMessage,
|
|
4071
|
+
{
|
|
4072
|
+
error: statusError,
|
|
4073
|
+
onRetry: handleRetry,
|
|
4074
|
+
status
|
|
4075
|
+
}
|
|
4076
|
+
) : /* @__PURE__ */ jsxs128(Fragment4, { children: [
|
|
4077
|
+
/* @__PURE__ */ jsx135(Main, { open, children: /* @__PURE__ */ jsx135(
|
|
4078
|
+
Box12,
|
|
3713
4079
|
{
|
|
3714
4080
|
sx: {
|
|
3715
4081
|
height: "100%",
|
|
3716
4082
|
overflow: "auto"
|
|
3717
4083
|
},
|
|
3718
|
-
children: traceId !== void 0 && /* @__PURE__ */
|
|
4084
|
+
children: traceId !== void 0 && /* @__PURE__ */ jsx135(ReactFlowProvider, { children: /* @__PURE__ */ jsx135(
|
|
3719
4085
|
TraceGraph,
|
|
3720
4086
|
{
|
|
3721
4087
|
initialFocusEventId: spanId,
|
|
@@ -3726,8 +4092,8 @@ var TraceGraphPage = () => {
|
|
|
3726
4092
|
) })
|
|
3727
4093
|
}
|
|
3728
4094
|
) }),
|
|
3729
|
-
/* @__PURE__ */
|
|
3730
|
-
]
|
|
4095
|
+
/* @__PURE__ */ jsx135(StyledDrawer, { anchor: "right", open, variant: "persistent", children: /* @__PURE__ */ jsx135(EventDetails, { selectedEvent }) })
|
|
4096
|
+
] })
|
|
3731
4097
|
}
|
|
3732
4098
|
)
|
|
3733
4099
|
}
|