@datarecce/ui 0.1.22 → 0.1.23
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/{RecceCheckContext-BETsmiD5.mjs → RecceCheckContext-DIQjrvH8.mjs} +2 -2
- package/dist/{RecceCheckContext-BETsmiD5.mjs.map → RecceCheckContext-DIQjrvH8.mjs.map} +1 -1
- package/dist/{RecceCheckContext-DNKi97uE.js → RecceCheckContext-_xzNlnbJ.js} +2 -2
- package/dist/{RecceCheckContext-DNKi97uE.js.map → RecceCheckContext-_xzNlnbJ.js.map} +1 -1
- package/dist/api.d.mts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +11 -37
- package/dist/api.mjs +3 -29
- package/dist/{components-C735_oqD.mjs → components-CfY72Lq2.mjs} +1259 -11
- package/dist/components-CfY72Lq2.mjs.map +1 -0
- package/dist/{components-DeA4kqxK.js → components-DXbVq9Cw.js} +1310 -35
- package/dist/components-DXbVq9Cw.js.map +1 -0
- package/dist/components.d.mts +2 -2
- package/dist/components.d.ts +2 -2
- package/dist/components.js +8 -4
- package/dist/components.mjs +5 -5
- package/dist/{hooks-D6xvNXEc.js → hooks-C4jkoryM.js} +3 -3
- package/dist/{hooks-D6xvNXEc.js.map → hooks-C4jkoryM.js.map} +1 -1
- package/dist/{hooks-Ba-AoxcK.mjs → hooks-C8pyX9m_.mjs} +3 -3
- package/dist/{hooks-Ba-AoxcK.mjs.map → hooks-C8pyX9m_.mjs.map} +1 -1
- package/dist/hooks.d.mts +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +3 -3
- package/dist/hooks.mjs +3 -3
- package/dist/{index-DYduBYD8.d.ts → index-CVPmrztP.d.ts} +20 -2
- package/dist/index-CVPmrztP.d.ts.map +1 -0
- package/dist/{index-Sj_wOmNH.d.mts → index-DIHuswfP.d.mts} +85 -67
- package/dist/index-DIHuswfP.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +18 -14
- package/dist/index.mjs +7 -7
- package/dist/{state-BjKRZMwY.js → state-AeoqV9ja.js} +19 -1
- package/dist/{state-BjKRZMwY.js.map → state-AeoqV9ja.js.map} +1 -1
- package/dist/{state-BySLlIE7.mjs → state-BbgVwFV2.mjs} +8 -2
- package/dist/{state-BySLlIE7.mjs.map → state-BbgVwFV2.mjs.map} +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/{user-BHOgMaBf.mjs → version-C2NU3xyx.mjs} +27 -3
- package/dist/version-C2NU3xyx.mjs.map +1 -0
- package/dist/{user-Dt_n5IJX.js → version-MxW9vrDY.js} +32 -2
- package/dist/version-MxW9vrDY.js.map +1 -0
- package/package.json +4 -4
- package/dist/api.js.map +0 -1
- package/dist/api.mjs.map +0 -1
- package/dist/components-C735_oqD.mjs.map +0 -1
- package/dist/components-DeA4kqxK.js.map +0 -1
- package/dist/index-DYduBYD8.d.ts.map +0 -1
- package/dist/index-Sj_wOmNH.d.mts.map +0 -1
- package/dist/user-BHOgMaBf.mjs.map +0 -1
- package/dist/user-Dt_n5IJX.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client"
|
|
2
|
-
const require_state = require('./state-
|
|
2
|
+
const require_state = require('./state-AeoqV9ja.js');
|
|
3
3
|
const require_urls = require('./urls-SazAekCZ.js');
|
|
4
|
-
const
|
|
5
|
-
const require_RecceCheckContext = require('./RecceCheckContext-
|
|
4
|
+
const require_version = require('./version-MxW9vrDY.js');
|
|
5
|
+
const require_RecceCheckContext = require('./RecceCheckContext-_xzNlnbJ.js');
|
|
6
6
|
const require_tooltipMessage = require('./tooltipMessage-Dbi1kkfi.js');
|
|
7
7
|
let _mui_material_CssBaseline = require("@mui/material/CssBaseline");
|
|
8
8
|
_mui_material_CssBaseline = require_state.__toESM(_mui_material_CssBaseline);
|
|
@@ -50,6 +50,8 @@ _mui_material_DialogTitle = require_state.__toESM(_mui_material_DialogTitle);
|
|
|
50
50
|
let _mui_material_IconButton = require("@mui/material/IconButton");
|
|
51
51
|
_mui_material_IconButton = require_state.__toESM(_mui_material_IconButton);
|
|
52
52
|
let react_icons_io5 = require("react-icons/io5");
|
|
53
|
+
let next_link = require("next/link");
|
|
54
|
+
next_link = require_state.__toESM(next_link);
|
|
53
55
|
let _mui_material_Checkbox = require("@mui/material/Checkbox");
|
|
54
56
|
_mui_material_Checkbox = require_state.__toESM(_mui_material_Checkbox);
|
|
55
57
|
let _mui_material_FormControlLabel = require("@mui/material/FormControlLabel");
|
|
@@ -63,8 +65,10 @@ _mui_material_MenuItem = require_state.__toESM(_mui_material_MenuItem);
|
|
|
63
65
|
let react_icons_vsc = require("react-icons/vsc");
|
|
64
66
|
let _mui_material_Tooltip = require("@mui/material/Tooltip");
|
|
65
67
|
_mui_material_Tooltip = require_state.__toESM(_mui_material_Tooltip);
|
|
68
|
+
let usehooks_ts = require("usehooks-ts");
|
|
66
69
|
let _mui_material_ListSubheader = require("@mui/material/ListSubheader");
|
|
67
70
|
_mui_material_ListSubheader = require_state.__toESM(_mui_material_ListSubheader);
|
|
71
|
+
let next_navigation = require("next/navigation");
|
|
68
72
|
let _mui_material_Link = require("@mui/material/Link");
|
|
69
73
|
_mui_material_Link = require_state.__toESM(_mui_material_Link);
|
|
70
74
|
let _mui_material_Popover = require("@mui/material/Popover");
|
|
@@ -149,6 +153,10 @@ let _mui_material_CardHeader = require("@mui/material/CardHeader");
|
|
|
149
153
|
_mui_material_CardHeader = require_state.__toESM(_mui_material_CardHeader);
|
|
150
154
|
let _mui_material_Badge = require("@mui/material/Badge");
|
|
151
155
|
_mui_material_Badge = require_state.__toESM(_mui_material_Badge);
|
|
156
|
+
let app__mainComponents__DisplayModeToggle = require("app/(mainComponents)/DisplayModeToggle");
|
|
157
|
+
app__mainComponents__DisplayModeToggle = require_state.__toESM(app__mainComponents__DisplayModeToggle);
|
|
158
|
+
let app__mainComponents__RecceVersionBadge = require("app/(mainComponents)/RecceVersionBadge");
|
|
159
|
+
app__mainComponents__RecceVersionBadge = require_state.__toESM(app__mainComponents__RecceVersionBadge);
|
|
152
160
|
|
|
153
161
|
//#region recce-source/js/src/components/ui/mui-provider.tsx
|
|
154
162
|
/**
|
|
@@ -1351,9 +1359,9 @@ var require_embed_resources = /* @__PURE__ */ require_state.__commonJSMin(((expo
|
|
|
1351
1359
|
var preferredFontFormat = _a.preferredFontFormat;
|
|
1352
1360
|
return !preferredFontFormat ? str : str.replace(FONT_SRC_REGEX, function(match) {
|
|
1353
1361
|
while (true) {
|
|
1354
|
-
var _a$1 = URL_WITH_FORMAT_REGEX.exec(match) || [], src = _a$1[0], format$
|
|
1355
|
-
if (!format$
|
|
1356
|
-
if (format$
|
|
1362
|
+
var _a$1 = URL_WITH_FORMAT_REGEX.exec(match) || [], src = _a$1[0], format$4 = _a$1[2];
|
|
1363
|
+
if (!format$4) return "";
|
|
1364
|
+
if (format$4 === preferredFontFormat) return "src: ".concat(src, ";");
|
|
1357
1365
|
}
|
|
1358
1366
|
});
|
|
1359
1367
|
}
|
|
@@ -2288,7 +2296,7 @@ const getHTMLElementFromRef = (refCurrent) => {
|
|
|
2288
2296
|
};
|
|
2289
2297
|
const IGNORE_SCREENSHOT_CLASS = "ignore-screenshot";
|
|
2290
2298
|
const highlightBoxShadow = "rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px";
|
|
2291
|
-
function useCopyToClipboard({ renderLibrary = "html2canvas", imageType = "png", backgroundColor = null, boardEffect = true, shadowEffect = false, borderStyle = `solid 1px ${require_state.colors.neutral[300]}`, borderRadius = "10px", onSuccess, onError, ignoreElements }) {
|
|
2299
|
+
function useCopyToClipboard$1({ renderLibrary = "html2canvas", imageType = "png", backgroundColor = null, boardEffect = true, shadowEffect = false, borderStyle = `solid 1px ${require_state.colors.neutral[300]}`, borderRadius = "10px", onSuccess, onError, ignoreElements }) {
|
|
2292
2300
|
const [status, setStatus] = (0, react.useState)("idle");
|
|
2293
2301
|
const ref = (0, react.useRef)(null);
|
|
2294
2302
|
const { onOpen, setImgBlob, ImageDownloadModal } = useImageDownloadModal();
|
|
@@ -2389,7 +2397,7 @@ function useCopyToClipboard({ renderLibrary = "html2canvas", imageType = "png",
|
|
|
2389
2397
|
}
|
|
2390
2398
|
function useCopyToClipboardButton(options) {
|
|
2391
2399
|
const { successToast, failToast } = require_state.useClipBoardToast();
|
|
2392
|
-
const { isLoading, copyToClipboard, ImageDownloadModal, ref } = useCopyToClipboard({
|
|
2400
|
+
const { isLoading, copyToClipboard, ImageDownloadModal, ref } = useCopyToClipboard$1({
|
|
2393
2401
|
imageType: "png",
|
|
2394
2402
|
shadowEffect: true,
|
|
2395
2403
|
backgroundColor: options?.backgroundColor ?? require_state.colors.neutral[100],
|
|
@@ -4452,7 +4460,7 @@ const useLineageViewContextMenu = () => {
|
|
|
4452
4460
|
//#endregion
|
|
4453
4461
|
//#region recce-source/js/src/components/lineage/LineageViewNotification.tsx
|
|
4454
4462
|
function LineageViewNotification({ notification, type }) {
|
|
4455
|
-
const notificationKey =
|
|
4463
|
+
const notificationKey = require_version.sessionStorageKeys.lineageNotificationDismissed;
|
|
4456
4464
|
const [visible, setVisible] = (0, react.useState)(() => {
|
|
4457
4465
|
return sessionStorage.getItem(notificationKey) !== "true";
|
|
4458
4466
|
});
|
|
@@ -6394,7 +6402,7 @@ function AuthModal({ handleParentClose, parentOpen = false, ignoreCookie = false
|
|
|
6394
6402
|
},
|
|
6395
6403
|
onClick: async () => {
|
|
6396
6404
|
setAuthState("authenticating");
|
|
6397
|
-
const { connection_url } = await
|
|
6405
|
+
const { connection_url } = await require_version.connectToCloud();
|
|
6398
6406
|
window.open(connection_url, "_blank");
|
|
6399
6407
|
},
|
|
6400
6408
|
children: [
|
|
@@ -7286,7 +7294,7 @@ function SandboxView({ isOpen, onClose, current }) {
|
|
|
7286
7294
|
}
|
|
7287
7295
|
});
|
|
7288
7296
|
const { feedbackToast, closeToast } = useFeedbackCollectionToast({
|
|
7289
|
-
feedbackId:
|
|
7297
|
+
feedbackId: require_version.localStorageKeys.previewChangeFeedbackID,
|
|
7290
7298
|
description: "Enjoy preview change?",
|
|
7291
7299
|
onFeedbackSubmit: (feedback) => {
|
|
7292
7300
|
switch (feedback) {
|
|
@@ -7315,7 +7323,7 @@ function SandboxView({ isOpen, onClose, current }) {
|
|
|
7315
7323
|
externalLinkText: "Give us feedback"
|
|
7316
7324
|
});
|
|
7317
7325
|
const { guideToast: prepareEnvToast, closeGuideToast } = useGuideToast({
|
|
7318
|
-
guideId:
|
|
7326
|
+
guideId: require_version.localStorageKeys.prepareEnvGuideID,
|
|
7319
7327
|
description: "Want to compare data changes with production data?",
|
|
7320
7328
|
externalLink: "https://docs.datarecce.io/get-started/#prepare-dbt-artifacts",
|
|
7321
7329
|
externalLinkText: "Learn how.",
|
|
@@ -7742,7 +7750,7 @@ function ExploreChangeMenuButton({ node, baseColumns, currentColumns, disableRea
|
|
|
7742
7750
|
const isAddedOrRemoved = node.data.changeStatus === "added" || node.data.changeStatus === "removed";
|
|
7743
7751
|
const addSchemaCheck = (0, react.useCallback)(async () => {
|
|
7744
7752
|
const nodeId = node.id;
|
|
7745
|
-
setLocation(`/checks/?id=${(await
|
|
7753
|
+
setLocation(`/checks/?id=${(await require_version.createSchemaDiffCheck({ node_id: nodeId })).check_id}`);
|
|
7746
7754
|
}, [node, setLocation]);
|
|
7747
7755
|
const formattedColumns = formatSelectColumns(baseColumns, currentColumns);
|
|
7748
7756
|
let query = `select * from {{ ref("${node.data.name}") }}`;
|
|
@@ -8391,8 +8399,8 @@ const useMultiNodesAction = (nodes, { onActionStarted, onActionNodeUpdated, onAc
|
|
|
8391
8399
|
};
|
|
8392
8400
|
const addSchemaDiffCheck = async () => {
|
|
8393
8401
|
let check;
|
|
8394
|
-
if (nodes.length === 1) check = await
|
|
8395
|
-
else check = await
|
|
8402
|
+
if (nodes.length === 1) check = await require_version.createSchemaDiffCheck({ node_id: nodes[0].id });
|
|
8403
|
+
else check = await require_version.createSchemaDiffCheck({ node_id: nodes.map((node) => node.id) });
|
|
8396
8404
|
return check;
|
|
8397
8405
|
};
|
|
8398
8406
|
const cancel = async () => {
|
|
@@ -8463,7 +8471,7 @@ function PrivateLineageView({ interactive = false, ...props }, ref) {
|
|
|
8463
8471
|
const reactFlow = (0, _xyflow_react.useReactFlow)();
|
|
8464
8472
|
const refResize = (0, react.useRef)(null);
|
|
8465
8473
|
const { successToast, failToast } = require_state.useClipBoardToast();
|
|
8466
|
-
const { copyToClipboard, ImageDownloadModal, ref: refReactFlow } = useCopyToClipboard({
|
|
8474
|
+
const { copyToClipboard, ImageDownloadModal, ref: refReactFlow } = useCopyToClipboard$1({
|
|
8467
8475
|
renderLibrary: "html-to-image",
|
|
8468
8476
|
imageType: "png",
|
|
8469
8477
|
shadowEffect: true,
|
|
@@ -8605,7 +8613,7 @@ function PrivateLineageView({ interactive = false, ...props }, ref) {
|
|
|
8605
8613
|
...props.viewOptions
|
|
8606
8614
|
};
|
|
8607
8615
|
try {
|
|
8608
|
-
filteredNodeIds$1 = (await
|
|
8616
|
+
filteredNodeIds$1 = (await require_version.select({
|
|
8609
8617
|
select: newViewOptions.select,
|
|
8610
8618
|
exclude: newViewOptions.exclude,
|
|
8611
8619
|
packages: newViewOptions.packages,
|
|
@@ -8613,7 +8621,7 @@ function PrivateLineageView({ interactive = false, ...props }, ref) {
|
|
|
8613
8621
|
})).nodes;
|
|
8614
8622
|
} catch (_$1) {
|
|
8615
8623
|
newViewOptions.view_mode = "all";
|
|
8616
|
-
filteredNodeIds$1 = (await
|
|
8624
|
+
filteredNodeIds$1 = (await require_version.select({
|
|
8617
8625
|
select: newViewOptions.select,
|
|
8618
8626
|
exclude: newViewOptions.exclude,
|
|
8619
8627
|
packages: newViewOptions.packages,
|
|
@@ -8734,7 +8742,7 @@ function PrivateLineageView({ interactive = false, ...props }, ref) {
|
|
|
8734
8742
|
if (!lineageGraph) return;
|
|
8735
8743
|
if (viewOptions.select !== newViewOptions.select || viewOptions.exclude !== newViewOptions.exclude || viewOptions.packages !== newViewOptions.packages || viewOptions.view_mode !== newViewOptions.view_mode) {
|
|
8736
8744
|
try {
|
|
8737
|
-
const result = await
|
|
8745
|
+
const result = await require_version.select({
|
|
8738
8746
|
select: newViewOptions.select,
|
|
8739
8747
|
exclude: newViewOptions.exclude,
|
|
8740
8748
|
packages: newViewOptions.packages,
|
|
@@ -9041,13 +9049,13 @@ function PrivateLineageView({ interactive = false, ...props }, ref) {
|
|
|
9041
9049
|
});
|
|
9042
9050
|
}
|
|
9043
9051
|
} else if (focusedNode) {
|
|
9044
|
-
check = await
|
|
9052
|
+
check = await require_version.createSchemaDiffCheck({ node_id: focusedNode.id });
|
|
9045
9053
|
require_state.trackMultiNodesAction({
|
|
9046
9054
|
type: "schema_diff",
|
|
9047
9055
|
selected: "single"
|
|
9048
9056
|
});
|
|
9049
9057
|
} else {
|
|
9050
|
-
check = await
|
|
9058
|
+
check = await require_version.createSchemaDiffCheck({
|
|
9051
9059
|
select: viewOptions.select,
|
|
9052
9060
|
exclude: viewOptions.exclude,
|
|
9053
9061
|
packages: viewOptions.packages,
|
|
@@ -10391,7 +10399,7 @@ function UserAvatar({ event }) {
|
|
|
10391
10399
|
const userId = actor.user_id?.toString();
|
|
10392
10400
|
const { data: avatarUrl } = (0, _tanstack_react_query.useQuery)({
|
|
10393
10401
|
queryKey: ["github-avatar", userId],
|
|
10394
|
-
queryFn: () => userId ?
|
|
10402
|
+
queryFn: () => userId ? require_version.fetchGitHubAvatar(userId) : Promise.resolve(null),
|
|
10395
10403
|
enabled: !!userId,
|
|
10396
10404
|
retry: false,
|
|
10397
10405
|
staleTime: 300 * 1e3
|
|
@@ -10740,7 +10748,7 @@ function CheckTimeline({ checkId }) {
|
|
|
10740
10748
|
const { events, isLoading, error, createComment: createComment$1, isCreatingComment, updateComment: updateComment$1, deleteComment: deleteComment$1 } = useCheckEvents(checkId);
|
|
10741
10749
|
const { data: currentUser } = (0, _tanstack_react_query.useQuery)({
|
|
10742
10750
|
queryKey: require_state.cacheKeys.user(),
|
|
10743
|
-
queryFn:
|
|
10751
|
+
queryFn: require_version.fetchUser,
|
|
10744
10752
|
retry: false
|
|
10745
10753
|
});
|
|
10746
10754
|
const handleCreateComment = (content) => {
|
|
@@ -11129,7 +11137,7 @@ function PrivateSchemaDiffView({ check }, ref) {
|
|
|
11129
11137
|
const params = check.params;
|
|
11130
11138
|
const { isLoading, error, data } = (0, _tanstack_react_query.useQuery)({
|
|
11131
11139
|
queryKey: [...require_state.cacheKeys.check(check.check_id), "select"],
|
|
11132
|
-
queryFn: async () =>
|
|
11140
|
+
queryFn: async () => require_version.select({
|
|
11133
11141
|
select: params.select,
|
|
11134
11142
|
exclude: params.exclude,
|
|
11135
11143
|
packages: params.packages,
|
|
@@ -11821,7 +11829,7 @@ const CheckEmptyState = () => {
|
|
|
11821
11829
|
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
11822
11830
|
const [, setLocation] = require_state.useAppLocation();
|
|
11823
11831
|
const { mutate: createSchemaCheck, isPending } = (0, _tanstack_react_query.useMutation)({
|
|
11824
|
-
mutationFn: () =>
|
|
11832
|
+
mutationFn: () => require_version.createSchemaDiffCheck({ select: "state:modified" }),
|
|
11825
11833
|
onSuccess: async (check) => {
|
|
11826
11834
|
await queryClient.invalidateQueries({ queryKey: require_state.cacheKeys.checks() });
|
|
11827
11835
|
setLocation(`/checks/?id=${check.check_id}`);
|
|
@@ -12471,6 +12479,124 @@ function SummaryView() {
|
|
|
12471
12479
|
}) });
|
|
12472
12480
|
}
|
|
12473
12481
|
|
|
12482
|
+
//#endregion
|
|
12483
|
+
//#region recce-source/js/src/components/app/AvatarDropdown.tsx
|
|
12484
|
+
function AvatarDropdown() {
|
|
12485
|
+
const { data: user, isLoading, error } = (0, _tanstack_react_query.useQuery)({
|
|
12486
|
+
queryKey: require_state.cacheKeys.user(),
|
|
12487
|
+
queryFn: require_version.fetchUser,
|
|
12488
|
+
retry: false
|
|
12489
|
+
});
|
|
12490
|
+
const { data: avatarUrl } = (0, _tanstack_react_query.useQuery)({
|
|
12491
|
+
queryKey: ["github-avatar", user?.id],
|
|
12492
|
+
queryFn: () => user ? require_version.fetchGitHubAvatar(user.id) : Promise.resolve(null),
|
|
12493
|
+
enabled: !!user?.id && user.login_type === "github",
|
|
12494
|
+
retry: false,
|
|
12495
|
+
staleTime: 300 * 1e3
|
|
12496
|
+
});
|
|
12497
|
+
const [anchorEl, setAnchorEl] = (0, react.useState)(null);
|
|
12498
|
+
const open = Boolean(anchorEl);
|
|
12499
|
+
const handleClick = (event) => {
|
|
12500
|
+
setAnchorEl(event.currentTarget);
|
|
12501
|
+
};
|
|
12502
|
+
const handleClose = () => {
|
|
12503
|
+
setAnchorEl(null);
|
|
12504
|
+
};
|
|
12505
|
+
const showUserInfo = !isLoading && !error && user;
|
|
12506
|
+
const getInitials = (name) => {
|
|
12507
|
+
if (!name) return "U";
|
|
12508
|
+
return name.charAt(0).toUpperCase();
|
|
12509
|
+
};
|
|
12510
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12511
|
+
onClick: handleClick,
|
|
12512
|
+
sx: {
|
|
12513
|
+
width: 32,
|
|
12514
|
+
height: 32,
|
|
12515
|
+
borderRadius: "50%",
|
|
12516
|
+
bgcolor: "background.paper",
|
|
12517
|
+
color: "primary.main",
|
|
12518
|
+
display: "flex",
|
|
12519
|
+
alignItems: "center",
|
|
12520
|
+
justifyContent: "center",
|
|
12521
|
+
cursor: "pointer"
|
|
12522
|
+
},
|
|
12523
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_CircularProgress.default, { size: 16 })
|
|
12524
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Avatar.default, {
|
|
12525
|
+
onClick: handleClick,
|
|
12526
|
+
src: avatarUrl || void 0,
|
|
12527
|
+
sx: {
|
|
12528
|
+
width: 28,
|
|
12529
|
+
height: 28,
|
|
12530
|
+
cursor: "pointer",
|
|
12531
|
+
outline: "1px solid white",
|
|
12532
|
+
fontSize: "0.875rem"
|
|
12533
|
+
},
|
|
12534
|
+
children: getInitials(user?.login)
|
|
12535
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Menu.default, {
|
|
12536
|
+
anchorEl,
|
|
12537
|
+
open,
|
|
12538
|
+
onClose: handleClose,
|
|
12539
|
+
slotProps: { paper: { sx: {
|
|
12540
|
+
bgcolor: "background.paper",
|
|
12541
|
+
borderColor: "divider",
|
|
12542
|
+
boxShadow: 3,
|
|
12543
|
+
minWidth: 180
|
|
12544
|
+
} } },
|
|
12545
|
+
children: [
|
|
12546
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
12547
|
+
sx: {
|
|
12548
|
+
px: 2,
|
|
12549
|
+
py: 1.5
|
|
12550
|
+
},
|
|
12551
|
+
children: [
|
|
12552
|
+
isLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
12553
|
+
sx: {
|
|
12554
|
+
display: "flex",
|
|
12555
|
+
alignItems: "center",
|
|
12556
|
+
gap: 1
|
|
12557
|
+
},
|
|
12558
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12559
|
+
variant: "body2",
|
|
12560
|
+
color: "text.primary",
|
|
12561
|
+
children: "Loading..."
|
|
12562
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_CircularProgress.default, { size: 16 })]
|
|
12563
|
+
}),
|
|
12564
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12565
|
+
variant: "caption",
|
|
12566
|
+
color: "error",
|
|
12567
|
+
children: "Failed to load user information"
|
|
12568
|
+
}),
|
|
12569
|
+
showUserInfo && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12570
|
+
variant: "body2",
|
|
12571
|
+
fontWeight: "600",
|
|
12572
|
+
color: "text.primary",
|
|
12573
|
+
children: user.login
|
|
12574
|
+
}), user.email && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12575
|
+
variant: "caption",
|
|
12576
|
+
color: "text.secondary",
|
|
12577
|
+
children: user.email
|
|
12578
|
+
})] })
|
|
12579
|
+
]
|
|
12580
|
+
}),
|
|
12581
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Divider.default, {}),
|
|
12582
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
12583
|
+
onClick: () => {
|
|
12584
|
+
window.open("https://cloud.datarecce.io/", "_blank");
|
|
12585
|
+
handleClose();
|
|
12586
|
+
},
|
|
12587
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_fa.FaCloud, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Recce Cloud" })]
|
|
12588
|
+
}),
|
|
12589
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
12590
|
+
onClick: () => {
|
|
12591
|
+
window.open(require_urls.RECCE_SUPPORT_CALENDAR_URL, "_blank");
|
|
12592
|
+
handleClose();
|
|
12593
|
+
},
|
|
12594
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_fa.FaUser, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Get live support" })]
|
|
12595
|
+
})
|
|
12596
|
+
]
|
|
12597
|
+
})] });
|
|
12598
|
+
}
|
|
12599
|
+
|
|
12474
12600
|
//#endregion
|
|
12475
12601
|
//#region recce-source/js/src/components/timeout/IdleTimeoutBadge.tsx
|
|
12476
12602
|
/**
|
|
@@ -12490,20 +12616,1145 @@ function IdleTimeoutBadge() {
|
|
|
12490
12616
|
color: "warning",
|
|
12491
12617
|
variant: "standard",
|
|
12492
12618
|
sx: {
|
|
12493
|
-
display: "flex",
|
|
12619
|
+
display: "flex",
|
|
12620
|
+
alignItems: "center",
|
|
12621
|
+
gap: 1,
|
|
12622
|
+
fontSize: "0.75rem",
|
|
12623
|
+
mr: 2
|
|
12624
|
+
},
|
|
12625
|
+
children: [
|
|
12626
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12627
|
+
component: react_icons_io5.IoWarning,
|
|
12628
|
+
sx: { display: "inline-flex" }
|
|
12629
|
+
}),
|
|
12630
|
+
"Idle timeout: ",
|
|
12631
|
+
require_state.formatDuration(remainingSeconds, "compact")
|
|
12632
|
+
]
|
|
12633
|
+
});
|
|
12634
|
+
}
|
|
12635
|
+
|
|
12636
|
+
//#endregion
|
|
12637
|
+
//#region recce-source/js/app/(mainComponents)/TopBar.tsx
|
|
12638
|
+
function LinkIcon({ icon: IconComponent, href, sx, ...props }) {
|
|
12639
|
+
const theme = (0, _mui_material_styles.useTheme)();
|
|
12640
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Link.default, {
|
|
12641
|
+
sx: {
|
|
12642
|
+
height: "20px",
|
|
12643
|
+
color: "common.white",
|
|
12644
|
+
...sx
|
|
12645
|
+
},
|
|
12646
|
+
href,
|
|
12647
|
+
target: "_blank",
|
|
12648
|
+
...props,
|
|
12649
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconComponent, { style: {
|
|
12650
|
+
color: theme.palette.common.white,
|
|
12651
|
+
width: 20,
|
|
12652
|
+
height: 20
|
|
12653
|
+
} })
|
|
12654
|
+
});
|
|
12655
|
+
}
|
|
12656
|
+
function TopBar() {
|
|
12657
|
+
const { reviewMode, isDemoSite, envInfo, cloudMode } = require_state.useLineageGraphContext();
|
|
12658
|
+
const { featureToggles, authed } = require_state.useRecceInstanceContext();
|
|
12659
|
+
const { url: prURL, id: prID } = envInfo?.pullRequest ?? {};
|
|
12660
|
+
const demoPrId = prURL ? prURL.split("/").pop() : null;
|
|
12661
|
+
const brandLink = cloudMode || authed ? "https://cloud.datarecce.io/" : "https://reccehq.com/";
|
|
12662
|
+
const [showModal, setShowModal] = (0, react.useState)(false);
|
|
12663
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
12664
|
+
sx: {
|
|
12665
|
+
display: "flex",
|
|
12666
|
+
gap: "10px",
|
|
12667
|
+
minHeight: "40px",
|
|
12668
|
+
alignItems: "center",
|
|
12669
|
+
bgcolor: require_state.colors.brand[400]
|
|
12670
|
+
},
|
|
12671
|
+
children: [
|
|
12672
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Link.default, {
|
|
12673
|
+
href: brandLink,
|
|
12674
|
+
target: "_blank",
|
|
12675
|
+
sx: { "&:hover": { textDecoration: "none" } },
|
|
12676
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
12677
|
+
sx: {
|
|
12678
|
+
display: "flex",
|
|
12679
|
+
gap: "10px",
|
|
12680
|
+
alignItems: "center"
|
|
12681
|
+
},
|
|
12682
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12683
|
+
component: "img",
|
|
12684
|
+
sx: {
|
|
12685
|
+
width: 20,
|
|
12686
|
+
height: 20,
|
|
12687
|
+
ml: "18px"
|
|
12688
|
+
},
|
|
12689
|
+
src: "/logo/recce-logo-white.png",
|
|
12690
|
+
alt: "recce-logo-white"
|
|
12691
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12692
|
+
variant: "h4",
|
|
12693
|
+
sx: {
|
|
12694
|
+
fontFamily: "\"Montserrat\", sans-serif",
|
|
12695
|
+
color: "common.white",
|
|
12696
|
+
fontSize: "1.25rem"
|
|
12697
|
+
},
|
|
12698
|
+
children: "RECCE"
|
|
12699
|
+
})]
|
|
12700
|
+
})
|
|
12701
|
+
}),
|
|
12702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(app__mainComponents__DisplayModeToggle.default, {}),
|
|
12703
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(app__mainComponents__RecceVersionBadge.default, {}),
|
|
12704
|
+
(featureToggles.mode ?? reviewMode) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Badge.default, {
|
|
12705
|
+
sx: {
|
|
12706
|
+
fontSize: "0.875rem",
|
|
12707
|
+
color: "rgba(255,255,255,0.8)",
|
|
12708
|
+
textTransform: "uppercase",
|
|
12709
|
+
borderWidth: 1,
|
|
12710
|
+
px: 1,
|
|
12711
|
+
borderRadius: .75,
|
|
12712
|
+
borderColor: "rgba(255,255,255,0.8)"
|
|
12713
|
+
},
|
|
12714
|
+
children: featureToggles.mode ?? "review mode"
|
|
12715
|
+
}),
|
|
12716
|
+
cloudMode && prID && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Badge.default, {
|
|
12717
|
+
sx: {
|
|
12718
|
+
fontSize: "0.875rem",
|
|
12719
|
+
color: "rgba(255,255,255,0.8)",
|
|
12720
|
+
textTransform: "uppercase",
|
|
12721
|
+
borderWidth: 1,
|
|
12722
|
+
px: 1,
|
|
12723
|
+
borderRadius: .75,
|
|
12724
|
+
borderColor: "rgba(255,255,255,0.8)"
|
|
12725
|
+
},
|
|
12726
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
12727
|
+
direction: "row",
|
|
12728
|
+
spacing: 1,
|
|
12729
|
+
alignItems: "center",
|
|
12730
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { children: "cloud mode" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12731
|
+
sx: {
|
|
12732
|
+
borderLeft: "1px solid rgba(255,255,255,0.8)",
|
|
12733
|
+
pl: "8px"
|
|
12734
|
+
},
|
|
12735
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Link.default, {
|
|
12736
|
+
href: prURL,
|
|
12737
|
+
sx: { "&:hover": { textDecoration: "none" } },
|
|
12738
|
+
target: "_blank",
|
|
12739
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_vsc.VscGitPullRequest, { style: {
|
|
12740
|
+
color: "rgba(255,255,255,0.8)",
|
|
12741
|
+
width: 12,
|
|
12742
|
+
height: 12,
|
|
12743
|
+
marginRight: 2,
|
|
12744
|
+
display: "inline",
|
|
12745
|
+
verticalAlign: "middle"
|
|
12746
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12747
|
+
component: "span",
|
|
12748
|
+
sx: {
|
|
12749
|
+
color: "rgba(255,255,255,0.8)",
|
|
12750
|
+
display: "inline"
|
|
12751
|
+
},
|
|
12752
|
+
children: `#${String(prID)}`
|
|
12753
|
+
})]
|
|
12754
|
+
})
|
|
12755
|
+
})]
|
|
12756
|
+
})
|
|
12757
|
+
}),
|
|
12758
|
+
isDemoSite && prURL && demoPrId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Badge.default, {
|
|
12759
|
+
sx: {
|
|
12760
|
+
fontSize: "0.875rem",
|
|
12761
|
+
color: "rgba(255,255,255,0.8)",
|
|
12762
|
+
textTransform: "uppercase",
|
|
12763
|
+
borderWidth: 1,
|
|
12764
|
+
px: 1,
|
|
12765
|
+
borderRadius: .75,
|
|
12766
|
+
borderColor: "rgba(255,255,255,0.8)"
|
|
12767
|
+
},
|
|
12768
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
12769
|
+
direction: "row",
|
|
12770
|
+
spacing: 1,
|
|
12771
|
+
alignItems: "center",
|
|
12772
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { children: "demo mode" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12773
|
+
sx: {
|
|
12774
|
+
borderLeft: "1px solid rgba(255,255,255,0.8)",
|
|
12775
|
+
pl: "8px"
|
|
12776
|
+
},
|
|
12777
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Link.default, {
|
|
12778
|
+
href: prURL,
|
|
12779
|
+
sx: { "&:hover": { textDecoration: "none" } },
|
|
12780
|
+
target: "_blank",
|
|
12781
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_vsc.VscGitPullRequest, { style: {
|
|
12782
|
+
color: "rgba(255,255,255,0.8)",
|
|
12783
|
+
width: 12,
|
|
12784
|
+
height: 12,
|
|
12785
|
+
marginRight: 2,
|
|
12786
|
+
display: "inline",
|
|
12787
|
+
verticalAlign: "middle"
|
|
12788
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
12789
|
+
component: "span",
|
|
12790
|
+
sx: {
|
|
12791
|
+
color: "rgba(255,255,255,0.8)",
|
|
12792
|
+
display: "inline"
|
|
12793
|
+
},
|
|
12794
|
+
children: `#${demoPrId}`
|
|
12795
|
+
})]
|
|
12796
|
+
})
|
|
12797
|
+
})]
|
|
12798
|
+
})
|
|
12799
|
+
}),
|
|
12800
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { sx: { flex: 1 } }),
|
|
12801
|
+
(isDemoSite || featureToggles.mode === "read only") && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
12802
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkIcon, {
|
|
12803
|
+
icon: react_icons_fa.FaGithub,
|
|
12804
|
+
href: "https://github.com/DataRecce/recce"
|
|
12805
|
+
}),
|
|
12806
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkIcon, {
|
|
12807
|
+
icon: react_icons_fa.FaSlack,
|
|
12808
|
+
href: "https://getdbt.slack.com/archives/C05C28V7CPP"
|
|
12809
|
+
}),
|
|
12810
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LinkIcon, {
|
|
12811
|
+
sx: { mr: 2 },
|
|
12812
|
+
icon: react_icons_fa.FaQuestionCircle,
|
|
12813
|
+
href: "https://docs.datarecce.io"
|
|
12814
|
+
})
|
|
12815
|
+
] }),
|
|
12816
|
+
!isDemoSite && featureToggles.mode !== "read only" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IdleTimeoutBadge, {}), authed || cloudMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12817
|
+
sx: { mr: 2 },
|
|
12818
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AvatarDropdown, {})
|
|
12819
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12820
|
+
component: "button",
|
|
12821
|
+
sx: {
|
|
12822
|
+
color: "common.white",
|
|
12823
|
+
fontSize: "0.875rem",
|
|
12824
|
+
fontWeight: 600,
|
|
12825
|
+
bgcolor: "brand.700",
|
|
12826
|
+
borderRadius: 1,
|
|
12827
|
+
px: 3,
|
|
12828
|
+
py: 1,
|
|
12829
|
+
mr: 2,
|
|
12830
|
+
cursor: "pointer",
|
|
12831
|
+
border: "none"
|
|
12832
|
+
},
|
|
12833
|
+
onClick: () => {
|
|
12834
|
+
setShowModal(true);
|
|
12835
|
+
},
|
|
12836
|
+
children: "Connect to Cloud"
|
|
12837
|
+
}), showModal && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthModal, {
|
|
12838
|
+
parentOpen: showModal,
|
|
12839
|
+
handleParentClose: setShowModal,
|
|
12840
|
+
ignoreCookie: true,
|
|
12841
|
+
variant: "user-profile"
|
|
12842
|
+
})] })] })
|
|
12843
|
+
]
|
|
12844
|
+
});
|
|
12845
|
+
}
|
|
12846
|
+
|
|
12847
|
+
//#endregion
|
|
12848
|
+
//#region recce-source/js/src/components/app/Filename.tsx
|
|
12849
|
+
const useRecceToast = () => {
|
|
12850
|
+
const toastSuccess = (message) => {
|
|
12851
|
+
require_state.toaster.create({
|
|
12852
|
+
description: message,
|
|
12853
|
+
type: "success",
|
|
12854
|
+
duration: 5e3,
|
|
12855
|
+
closable: true
|
|
12856
|
+
});
|
|
12857
|
+
};
|
|
12858
|
+
const toastError = (message, error) => {
|
|
12859
|
+
let errorMessage = message;
|
|
12860
|
+
if (error != null) if (error instanceof axios.AxiosError) errorMessage = `${message}. ${String(error.response?.data?.detail)}`;
|
|
12861
|
+
else errorMessage = `${message}. ${error}`;
|
|
12862
|
+
require_state.toaster.create({
|
|
12863
|
+
description: errorMessage,
|
|
12864
|
+
type: "error",
|
|
12865
|
+
duration: 5e3,
|
|
12866
|
+
closable: true
|
|
12867
|
+
});
|
|
12868
|
+
};
|
|
12869
|
+
return {
|
|
12870
|
+
toastSuccess,
|
|
12871
|
+
toastError
|
|
12872
|
+
};
|
|
12873
|
+
};
|
|
12874
|
+
const useClosePrompt = (prompt) => {
|
|
12875
|
+
(0, react.useEffect)(() => {
|
|
12876
|
+
const handleBeforeUnload = (e) => {
|
|
12877
|
+
e.preventDefault();
|
|
12878
|
+
};
|
|
12879
|
+
if (prompt) window.addEventListener("beforeunload", handleBeforeUnload);
|
|
12880
|
+
return () => {
|
|
12881
|
+
if (prompt) window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
12882
|
+
};
|
|
12883
|
+
}, [prompt]);
|
|
12884
|
+
};
|
|
12885
|
+
const Filename = () => {
|
|
12886
|
+
const { featureToggles } = require_state.useRecceInstanceContext();
|
|
12887
|
+
const { fileName, cloudMode, isDemoSite, envInfo } = require_state.useLineageGraphContext();
|
|
12888
|
+
const [modalOpen, setModalOpen] = (0, react.useState)(false);
|
|
12889
|
+
const [overwriteOpen, setOverwriteOpen] = (0, react.useState)(false);
|
|
12890
|
+
const isStateless = !fileName && !cloudMode && !isDemoSite;
|
|
12891
|
+
const { data: checks } = require_state.useChecks(isStateless);
|
|
12892
|
+
const hasNonPresetChecks = checks != void 0 && checks.filter((check) => !check.is_preset).length > 0;
|
|
12893
|
+
useClosePrompt(isStateless && hasNonPresetChecks);
|
|
12894
|
+
const [{ newFileName, errorMessage, modified, overwriteWithMethod, bypass }, setState] = (0, react.useState)({ newFileName: fileName ?? "recce_state.json" });
|
|
12895
|
+
const inputRef = (0, react.useRef)(null);
|
|
12896
|
+
const { toastSuccess, toastError } = useRecceToast();
|
|
12897
|
+
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
12898
|
+
const handleOpen = () => {
|
|
12899
|
+
setState({
|
|
12900
|
+
newFileName: fileName ?? "recce_state.json",
|
|
12901
|
+
modified: !fileName
|
|
12902
|
+
});
|
|
12903
|
+
setModalOpen(true);
|
|
12904
|
+
};
|
|
12905
|
+
const handleModalClose = () => setModalOpen(false);
|
|
12906
|
+
const handleOverwriteClose = () => setOverwriteOpen(false);
|
|
12907
|
+
const handleAction = async (method, overwrite) => {
|
|
12908
|
+
if (!newFileName) return;
|
|
12909
|
+
const bypassOverwrite = localStorage.getItem(require_version.localStorageKeys.bypassSaveOverwrite) === "true";
|
|
12910
|
+
try {
|
|
12911
|
+
if (method === "save") await require_state.saveAs({
|
|
12912
|
+
filename: newFileName,
|
|
12913
|
+
overwrite: overwrite ?? bypassOverwrite
|
|
12914
|
+
});
|
|
12915
|
+
else await require_state.rename({
|
|
12916
|
+
filename: newFileName,
|
|
12917
|
+
overwrite: overwrite ?? bypassOverwrite
|
|
12918
|
+
});
|
|
12919
|
+
toastSuccess(method === "save" ? "Save file successfully" : "Rename file successfully");
|
|
12920
|
+
await queryClient.invalidateQueries({ queryKey: require_state.cacheKeys.lineage() });
|
|
12921
|
+
if (bypass) localStorage.setItem(require_version.localStorageKeys.bypassSaveOverwrite, "true");
|
|
12922
|
+
} catch (error) {
|
|
12923
|
+
if (error instanceof axios.AxiosError) {
|
|
12924
|
+
if (error.response?.status === 409) {
|
|
12925
|
+
setState((s) => ({
|
|
12926
|
+
...s,
|
|
12927
|
+
overwriteWithMethod: method
|
|
12928
|
+
}));
|
|
12929
|
+
setOverwriteOpen(true);
|
|
12930
|
+
return;
|
|
12931
|
+
}
|
|
12932
|
+
}
|
|
12933
|
+
toastError(method === "save" ? "Save file failed" : "Rename file failed", error);
|
|
12934
|
+
} finally {
|
|
12935
|
+
handleModalClose();
|
|
12936
|
+
}
|
|
12937
|
+
};
|
|
12938
|
+
const handleOvewriteBack = () => {
|
|
12939
|
+
handleOverwriteClose();
|
|
12940
|
+
setModalOpen(true);
|
|
12941
|
+
setState((s) => {
|
|
12942
|
+
return {
|
|
12943
|
+
...s,
|
|
12944
|
+
overwriteWithMethod: void 0
|
|
12945
|
+
};
|
|
12946
|
+
});
|
|
12947
|
+
};
|
|
12948
|
+
if (cloudMode || isDemoSite) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
12949
|
+
const titleNewInstance = "New Instance" + (hasNonPresetChecks ? " (unsaved)" : "");
|
|
12950
|
+
let titleReadOnlyState;
|
|
12951
|
+
if (featureToggles.disableSaveToFile && fileName) {
|
|
12952
|
+
const generatedAt = envInfo?.stateMetadata?.generated_at;
|
|
12953
|
+
const formattedDate = generatedAt ? formatRunDateTime(new Date(generatedAt)) : null;
|
|
12954
|
+
titleReadOnlyState = formattedDate ? `${fileName} (${formattedDate})` : null;
|
|
12955
|
+
}
|
|
12956
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
12957
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
12958
|
+
direction: "row",
|
|
12959
|
+
alignItems: "center",
|
|
12960
|
+
justifyContent: "center",
|
|
12961
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12962
|
+
sx: { fontWeight: 600 },
|
|
12963
|
+
children: titleReadOnlyState ?? fileName ?? titleNewInstance
|
|
12964
|
+
}), !featureToggles.disableSaveToFile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
12965
|
+
title: fileName ? "Change Filename" : "Save",
|
|
12966
|
+
enterDelay: 1e3,
|
|
12967
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
12968
|
+
onClick: handleOpen,
|
|
12969
|
+
"aria-label": fileName ? "Change Filename" : "Save",
|
|
12970
|
+
size: "small",
|
|
12971
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
12972
|
+
component: fileName ? require_state.IconEdit : require_state.IconSave,
|
|
12973
|
+
sx: {
|
|
12974
|
+
fontSize: 16,
|
|
12975
|
+
verticalAlign: "middle"
|
|
12976
|
+
}
|
|
12977
|
+
})
|
|
12978
|
+
})
|
|
12979
|
+
})]
|
|
12980
|
+
}),
|
|
12981
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Dialog.default, {
|
|
12982
|
+
open: modalOpen,
|
|
12983
|
+
onClose: handleModalClose,
|
|
12984
|
+
children: [
|
|
12985
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogTitle.default, {
|
|
12986
|
+
sx: {
|
|
12987
|
+
display: "flex",
|
|
12988
|
+
alignItems: "center"
|
|
12989
|
+
},
|
|
12990
|
+
children: [
|
|
12991
|
+
fileName ? "Change Filename" : "Save File",
|
|
12992
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { sx: { flexGrow: 1 } }),
|
|
12993
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
12994
|
+
size: "small",
|
|
12995
|
+
onClick: handleModalClose,
|
|
12996
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_io5.IoClose, {})
|
|
12997
|
+
})
|
|
12998
|
+
]
|
|
12999
|
+
}),
|
|
13000
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_DialogContent.default, {
|
|
13001
|
+
onKeyDown: (e) => {
|
|
13002
|
+
e.stopPropagation();
|
|
13003
|
+
},
|
|
13004
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_TextField.default, {
|
|
13005
|
+
inputRef,
|
|
13006
|
+
value: newFileName,
|
|
13007
|
+
label: "File name",
|
|
13008
|
+
placeholder: "Enter filename",
|
|
13009
|
+
error: !!errorMessage,
|
|
13010
|
+
helperText: errorMessage,
|
|
13011
|
+
fullWidth: true,
|
|
13012
|
+
size: "small",
|
|
13013
|
+
sx: { mt: 1 },
|
|
13014
|
+
onChange: (e) => {
|
|
13015
|
+
const value = e.target.value;
|
|
13016
|
+
let newErrorMessage = void 0;
|
|
13017
|
+
if (!value) newErrorMessage = "Filename cannot be empty.";
|
|
13018
|
+
else if (!value.endsWith(".json")) newErrorMessage = "Filename must end with .json.";
|
|
13019
|
+
else if (!/^[a-zA-Z0-9 _-]+\.json$/.test(value)) newErrorMessage = "Invalid filename. Only alphanumeric, space, _ and - are allowed.";
|
|
13020
|
+
else if (fileName && value === fileName) newErrorMessage = "Filename is the same as the current one.";
|
|
13021
|
+
setState((s) => {
|
|
13022
|
+
return {
|
|
13023
|
+
...s,
|
|
13024
|
+
modified: true,
|
|
13025
|
+
newFileName: value,
|
|
13026
|
+
errorMessage: newErrorMessage
|
|
13027
|
+
};
|
|
13028
|
+
});
|
|
13029
|
+
},
|
|
13030
|
+
onKeyDown: (e) => {
|
|
13031
|
+
if (e.key === "Enter") {
|
|
13032
|
+
if (errorMessage) return;
|
|
13033
|
+
if (!fileName) handleAction("save");
|
|
13034
|
+
else handleAction("rename");
|
|
13035
|
+
} else if (e.key === "Escape") handleModalClose();
|
|
13036
|
+
}
|
|
13037
|
+
})
|
|
13038
|
+
}),
|
|
13039
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogActions.default, {
|
|
13040
|
+
sx: { gap: "5px" },
|
|
13041
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13042
|
+
size: "small",
|
|
13043
|
+
color: fileName ? "inherit" : "iochmara",
|
|
13044
|
+
variant: "contained",
|
|
13045
|
+
onClick: async () => {
|
|
13046
|
+
await handleAction("save");
|
|
13047
|
+
},
|
|
13048
|
+
disabled: !newFileName || !!errorMessage || !modified,
|
|
13049
|
+
children: fileName ? "Save as New File" : "Confirm"
|
|
13050
|
+
}), fileName && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13051
|
+
size: "small",
|
|
13052
|
+
color: "iochmara",
|
|
13053
|
+
variant: "contained",
|
|
13054
|
+
onClick: async () => {
|
|
13055
|
+
await handleAction("rename");
|
|
13056
|
+
},
|
|
13057
|
+
disabled: !newFileName || !!errorMessage || !modified,
|
|
13058
|
+
children: "Rename"
|
|
13059
|
+
})]
|
|
13060
|
+
})
|
|
13061
|
+
]
|
|
13062
|
+
}),
|
|
13063
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Dialog.default, {
|
|
13064
|
+
open: overwriteOpen,
|
|
13065
|
+
onClose: handleOverwriteClose,
|
|
13066
|
+
children: [
|
|
13067
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogTitle.default, {
|
|
13068
|
+
sx: {
|
|
13069
|
+
display: "flex",
|
|
13070
|
+
alignItems: "center"
|
|
13071
|
+
},
|
|
13072
|
+
children: [
|
|
13073
|
+
"Overwrite File?",
|
|
13074
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { sx: { flexGrow: 1 } }),
|
|
13075
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13076
|
+
size: "small",
|
|
13077
|
+
onClick: handleOverwriteClose,
|
|
13078
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_io5.IoClose, {})
|
|
13079
|
+
})
|
|
13080
|
+
]
|
|
13081
|
+
}),
|
|
13082
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogContent.default, {
|
|
13083
|
+
sx: {
|
|
13084
|
+
borderTop: "solid 1px",
|
|
13085
|
+
borderBottom: "solid 1px",
|
|
13086
|
+
borderColor: "divider"
|
|
13087
|
+
},
|
|
13088
|
+
onKeyDown: (e) => {
|
|
13089
|
+
e.stopPropagation();
|
|
13090
|
+
},
|
|
13091
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
13092
|
+
sx: { fontSize: "12pt" },
|
|
13093
|
+
children: overwriteWithMethod === "save" ? "Saving a file with this name will overwrite the existing file. Are you sure you wish to continue?" : "Renaming the file with this name will overwrite the existing file. Are you sure you wish to continue?"
|
|
13094
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_FormControlLabel.default, {
|
|
13095
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Checkbox.default, {
|
|
13096
|
+
size: "small",
|
|
13097
|
+
checked: bypass,
|
|
13098
|
+
onChange: (e) => {
|
|
13099
|
+
setState((s) => ({
|
|
13100
|
+
...s,
|
|
13101
|
+
bypass: e.target.checked
|
|
13102
|
+
}));
|
|
13103
|
+
}
|
|
13104
|
+
}),
|
|
13105
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
13106
|
+
sx: {
|
|
13107
|
+
fontWeight: "bold",
|
|
13108
|
+
pt: "8px"
|
|
13109
|
+
},
|
|
13110
|
+
children: "Don't show this again"
|
|
13111
|
+
})
|
|
13112
|
+
})]
|
|
13113
|
+
}),
|
|
13114
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogActions.default, {
|
|
13115
|
+
sx: { gap: "5px" },
|
|
13116
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13117
|
+
variant: "outlined",
|
|
13118
|
+
onClick: handleOvewriteBack,
|
|
13119
|
+
size: "small",
|
|
13120
|
+
children: "Back"
|
|
13121
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13122
|
+
size: "small",
|
|
13123
|
+
color: "iochmara",
|
|
13124
|
+
variant: "contained",
|
|
13125
|
+
onClick: () => {
|
|
13126
|
+
if (!overwriteWithMethod) return;
|
|
13127
|
+
handleAction(overwriteWithMethod, true);
|
|
13128
|
+
handleOverwriteClose();
|
|
13129
|
+
},
|
|
13130
|
+
children: "Overwrite"
|
|
13131
|
+
})]
|
|
13132
|
+
})
|
|
13133
|
+
]
|
|
13134
|
+
})
|
|
13135
|
+
] });
|
|
13136
|
+
};
|
|
13137
|
+
|
|
13138
|
+
//#endregion
|
|
13139
|
+
//#region recce-source/js/src/components/app/StateExporter.tsx
|
|
13140
|
+
function StateExporter() {
|
|
13141
|
+
const { featureToggles } = require_state.useRecceInstanceContext();
|
|
13142
|
+
const handleExport = async () => {
|
|
13143
|
+
try {
|
|
13144
|
+
const jsonData = await require_state.exportState();
|
|
13145
|
+
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
13146
|
+
(0, file_saver.default)(new Blob([jsonString], { type: "application/json" }), `recce-state-${(0, date_fns.format)(/* @__PURE__ */ new Date(), "yyyy-MM-dd-HH-mm-ss")}.json`);
|
|
13147
|
+
} catch (error) {
|
|
13148
|
+
console.error("Export failed", error);
|
|
13149
|
+
require_state.toaster.create({
|
|
13150
|
+
title: "Export failed",
|
|
13151
|
+
description: String(error),
|
|
13152
|
+
type: "error",
|
|
13153
|
+
duration: 5e3,
|
|
13154
|
+
closable: true
|
|
13155
|
+
});
|
|
13156
|
+
}
|
|
13157
|
+
};
|
|
13158
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13159
|
+
title: "Export",
|
|
13160
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13161
|
+
size: "small",
|
|
13162
|
+
"aria-label": "Export state",
|
|
13163
|
+
onClick: async () => {
|
|
13164
|
+
await handleExport();
|
|
13165
|
+
require_state.trackStateAction({ name: "export" });
|
|
13166
|
+
},
|
|
13167
|
+
disabled: featureToggles.disableExportStateFile,
|
|
13168
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13169
|
+
component: require_state.IconExport,
|
|
13170
|
+
sx: {
|
|
13171
|
+
verticalAlign: "middle",
|
|
13172
|
+
width: "16px",
|
|
13173
|
+
height: "16px"
|
|
13174
|
+
}
|
|
13175
|
+
})
|
|
13176
|
+
})
|
|
13177
|
+
});
|
|
13178
|
+
}
|
|
13179
|
+
|
|
13180
|
+
//#endregion
|
|
13181
|
+
//#region recce-source/js/src/components/app/StateSharing.tsx
|
|
13182
|
+
const LOADING_MESSAGES = [
|
|
13183
|
+
"Processing...",
|
|
13184
|
+
"Still processing, please wait...",
|
|
13185
|
+
"Almost there, thanks for your patience..."
|
|
13186
|
+
];
|
|
13187
|
+
function TopLevelShare() {
|
|
13188
|
+
const { successToast, failToast } = require_state.useClipBoardToast();
|
|
13189
|
+
const [, copyToClipboard] = (0, usehooks_ts.useCopyToClipboard)();
|
|
13190
|
+
const { authed } = require_state.useRecceInstanceContext();
|
|
13191
|
+
const { shareUrl, isLoading, error, handleShareClick } = require_RecceCheckContext.useRecceShareStateContext();
|
|
13192
|
+
const [showModal, setShowModal] = (0, react.useState)(false);
|
|
13193
|
+
const [messageIndex, setMessageIndex] = (0, react.useState)(0);
|
|
13194
|
+
const [prevIsLoading, setPrevIsLoading] = (0, react.useState)(isLoading);
|
|
13195
|
+
if (isLoading !== prevIsLoading) {
|
|
13196
|
+
setPrevIsLoading(isLoading);
|
|
13197
|
+
if (isLoading) setMessageIndex(0);
|
|
13198
|
+
}
|
|
13199
|
+
(0, usehooks_ts.useInterval)(() => {
|
|
13200
|
+
setMessageIndex((prev) => Math.min(prev + 1, LOADING_MESSAGES.length - 1));
|
|
13201
|
+
}, isLoading ? 3e4 : null);
|
|
13202
|
+
(0, react.useEffect)(() => {
|
|
13203
|
+
if (error) failToast("Failed to share state", error);
|
|
13204
|
+
}, [error, failToast]);
|
|
13205
|
+
const handleCopy = async () => {
|
|
13206
|
+
try {
|
|
13207
|
+
await copyToClipboard(String(shareUrl));
|
|
13208
|
+
successToast("Copied the link to clipboard");
|
|
13209
|
+
} catch (error$1) {
|
|
13210
|
+
failToast("Failed to copy the link", error$1);
|
|
13211
|
+
}
|
|
13212
|
+
};
|
|
13213
|
+
if (!authed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13214
|
+
direction: "row",
|
|
13215
|
+
sx: {
|
|
13216
|
+
flex: 1,
|
|
13217
|
+
alignItems: "center"
|
|
13218
|
+
},
|
|
13219
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13220
|
+
size: "xsmall",
|
|
13221
|
+
color: "neutral",
|
|
13222
|
+
variant: "outlined",
|
|
13223
|
+
onClick: () => {
|
|
13224
|
+
setShowModal(true);
|
|
13225
|
+
},
|
|
13226
|
+
startIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_tb.TbCloudUpload, {}),
|
|
13227
|
+
children: "Share"
|
|
13228
|
+
}), showModal && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthModal, {
|
|
13229
|
+
parentOpen: showModal,
|
|
13230
|
+
handleParentClose: setShowModal,
|
|
13231
|
+
ignoreCookie: true,
|
|
13232
|
+
variant: "enable-share"
|
|
13233
|
+
})]
|
|
13234
|
+
});
|
|
13235
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13236
|
+
direction: "row",
|
|
13237
|
+
sx: {
|
|
13238
|
+
flex: 1,
|
|
12494
13239
|
alignItems: "center",
|
|
12495
|
-
gap:
|
|
12496
|
-
fontSize: "0.75rem",
|
|
12497
|
-
mr: 2
|
|
13240
|
+
gap: "5px"
|
|
12498
13241
|
},
|
|
12499
13242
|
children: [
|
|
12500
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
12501
|
-
|
|
12502
|
-
|
|
13243
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13244
|
+
size: "xsmall",
|
|
13245
|
+
variant: "outlined",
|
|
13246
|
+
color: "neutral",
|
|
13247
|
+
startIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_tb.TbCloudUpload, {}),
|
|
13248
|
+
endIcon: shareUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13249
|
+
component: react_icons_pi.PiCheckCircle,
|
|
13250
|
+
sx: { color: "success.main" }
|
|
13251
|
+
}) : void 0,
|
|
13252
|
+
onClick: async () => {
|
|
13253
|
+
await handleShareClick();
|
|
13254
|
+
require_state.trackShareState({ name: "create" });
|
|
13255
|
+
},
|
|
13256
|
+
disabled: isLoading,
|
|
13257
|
+
children: isLoading ? "Sharing..." : "Share"
|
|
12503
13258
|
}),
|
|
12504
|
-
|
|
12505
|
-
|
|
13259
|
+
isLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
13260
|
+
sx: {
|
|
13261
|
+
fontSize: 14,
|
|
13262
|
+
color: "grey.500"
|
|
13263
|
+
},
|
|
13264
|
+
children: LOADING_MESSAGES[messageIndex]
|
|
13265
|
+
}),
|
|
13266
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Stack.default, {
|
|
13267
|
+
direction: "row",
|
|
13268
|
+
spacing: .5,
|
|
13269
|
+
alignItems: "center",
|
|
13270
|
+
children: shareUrl && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13271
|
+
sx: {
|
|
13272
|
+
overflowX: "auto",
|
|
13273
|
+
whiteSpace: "nowrap",
|
|
13274
|
+
maxWidth: "350px"
|
|
13275
|
+
},
|
|
13276
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
13277
|
+
sx: { fontSize: 14 },
|
|
13278
|
+
children: shareUrl
|
|
13279
|
+
})
|
|
13280
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13281
|
+
size: "small",
|
|
13282
|
+
"aria-label": "Copy the share URL",
|
|
13283
|
+
onClick: async () => {
|
|
13284
|
+
await handleCopy();
|
|
13285
|
+
require_state.trackShareState({ name: "copy" });
|
|
13286
|
+
},
|
|
13287
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiCopy, {})
|
|
13288
|
+
})] })
|
|
13289
|
+
})
|
|
13290
|
+
]
|
|
13291
|
+
});
|
|
13292
|
+
}
|
|
13293
|
+
|
|
13294
|
+
//#endregion
|
|
13295
|
+
//#region recce-source/js/src/components/app/StateSynchronizer.tsx
|
|
13296
|
+
function isCheckDetailPage(href) {
|
|
13297
|
+
return /^\/checks\/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/.test(href);
|
|
13298
|
+
}
|
|
13299
|
+
function StateSpinner() {
|
|
13300
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13301
|
+
title: "Syncing",
|
|
13302
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13303
|
+
sx: { mx: "10px" },
|
|
13304
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_CircularProgress.default, { size: 20 })
|
|
13305
|
+
})
|
|
13306
|
+
});
|
|
13307
|
+
}
|
|
13308
|
+
function StateSynchronizer() {
|
|
13309
|
+
const [isSyncing, setSyncing] = (0, react.useState)(false);
|
|
13310
|
+
const queryClient = (0, _tanstack_react_query.useQueryClient)();
|
|
13311
|
+
const [location, setLocation] = require_state.useAppLocation();
|
|
13312
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
13313
|
+
const [syncOption, setSyncOption] = (0, react.useState)("");
|
|
13314
|
+
const { data: instanceInfo } = require_state.useRecceInstanceInfo();
|
|
13315
|
+
const handleClose = () => setOpen(false);
|
|
13316
|
+
const handleSync = (0, react.useCallback)(async (input) => {
|
|
13317
|
+
setOpen(false);
|
|
13318
|
+
setSyncing(true);
|
|
13319
|
+
if ((await require_state.syncState(input)).status === "conflict") {
|
|
13320
|
+
setOpen(true);
|
|
13321
|
+
setSyncing(false);
|
|
13322
|
+
return;
|
|
13323
|
+
}
|
|
13324
|
+
while (await require_state.isStateSyncing()) await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
13325
|
+
require_state.toaster.create({
|
|
13326
|
+
description: "Sync Completed",
|
|
13327
|
+
type: "success",
|
|
13328
|
+
duration: 5e3,
|
|
13329
|
+
closable: true
|
|
13330
|
+
});
|
|
13331
|
+
setSyncing(false);
|
|
13332
|
+
setSyncOption("");
|
|
13333
|
+
await queryClient.invalidateQueries({ queryKey: require_state.cacheKeys.lineage() });
|
|
13334
|
+
await queryClient.invalidateQueries({ queryKey: require_state.cacheKeys.checks() });
|
|
13335
|
+
await queryClient.invalidateQueries({ queryKey: require_state.cacheKeys.runs() });
|
|
13336
|
+
if (isCheckDetailPage(location)) setLocation("/checks");
|
|
13337
|
+
}, [
|
|
13338
|
+
queryClient,
|
|
13339
|
+
location,
|
|
13340
|
+
setLocation
|
|
13341
|
+
]);
|
|
13342
|
+
if (isSyncing) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StateSpinner, {});
|
|
13343
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13344
|
+
title: "Sync with Cloud",
|
|
13345
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13346
|
+
size: "small",
|
|
13347
|
+
"aria-label": "Sync state",
|
|
13348
|
+
onClick: () => handleSync(instanceInfo?.session_id ? { method: "merge" } : {}),
|
|
13349
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13350
|
+
component: require_state.IconSync,
|
|
13351
|
+
sx: {
|
|
13352
|
+
fontSize: 16,
|
|
13353
|
+
verticalAlign: "middle"
|
|
13354
|
+
}
|
|
13355
|
+
})
|
|
13356
|
+
})
|
|
13357
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Dialog.default, {
|
|
13358
|
+
open,
|
|
13359
|
+
onClose: handleClose,
|
|
13360
|
+
children: [
|
|
13361
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogTitle.default, {
|
|
13362
|
+
sx: {
|
|
13363
|
+
display: "flex",
|
|
13364
|
+
alignItems: "center",
|
|
13365
|
+
fontWeight: "bold"
|
|
13366
|
+
},
|
|
13367
|
+
children: [
|
|
13368
|
+
"Sync with Cloud",
|
|
13369
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, { sx: { flexGrow: 1 } }),
|
|
13370
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13371
|
+
size: "small",
|
|
13372
|
+
onClick: handleClose,
|
|
13373
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_io5.IoClose, {})
|
|
13374
|
+
})
|
|
13375
|
+
]
|
|
13376
|
+
}),
|
|
13377
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogContent.default, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, { children: "New changes have been detected in the cloud. Please choose a method to sync your state" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13378
|
+
sx: { mt: "5px" },
|
|
13379
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_RadioGroup.default, {
|
|
13380
|
+
value: syncOption,
|
|
13381
|
+
onChange: (e) => {
|
|
13382
|
+
setSyncOption(e.target.value);
|
|
13383
|
+
},
|
|
13384
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13385
|
+
direction: "column",
|
|
13386
|
+
children: [
|
|
13387
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_FormControlLabel.default, {
|
|
13388
|
+
value: "merge",
|
|
13389
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Radio.default, {}),
|
|
13390
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13391
|
+
direction: "row",
|
|
13392
|
+
alignItems: "center",
|
|
13393
|
+
children: ["Merge", /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13394
|
+
title: "This will merge the local and remote states.",
|
|
13395
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13396
|
+
component: react_icons_pi.PiInfo,
|
|
13397
|
+
sx: {
|
|
13398
|
+
ml: 2,
|
|
13399
|
+
cursor: "pointer"
|
|
13400
|
+
}
|
|
13401
|
+
})
|
|
13402
|
+
})]
|
|
13403
|
+
})
|
|
13404
|
+
}),
|
|
13405
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_FormControlLabel.default, {
|
|
13406
|
+
value: "overwrite",
|
|
13407
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Radio.default, {}),
|
|
13408
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13409
|
+
direction: "row",
|
|
13410
|
+
alignItems: "center",
|
|
13411
|
+
children: ["Overwrite", /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13412
|
+
title: "This will overwrite the remote state file with the local state.",
|
|
13413
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13414
|
+
component: react_icons_pi.PiInfo,
|
|
13415
|
+
sx: {
|
|
13416
|
+
ml: 2,
|
|
13417
|
+
cursor: "pointer"
|
|
13418
|
+
}
|
|
13419
|
+
})
|
|
13420
|
+
})]
|
|
13421
|
+
})
|
|
13422
|
+
}),
|
|
13423
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_FormControlLabel.default, {
|
|
13424
|
+
value: "revert",
|
|
13425
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Radio.default, {}),
|
|
13426
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Stack.default, {
|
|
13427
|
+
direction: "row",
|
|
13428
|
+
alignItems: "center",
|
|
13429
|
+
children: ["Revert", /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13430
|
+
title: "This will discard local changes and revert to the cloud state.",
|
|
13431
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13432
|
+
component: react_icons_pi.PiInfo,
|
|
13433
|
+
sx: {
|
|
13434
|
+
ml: 2,
|
|
13435
|
+
cursor: "pointer"
|
|
13436
|
+
}
|
|
13437
|
+
})
|
|
13438
|
+
})]
|
|
13439
|
+
})
|
|
13440
|
+
})
|
|
13441
|
+
]
|
|
13442
|
+
})
|
|
13443
|
+
})
|
|
13444
|
+
})] }),
|
|
13445
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_DialogActions.default, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13446
|
+
onClick: handleClose,
|
|
13447
|
+
sx: { mr: 1 },
|
|
13448
|
+
children: "Cancel"
|
|
13449
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
13450
|
+
color: "iochmara",
|
|
13451
|
+
variant: "contained",
|
|
13452
|
+
onClick: () => handleSync({ method: syncOption || void 0 }),
|
|
13453
|
+
disabled: !syncOption,
|
|
13454
|
+
children: "Sync"
|
|
13455
|
+
})] })
|
|
12506
13456
|
]
|
|
13457
|
+
})] });
|
|
13458
|
+
}
|
|
13459
|
+
|
|
13460
|
+
//#endregion
|
|
13461
|
+
//#region recce-source/js/app/(mainComponents)/NavBar.tsx
|
|
13462
|
+
/**
|
|
13463
|
+
* Route configuration for tabs
|
|
13464
|
+
*/
|
|
13465
|
+
const ROUTE_CONFIG = [
|
|
13466
|
+
{
|
|
13467
|
+
path: "/lineage",
|
|
13468
|
+
name: "Lineage"
|
|
13469
|
+
},
|
|
13470
|
+
{
|
|
13471
|
+
path: "/query",
|
|
13472
|
+
name: "Query"
|
|
13473
|
+
},
|
|
13474
|
+
{
|
|
13475
|
+
path: "/checks",
|
|
13476
|
+
name: "Checklist"
|
|
13477
|
+
}
|
|
13478
|
+
];
|
|
13479
|
+
function TabBadge({ queryKey, fetchCallback, selectCallback }) {
|
|
13480
|
+
const { data: count, isLoading, error } = (0, _tanstack_react_query.useQuery)({
|
|
13481
|
+
queryKey,
|
|
13482
|
+
queryFn: fetchCallback,
|
|
13483
|
+
select: selectCallback
|
|
13484
|
+
});
|
|
13485
|
+
if (isLoading || error || count === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
13486
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13487
|
+
bgcolor: "brand.main",
|
|
13488
|
+
display: "flex",
|
|
13489
|
+
justifyContent: "center",
|
|
13490
|
+
alignItems: "center",
|
|
13491
|
+
p: 1,
|
|
13492
|
+
borderRadius: "100%",
|
|
13493
|
+
color: "white",
|
|
13494
|
+
fontWeight: 700,
|
|
13495
|
+
fontSize: "0.75rem",
|
|
13496
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: count })
|
|
13497
|
+
});
|
|
13498
|
+
}
|
|
13499
|
+
function ChecklistBadge() {
|
|
13500
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TabBadge, {
|
|
13501
|
+
queryKey: require_state.cacheKeys.checks(),
|
|
13502
|
+
fetchCallback: require_state.listChecks,
|
|
13503
|
+
selectCallback: (checks) => {
|
|
13504
|
+
return checks.filter((check) => !check.is_checked).length;
|
|
13505
|
+
}
|
|
13506
|
+
});
|
|
13507
|
+
}
|
|
13508
|
+
function NavBar() {
|
|
13509
|
+
const pathname = (0, next_navigation.usePathname)();
|
|
13510
|
+
const { isDemoSite, isLoading, cloudMode } = require_state.useLineageGraphContext();
|
|
13511
|
+
const { featureToggles } = require_state.useRecceInstanceContext();
|
|
13512
|
+
const { data: flag, isLoading: isFlagLoading } = require_state.useRecceServerFlag();
|
|
13513
|
+
const prevPathnameRef = (0, react.useRef)(null);
|
|
13514
|
+
(0, react.useEffect)(() => {
|
|
13515
|
+
if (prevPathnameRef.current && prevPathnameRef.current !== pathname) require_state.trackNavigation({
|
|
13516
|
+
from: prevPathnameRef.current,
|
|
13517
|
+
to: pathname
|
|
13518
|
+
});
|
|
13519
|
+
prevPathnameRef.current = pathname;
|
|
13520
|
+
}, [pathname]);
|
|
13521
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13522
|
+
sx: {
|
|
13523
|
+
borderBottom: "1px solid lightgray",
|
|
13524
|
+
px: "12px"
|
|
13525
|
+
},
|
|
13526
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
13527
|
+
sx: {
|
|
13528
|
+
display: "grid",
|
|
13529
|
+
gridTemplateColumns: "1fr auto 1fr",
|
|
13530
|
+
width: "100%",
|
|
13531
|
+
alignItems: "center"
|
|
13532
|
+
},
|
|
13533
|
+
children: [
|
|
13534
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tabs.default, {
|
|
13535
|
+
value: (0, react.useMemo)(() => {
|
|
13536
|
+
if (pathname.startsWith("/checks")) return "/checks";
|
|
13537
|
+
if (pathname.startsWith("/query")) return "/query";
|
|
13538
|
+
if (pathname.startsWith("/runs")) return "/runs";
|
|
13539
|
+
return "/lineage";
|
|
13540
|
+
}, [pathname]),
|
|
13541
|
+
sx: {
|
|
13542
|
+
borderBottom: "none",
|
|
13543
|
+
minHeight: "auto"
|
|
13544
|
+
},
|
|
13545
|
+
children: ROUTE_CONFIG.map(({ path, name }) => {
|
|
13546
|
+
if (name === "Query" && flag?.single_env_onboarding) return null;
|
|
13547
|
+
if (name === "Checklist" && ChecklistBadge) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tab.default, {
|
|
13548
|
+
value: path,
|
|
13549
|
+
disabled: isLoading || isFlagLoading,
|
|
13550
|
+
sx: { p: 0 },
|
|
13551
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13552
|
+
sx: {
|
|
13553
|
+
display: "flex",
|
|
13554
|
+
alignItems: "center",
|
|
13555
|
+
gap: "4px"
|
|
13556
|
+
},
|
|
13557
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(next_link.default, {
|
|
13558
|
+
href: path,
|
|
13559
|
+
style: {
|
|
13560
|
+
textDecoration: "none",
|
|
13561
|
+
color: "inherit",
|
|
13562
|
+
padding: "0.875rem 1.1875rem",
|
|
13563
|
+
display: "flex",
|
|
13564
|
+
gap: 3,
|
|
13565
|
+
alignItems: "center"
|
|
13566
|
+
},
|
|
13567
|
+
children: [
|
|
13568
|
+
name,
|
|
13569
|
+
" ",
|
|
13570
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChecklistBadge, {})
|
|
13571
|
+
]
|
|
13572
|
+
})
|
|
13573
|
+
})
|
|
13574
|
+
}, path);
|
|
13575
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tab.default, {
|
|
13576
|
+
value: path,
|
|
13577
|
+
disabled: isLoading || isFlagLoading,
|
|
13578
|
+
sx: { p: 0 },
|
|
13579
|
+
label: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13580
|
+
sx: {
|
|
13581
|
+
display: "flex",
|
|
13582
|
+
alignItems: "center",
|
|
13583
|
+
gap: "4px"
|
|
13584
|
+
},
|
|
13585
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(next_link.default, {
|
|
13586
|
+
href: path,
|
|
13587
|
+
style: {
|
|
13588
|
+
textDecoration: "none",
|
|
13589
|
+
color: "inherit",
|
|
13590
|
+
padding: "0.875rem 1.1875rem"
|
|
13591
|
+
},
|
|
13592
|
+
children: name
|
|
13593
|
+
})
|
|
13594
|
+
})
|
|
13595
|
+
}, path);
|
|
13596
|
+
})
|
|
13597
|
+
}),
|
|
13598
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
13599
|
+
sx: {
|
|
13600
|
+
display: "flex",
|
|
13601
|
+
alignItems: "center",
|
|
13602
|
+
gap: "12px",
|
|
13603
|
+
justifyContent: "center"
|
|
13604
|
+
},
|
|
13605
|
+
children: [!isLoading && !isDemoSite && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Filename, {}), !isLoading && !isDemoSite && !flag?.single_env_onboarding && !featureToggles.disableShare && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TopLevelShare, {})]
|
|
13606
|
+
}),
|
|
13607
|
+
!isLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Box.default, {
|
|
13608
|
+
sx: {
|
|
13609
|
+
display: "flex",
|
|
13610
|
+
justifyContent: "right",
|
|
13611
|
+
alignItems: "center",
|
|
13612
|
+
mr: "8px"
|
|
13613
|
+
},
|
|
13614
|
+
children: [
|
|
13615
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnvInfo, {}),
|
|
13616
|
+
cloudMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StateSynchronizer, {}),
|
|
13617
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StateExporter, {})
|
|
13618
|
+
]
|
|
13619
|
+
})
|
|
13620
|
+
]
|
|
13621
|
+
})
|
|
13622
|
+
});
|
|
13623
|
+
}
|
|
13624
|
+
|
|
13625
|
+
//#endregion
|
|
13626
|
+
//#region recce-source/js/app/(mainComponents)/DisplayModeToggle.tsx
|
|
13627
|
+
/**
|
|
13628
|
+
* Display Mode Toggle - switches between light and dark themes
|
|
13629
|
+
*
|
|
13630
|
+
* Uses next-themes to persist the user's preference.
|
|
13631
|
+
* Default is light theme, with future support for system preference.
|
|
13632
|
+
*/
|
|
13633
|
+
function DisplayModeToggle() {
|
|
13634
|
+
const { setTheme, resolvedTheme } = (0, next_themes.useTheme)();
|
|
13635
|
+
const [mounted, setMounted] = (0, react.useState)(false);
|
|
13636
|
+
(0, react.useEffect)(() => {
|
|
13637
|
+
setMounted(true);
|
|
13638
|
+
}, []);
|
|
13639
|
+
const toggleTheme = () => {
|
|
13640
|
+
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
|
13641
|
+
};
|
|
13642
|
+
if (!mounted) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13643
|
+
size: "small",
|
|
13644
|
+
sx: {
|
|
13645
|
+
color: "rgba(255, 255, 255, 0.8)",
|
|
13646
|
+
"&:hover": { bgcolor: "rgba(255, 255, 255, 0.1)" }
|
|
13647
|
+
},
|
|
13648
|
+
disabled: true,
|
|
13649
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiSun, { style: {
|
|
13650
|
+
width: 18,
|
|
13651
|
+
height: 18
|
|
13652
|
+
} })
|
|
13653
|
+
});
|
|
13654
|
+
const isDark = resolvedTheme === "dark";
|
|
13655
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Tooltip.default, {
|
|
13656
|
+
title: isDark ? "Switch to light mode" : "Switch to dark mode",
|
|
13657
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_IconButton.default, {
|
|
13658
|
+
size: "small",
|
|
13659
|
+
onClick: toggleTheme,
|
|
13660
|
+
sx: {
|
|
13661
|
+
color: "rgba(255, 255, 255, 0.8)",
|
|
13662
|
+
"&:hover": { bgcolor: "rgba(255, 255, 255, 0.1)" }
|
|
13663
|
+
},
|
|
13664
|
+
"aria-label": isDark ? "Switch to light mode" : "Switch to dark mode",
|
|
13665
|
+
children: isDark ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiSun, { style: {
|
|
13666
|
+
width: 18,
|
|
13667
|
+
height: 18
|
|
13668
|
+
} }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiMoon, { style: {
|
|
13669
|
+
width: 18,
|
|
13670
|
+
height: 18
|
|
13671
|
+
} })
|
|
13672
|
+
})
|
|
13673
|
+
});
|
|
13674
|
+
}
|
|
13675
|
+
|
|
13676
|
+
//#endregion
|
|
13677
|
+
//#region recce-source/js/app/(mainComponents)/RecceVersionBadge.tsx
|
|
13678
|
+
function RecceVersionBadge() {
|
|
13679
|
+
const { version, latestVersion } = require_version.useVersionNumber();
|
|
13680
|
+
const versionFormatRegex = (0, react.useMemo)(() => /* @__PURE__ */ new RegExp("^\\d+\\.\\d+\\.\\d+$"), []);
|
|
13681
|
+
(0, react.useEffect)(() => {
|
|
13682
|
+
if (versionFormatRegex.test(version) && version !== latestVersion) {
|
|
13683
|
+
const storageKey = "recce-update-toast-shown";
|
|
13684
|
+
if (sessionStorage.getItem(storageKey)) return;
|
|
13685
|
+
setTimeout(() => {
|
|
13686
|
+
require_state.toaster.create({
|
|
13687
|
+
id: "recce-update-available",
|
|
13688
|
+
title: "Update available",
|
|
13689
|
+
description: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
13690
|
+
"A new version of Recce (v",
|
|
13691
|
+
latestVersion,
|
|
13692
|
+
") is available.",
|
|
13693
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("br", {}),
|
|
13694
|
+
"Please run",
|
|
13695
|
+
" ",
|
|
13696
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Box.default, {
|
|
13697
|
+
component: "code",
|
|
13698
|
+
sx: {
|
|
13699
|
+
bgcolor: "grey.200",
|
|
13700
|
+
px: .5,
|
|
13701
|
+
py: .25,
|
|
13702
|
+
borderRadius: .5,
|
|
13703
|
+
fontFamily: "monospace",
|
|
13704
|
+
fontSize: "0.875em"
|
|
13705
|
+
},
|
|
13706
|
+
children: "pip install --upgrade recce"
|
|
13707
|
+
}),
|
|
13708
|
+
" ",
|
|
13709
|
+
"to update Recce.",
|
|
13710
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("br", {}),
|
|
13711
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Link.default, {
|
|
13712
|
+
sx: {
|
|
13713
|
+
color: "primary.main",
|
|
13714
|
+
fontWeight: "bold",
|
|
13715
|
+
"&:hover": { textDecoration: "underline" }
|
|
13716
|
+
},
|
|
13717
|
+
href: `https://github.com/DataRecce/recce/releases/tag/v${latestVersion}`,
|
|
13718
|
+
target: "_blank",
|
|
13719
|
+
children: "Click here to view the detail of latest release"
|
|
13720
|
+
})
|
|
13721
|
+
] }),
|
|
13722
|
+
duration: 60 * 1e3,
|
|
13723
|
+
closable: true
|
|
13724
|
+
});
|
|
13725
|
+
sessionStorage.setItem(storageKey, "true");
|
|
13726
|
+
}, 0);
|
|
13727
|
+
}
|
|
13728
|
+
}, [
|
|
13729
|
+
version,
|
|
13730
|
+
latestVersion,
|
|
13731
|
+
versionFormatRegex
|
|
13732
|
+
]);
|
|
13733
|
+
if (!versionFormatRegex.test(version)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Typography.default, {
|
|
13734
|
+
component: "span",
|
|
13735
|
+
sx: {
|
|
13736
|
+
fontSize: "sm",
|
|
13737
|
+
color: "rgba(255,255,255,0.8)",
|
|
13738
|
+
textTransform: "uppercase",
|
|
13739
|
+
borderWidth: 1,
|
|
13740
|
+
px: 1,
|
|
13741
|
+
borderRadius: .75
|
|
13742
|
+
},
|
|
13743
|
+
children: version
|
|
13744
|
+
});
|
|
13745
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Link.default, {
|
|
13746
|
+
href: `https://github.com/DataRecce/recce/releases/tag/v${version}`,
|
|
13747
|
+
sx: {
|
|
13748
|
+
"&:hover": { textDecoration: "none" },
|
|
13749
|
+
fontSize: "sm",
|
|
13750
|
+
color: "rgba(255,255,255,0.8)",
|
|
13751
|
+
textTransform: "uppercase",
|
|
13752
|
+
borderWidth: 1,
|
|
13753
|
+
px: 1,
|
|
13754
|
+
borderRadius: .75
|
|
13755
|
+
},
|
|
13756
|
+
target: "_blank",
|
|
13757
|
+
children: version
|
|
12507
13758
|
});
|
|
12508
13759
|
}
|
|
12509
13760
|
|
|
@@ -12556,6 +13807,12 @@ Object.defineProperty(exports, 'DiffEditor_default', {
|
|
|
12556
13807
|
return DiffEditor_default;
|
|
12557
13808
|
}
|
|
12558
13809
|
});
|
|
13810
|
+
Object.defineProperty(exports, 'DisplayModeToggle', {
|
|
13811
|
+
enumerable: true,
|
|
13812
|
+
get: function () {
|
|
13813
|
+
return DisplayModeToggle;
|
|
13814
|
+
}
|
|
13815
|
+
});
|
|
12559
13816
|
Object.defineProperty(exports, 'EnvInfo', {
|
|
12560
13817
|
enumerable: true,
|
|
12561
13818
|
get: function () {
|
|
@@ -12640,6 +13897,12 @@ Object.defineProperty(exports, 'MuiProvider', {
|
|
|
12640
13897
|
return MuiProvider;
|
|
12641
13898
|
}
|
|
12642
13899
|
});
|
|
13900
|
+
Object.defineProperty(exports, 'NavBar', {
|
|
13901
|
+
enumerable: true,
|
|
13902
|
+
get: function () {
|
|
13903
|
+
return NavBar;
|
|
13904
|
+
}
|
|
13905
|
+
});
|
|
12643
13906
|
Object.defineProperty(exports, 'NodeSqlView', {
|
|
12644
13907
|
enumerable: true,
|
|
12645
13908
|
get: function () {
|
|
@@ -12664,6 +13927,12 @@ Object.defineProperty(exports, 'QueryPage', {
|
|
|
12664
13927
|
return QueryPage;
|
|
12665
13928
|
}
|
|
12666
13929
|
});
|
|
13930
|
+
Object.defineProperty(exports, 'RecceVersionBadge', {
|
|
13931
|
+
enumerable: true,
|
|
13932
|
+
get: function () {
|
|
13933
|
+
return RecceVersionBadge;
|
|
13934
|
+
}
|
|
13935
|
+
});
|
|
12667
13936
|
Object.defineProperty(exports, 'ResourceTypeTag', {
|
|
12668
13937
|
enumerable: true,
|
|
12669
13938
|
get: function () {
|
|
@@ -12748,6 +14017,12 @@ Object.defineProperty(exports, 'SummaryView', {
|
|
|
12748
14017
|
return SummaryView;
|
|
12749
14018
|
}
|
|
12750
14019
|
});
|
|
14020
|
+
Object.defineProperty(exports, 'TopBar', {
|
|
14021
|
+
enumerable: true,
|
|
14022
|
+
get: function () {
|
|
14023
|
+
return TopBar;
|
|
14024
|
+
}
|
|
14025
|
+
});
|
|
12751
14026
|
Object.defineProperty(exports, 'VSplit', {
|
|
12752
14027
|
enumerable: true,
|
|
12753
14028
|
get: function () {
|
|
@@ -12760,4 +14035,4 @@ Object.defineProperty(exports, 'mui_provider_default', {
|
|
|
12760
14035
|
return mui_provider_default;
|
|
12761
14036
|
}
|
|
12762
14037
|
});
|
|
12763
|
-
//# sourceMappingURL=components-
|
|
14038
|
+
//# sourceMappingURL=components-DXbVq9Cw.js.map
|