@datarecce/ui 0.1.1 → 0.1.8
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/README.md +89 -35
- package/dist/agGridStyles-L5J6VVIU.css +54 -0
- package/dist/api.js.map +1 -1
- package/dist/api.mjs.map +1 -1
- package/dist/components.js +7834 -4836
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +7553 -4584
- package/dist/components.mjs.map +1 -1
- package/dist/hooks.js +129 -61
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs +116 -56
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.js +7837 -4839
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7553 -4584
- package/dist/index.mjs.map +1 -1
- package/dist/style-LYNBK7ND.css +106 -0
- package/dist/styles-TU5BYTIL.css +21 -0
- package/package.json +24 -13
- package/dist/reload-image-PGVLW7NX.svg +0 -4
- package/dist/styles-LEL5RGUW.css +0 -67
package/dist/hooks.js
CHANGED
|
@@ -2,14 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
var reactQuery = require('@tanstack/react-query');
|
|
4
4
|
var axios = require('axios');
|
|
5
|
-
|
|
5
|
+
require('@mui/material/Alert');
|
|
6
|
+
require('@mui/material/CircularProgress');
|
|
7
|
+
require('@mui/material/Snackbar');
|
|
8
|
+
var Stack2 = require('@mui/material/Stack');
|
|
9
|
+
require('@mui/material/Typography');
|
|
10
|
+
var react = require('react');
|
|
6
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
-
var
|
|
12
|
+
var Box = require('@mui/material/Box');
|
|
13
|
+
var Button = require('@mui/material/Button');
|
|
14
|
+
var MuiDialog = require('@mui/material/Dialog');
|
|
15
|
+
var DialogActions = require('@mui/material/DialogActions');
|
|
16
|
+
var DialogContent = require('@mui/material/DialogContent');
|
|
17
|
+
var DialogTitle = require('@mui/material/DialogTitle');
|
|
18
|
+
var IconButton = require('@mui/material/IconButton');
|
|
19
|
+
var io5 = require('react-icons/io5');
|
|
8
20
|
var unified = require('@amplitude/unified');
|
|
9
21
|
|
|
10
22
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
23
|
|
|
12
24
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
25
|
+
var Stack2__default = /*#__PURE__*/_interopDefault(Stack2);
|
|
26
|
+
var Box__default = /*#__PURE__*/_interopDefault(Box);
|
|
27
|
+
var Button__default = /*#__PURE__*/_interopDefault(Button);
|
|
28
|
+
var MuiDialog__default = /*#__PURE__*/_interopDefault(MuiDialog);
|
|
29
|
+
var DialogActions__default = /*#__PURE__*/_interopDefault(DialogActions);
|
|
30
|
+
var DialogContent__default = /*#__PURE__*/_interopDefault(DialogContent);
|
|
31
|
+
var DialogTitle__default = /*#__PURE__*/_interopDefault(DialogTitle);
|
|
32
|
+
var IconButton__default = /*#__PURE__*/_interopDefault(IconButton);
|
|
13
33
|
|
|
14
34
|
// recce-source/js/src/lib/api/cacheKeys.ts
|
|
15
35
|
var cacheKeys = {
|
|
@@ -52,10 +72,37 @@ var useRecceInstanceInfo = () => {
|
|
|
52
72
|
queryFn: getRecceInstanceInfo
|
|
53
73
|
});
|
|
54
74
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
react.createContext(null);
|
|
76
|
+
var toastIdCounter = 0;
|
|
77
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
78
|
+
var toaster = {
|
|
79
|
+
create: (options) => {
|
|
80
|
+
const id = options.id || `toast-${++toastIdCounter}`;
|
|
81
|
+
listeners.forEach(
|
|
82
|
+
(listener) => listener({ type: "create", options: { ...options, id } })
|
|
83
|
+
);
|
|
84
|
+
return id;
|
|
85
|
+
},
|
|
86
|
+
success: (options) => toaster.create({ ...options, type: "success" }),
|
|
87
|
+
error: (options) => toaster.create({ ...options, type: "error" }),
|
|
88
|
+
warning: (options) => toaster.create({ ...options, type: "warning" }),
|
|
89
|
+
info: (options) => toaster.create({ ...options, type: "info" }),
|
|
90
|
+
loading: (options) => toaster.create({ ...options, type: "loading" }),
|
|
91
|
+
dismiss: (id) => {
|
|
92
|
+
listeners.forEach((listener) => listener({ type: "dismiss", id }));
|
|
93
|
+
},
|
|
94
|
+
// Alias for dismiss (for backward compatibility)
|
|
95
|
+
remove: (id) => {
|
|
96
|
+
listeners.forEach((listener) => listener({ type: "dismiss", id }));
|
|
97
|
+
},
|
|
98
|
+
update: (id, options) => {
|
|
99
|
+
listeners.forEach((listener) => listener({ type: "update", id, options }));
|
|
100
|
+
},
|
|
101
|
+
subscribe: (listener) => {
|
|
102
|
+
listeners.add(listener);
|
|
103
|
+
return () => listeners.delete(listener);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
59
106
|
|
|
60
107
|
// recce-source/js/src/lib/hooks/useCheckToast.tsx
|
|
61
108
|
function useCheckToast() {
|
|
@@ -95,9 +142,9 @@ function useClipBoardToast() {
|
|
|
95
142
|
failToast
|
|
96
143
|
};
|
|
97
144
|
}
|
|
98
|
-
var LineageViewContext = react
|
|
145
|
+
var LineageViewContext = react.createContext(void 0);
|
|
99
146
|
var useLineageViewContext = () => {
|
|
100
|
-
return react
|
|
147
|
+
return react.useContext(LineageViewContext);
|
|
101
148
|
};
|
|
102
149
|
function track(eventInput, eventProperties, eventOptions) {
|
|
103
150
|
{
|
|
@@ -115,27 +162,24 @@ function trackExploreActionForm(props) {
|
|
|
115
162
|
track("[Web] explore_action_form", props);
|
|
116
163
|
}
|
|
117
164
|
function useValueDiffAlertDialog() {
|
|
118
|
-
const
|
|
119
|
-
const [nodeCount, setNodeCount] = react
|
|
120
|
-
const [resolvePromise, setResolvePromise] = react
|
|
121
|
-
const cancelRef = react
|
|
122
|
-
const confirm = react
|
|
123
|
-
(nodeCount2)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
},
|
|
130
|
-
[onOpen]
|
|
131
|
-
);
|
|
165
|
+
const [open, setOpen] = react.useState(false);
|
|
166
|
+
const [nodeCount, setNodeCount] = react.useState(0);
|
|
167
|
+
const [resolvePromise, setResolvePromise] = react.useState();
|
|
168
|
+
const cancelRef = react.useRef(null);
|
|
169
|
+
const confirm = react.useCallback((nodeCount2) => {
|
|
170
|
+
setNodeCount(nodeCount2);
|
|
171
|
+
return new Promise((resolve) => {
|
|
172
|
+
setResolvePromise(() => resolve);
|
|
173
|
+
setOpen(true);
|
|
174
|
+
});
|
|
175
|
+
}, []);
|
|
132
176
|
const handleConfirm = () => {
|
|
133
177
|
trackExploreActionForm({
|
|
134
178
|
action: EXPLORE_ACTION.VALUE_DIFF,
|
|
135
179
|
event: EXPLORE_FORM_EVENT.EXECUTE
|
|
136
180
|
});
|
|
137
181
|
resolvePromise?.(true);
|
|
138
|
-
|
|
182
|
+
setOpen(false);
|
|
139
183
|
};
|
|
140
184
|
const handleCancel = () => {
|
|
141
185
|
trackExploreActionForm({
|
|
@@ -143,47 +187,71 @@ function useValueDiffAlertDialog() {
|
|
|
143
187
|
event: EXPLORE_FORM_EVENT.CANCEL
|
|
144
188
|
});
|
|
145
189
|
resolvePromise?.(false);
|
|
146
|
-
|
|
190
|
+
setOpen(false);
|
|
147
191
|
};
|
|
148
|
-
const ValueDiffAlertDialog = /* @__PURE__ */ jsxRuntime.
|
|
149
|
-
|
|
192
|
+
const ValueDiffAlertDialog = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
193
|
+
MuiDialog__default.default,
|
|
150
194
|
{
|
|
151
|
-
size: "xl",
|
|
152
195
|
open,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
onClose: handleCancel,
|
|
197
|
+
maxWidth: "md",
|
|
198
|
+
fullWidth: true,
|
|
199
|
+
"aria-labelledby": "value-diff-alert-dialog-title",
|
|
200
|
+
children: [
|
|
201
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
202
|
+
DialogTitle__default.default,
|
|
203
|
+
{
|
|
204
|
+
id: "value-diff-alert-dialog-title",
|
|
205
|
+
sx: { fontSize: "1.125rem", fontWeight: "bold" },
|
|
206
|
+
children: [
|
|
207
|
+
"Value Diff on ",
|
|
208
|
+
nodeCount,
|
|
209
|
+
" nodes"
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
214
|
+
IconButton__default.default,
|
|
215
|
+
{
|
|
216
|
+
"aria-label": "close",
|
|
217
|
+
onClick: handleCancel,
|
|
218
|
+
sx: {
|
|
219
|
+
position: "absolute",
|
|
220
|
+
right: 8,
|
|
221
|
+
top: 8,
|
|
222
|
+
color: "grey.500"
|
|
223
|
+
},
|
|
224
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(io5.IoClose, {})
|
|
225
|
+
}
|
|
226
|
+
),
|
|
227
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogContent__default.default, { children: /* @__PURE__ */ jsxRuntime.jsx(Stack2__default.default, { spacing: "20px", children: /* @__PURE__ */ jsxRuntime.jsxs(Box__default.default, { children: [
|
|
228
|
+
"Value diff will be executed on ",
|
|
229
|
+
nodeCount,
|
|
230
|
+
" nodes in the Lineage, which can add extra costs to your bill."
|
|
231
|
+
] }) }) }),
|
|
232
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogActions__default.default, { sx: { gap: 0.5 }, children: [
|
|
233
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
234
|
+
Button__default.default,
|
|
235
|
+
{
|
|
236
|
+
ref: cancelRef,
|
|
237
|
+
onClick: handleCancel,
|
|
238
|
+
variant: "outlined",
|
|
239
|
+
color: "neutral",
|
|
240
|
+
children: "Cancel"
|
|
241
|
+
}
|
|
242
|
+
),
|
|
243
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
244
|
+
Button__default.default,
|
|
245
|
+
{
|
|
246
|
+
color: "iochmara",
|
|
247
|
+
variant: "contained",
|
|
248
|
+
onClick: handleConfirm,
|
|
249
|
+
sx: { ml: 1.5 },
|
|
250
|
+
children: "Execute"
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
] })
|
|
254
|
+
]
|
|
187
255
|
}
|
|
188
256
|
);
|
|
189
257
|
return { confirm, AlertDialog: ValueDiffAlertDialog };
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../recce-source/js/src/lib/api/cacheKeys.ts","../recce-source/js/src/lib/const.ts","../recce-source/js/src/lib/api/axiosClient.ts","../recce-source/js/src/lib/api/instanceInfo.ts","../recce-source/js/src/lib/hooks/useRecceInstanceInfo.tsx","../recce-source/js/src/components/ui/toaster.tsx","../recce-source/js/src/lib/hooks/useCheckToast.tsx","../recce-source/js/src/lib/hooks/useClipBoardToast.tsx","../recce-source/js/src/components/lineage/LineageViewContext.tsx","../recce-source/js/src/lib/api/track.ts","../recce-source/js/src/components/lineage/useValueDiffAlertDialog.tsx"],"names":["axios","QueryClient","useQuery","createToaster","createContext","useContext","trk","useDisclosure","useState","useRef","useCallback","nodeCount","jsx","Dialog","jsxs","Portal","Flex","Box","Button","CloseButton"],"mappings":"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","file":"hooks.js","sourcesContent":["export const cacheKeys = {\n rowCount: (model: string) => [\"row_count\", model],\n lineage: () => [\"lineage\"],\n checks: () => [\"checks\", \"list\"],\n check: (checkId: string) => [\"checks\", checkId],\n checkEvents: (checkId: string) => [\"checks\", checkId, \"events\"],\n runs: () => [\"runs\"],\n run: (runId: string) => [\"runs\", runId],\n runsAggregated: () => [\"runs_aggregated\"],\n flag: () => [\"flag\"],\n instanceInfo: () => [\"instance_info\"],\n user: () => [\"user\"],\n};\n","let apiUrl = process.env.NEXT_PUBLIC_API_URL;\napiUrl ??= typeof window !== \"undefined\" ? window.location.origin : \"\";\n\nexport const PUBLIC_API_URL = apiUrl;\n\nlet cloudWebUrl = process.env.NEXT_PUBLIC_CLOUD_WEB_URL;\ncloudWebUrl ??= \"https://cloud.datarecce.io\";\n\nexport const PUBLIC_CLOUD_WEB_URL = cloudWebUrl;\n","import { QueryClient } from \"@tanstack/react-query\";\nimport axios from \"axios\";\nimport { PUBLIC_API_URL } from \"@/lib/const\";\n\nexport const axiosClient = axios.create({\n baseURL: PUBLIC_API_URL,\n});\n\nexport const reactQueryClient = new QueryClient();\n","import { AxiosResponse } from \"axios\";\nimport { axiosClient } from \"./axiosClient\";\n\nexport interface RecceInstanceInfo {\n server_mode: \"server\" | \"preview\" | \"read-only\";\n single_env: boolean;\n authed: boolean;\n cloud_instance: boolean;\n lifetime_expired_at?: Date;\n idle_timeout?: number;\n share_url?: string;\n session_id?: string;\n organization_name?: string;\n web_url?: string;\n}\n\nexport async function getRecceInstanceInfo(): Promise<RecceInstanceInfo> {\n return (\n await axiosClient.get<never, AxiosResponse<RecceInstanceInfo>>(\n \"/api/instance-info\",\n )\n ).data;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { cacheKeys } from \"../api/cacheKeys\";\nimport { getRecceInstanceInfo, RecceInstanceInfo } from \"../api/instanceInfo\";\n\nexport const useRecceInstanceInfo = () => {\n return useQuery<RecceInstanceInfo>({\n queryKey: cacheKeys.instanceInfo(),\n queryFn: getRecceInstanceInfo,\n });\n};\n","\"use client\";\n\nimport type { CreateToasterReturn } from \"@chakra-ui/react\";\nimport {\n Toaster as ChakraToaster,\n createToaster,\n Portal,\n Spinner,\n Stack,\n Toast,\n} from \"@chakra-ui/react\";\n\nexport const toaster: CreateToasterReturn = createToaster({\n placement: \"bottom-end\",\n pauseOnPageIdle: true,\n});\n\nexport const Toaster = () => {\n return (\n <Portal>\n <ChakraToaster toaster={toaster} insetInline={{ mdDown: \"4\" }}>\n {(toast) => (\n <Toast.Root width={{ md: \"sm\" }}>\n {toast.type === \"loading\" ? (\n <Spinner size=\"sm\" color=\"blue.solid\" />\n ) : (\n <Toast.Indicator />\n )}\n <Stack gap=\"1\" flex=\"1\" maxWidth=\"100%\">\n {toast.title && <Toast.Title>{toast.title}</Toast.Title>}\n {toast.description && (\n <Toast.Description>{toast.description}</Toast.Description>\n )}\n </Stack>\n {toast.action && (\n <Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>\n )}\n {toast.closable && <Toast.CloseTrigger />}\n </Toast.Root>\n )}\n </ChakraToaster>\n </Portal>\n );\n};\n","import { toaster } from \"@/components/ui/toaster\";\n\nexport function useCheckToast() {\n function markedAsApprovedToast() {\n toaster.create({\n title: \"Marked as approved\",\n type: \"success\",\n duration: 2000,\n });\n }\n return {\n markedAsApprovedToast,\n };\n}\n","import { toaster } from \"@/components/ui/toaster\";\n\nexport function useClipBoardToast() {\n function successToast(message: string) {\n toaster.create({\n description: message,\n type: \"info\",\n duration: 5000,\n closable: true,\n });\n }\n\n function failToast(title: string, error: unknown) {\n toaster.create({\n title: title,\n description: String(error),\n type: \"error\",\n duration: 5000,\n closable: true,\n });\n }\n\n return {\n successToast,\n failToast,\n };\n}\n","import React, { createContext, useContext } from \"react\";\nimport { CllInput, ColumnLineageData } from \"@/lib/api/cll\";\nimport { LineageDiffViewOptions } from \"@/lib/api/lineagecheck\";\nimport { Run } from \"@/lib/api/types\";\nimport { LineageGraphNode, LineageGraphNodes } from \"./lineage\";\n\ntype NewType = LineageDiffViewOptions;\ntype ActionMode = \"per_node\" | \"multi_nodes\";\n\ninterface NodeAction {\n mode: ActionMode;\n status?: \"pending\" | \"running\" | \"success\" | \"failure\" | \"skipped\";\n skipReason?: string;\n run?: Run;\n}\n\nexport interface ActionState {\n mode: ActionMode;\n status: \"pending\" | \"running\" | \"canceling\" | \"canceled\" | \"completed\";\n currentRun?: Partial<Run>;\n completed: number;\n total: number;\n actions: Record<string, NodeAction>;\n}\n\nexport interface LineageViewContextType {\n interactive: boolean;\n nodes: LineageGraphNodes[];\n focusedNode?: LineageGraphNode;\n selectedNodes: LineageGraphNode[];\n cll: ColumnLineageData | undefined;\n\n // context menu\n showContextMenu: (event: React.MouseEvent, node: LineageGraphNodes) => void;\n\n // filter\n viewOptions: LineageDiffViewOptions;\n onViewOptionsChanged: (options: NewType) => void;\n\n // Multi nodes selection\n selectMode: \"selecting\" | \"action_result\" | undefined;\n selectNode: (nodeId: string) => void;\n selectParentNodes: (nodeId: string, degree?: number) => void;\n selectChildNodes: (nodeId: string, degree?: number) => void;\n deselect: () => void;\n\n // node state\n isNodeHighlighted: (nodeId: string) => boolean;\n isNodeSelected: (nodeId: string) => boolean;\n isEdgeHighlighted: (source: string, target: string) => boolean;\n getNodeAction: (nodeId: string) => NodeAction;\n getNodeColumnSet: (nodeId: string) => Set<string>;\n isNodeShowingChangeAnalysis: (nodeId: string) => boolean;\n\n //actions\n runRowCount: () => Promise<void>;\n runRowCountDiff: () => Promise<void>;\n runValueDiff: () => Promise<void>;\n addLineageDiffCheck: (viewMode?: string) => void;\n addSchemaDiffCheck: () => void;\n cancel: () => void;\n actionState: ActionState;\n\n // Column Level Lineage\n centerNode: (nodeId: string) => void;\n showColumnLevelLineage: (cll?: CllInput) => Promise<void>;\n resetColumnLevelLineage: (previous?: boolean) => Promise<void>;\n}\n\nexport const LineageViewContext = createContext<\n LineageViewContextType | undefined\n>(undefined);\n\nexport const useLineageViewContextSafe = (): LineageViewContextType => {\n const context = useContext(LineageViewContext);\n if (!context) {\n throw new Error(\n \"useLineageViewContext must be used within a LineageViewProvider\",\n );\n }\n return context;\n};\n\nexport const useLineageViewContext = (): LineageViewContextType | undefined => {\n return useContext(LineageViewContext);\n};\n","import {\n AmplitudeReturn,\n BaseEvent,\n EventOptions,\n Result,\n} from \"@amplitude/analytics-core\";\nimport { initAll, track as trk } from \"@amplitude/unified\";\n\nfunction track(\n eventInput: string | BaseEvent,\n // biome-ignore lint/suspicious/noExplicitAny: Amplitude library uses any for event properties\n eventProperties?: Record<string, any> | undefined,\n eventOptions?: EventOptions | undefined,\n): AmplitudeReturn<Result> {\n // If Amplitude isn't initialized, log to console instead\n if (!amplitudeInitialized) {\n console.log(\"[Tracking]\", eventInput, eventProperties, eventOptions);\n }\n return trk(eventInput, eventProperties, eventOptions);\n}\n\nlet amplitudeInitialized = false;\n\nexport function trackInit() {\n function getCookie(key: string) {\n const b = document.cookie.match(\"(^|;)\\\\s*\" + key + \"\\\\s*=\\\\s*([^;]+)\");\n return b ? b.pop() : \"\";\n }\n\n const userId =\n process.env.NODE_ENV === \"development\"\n ? \"web_dev\"\n : getCookie(\"recce_user_id\");\n const apiKey = process.env.AMPLITUDE_API_KEY;\n if (userId && apiKey) {\n try {\n void initAll(apiKey, {\n analytics: {\n userId,\n autocapture: true,\n },\n sessionReplay: {\n sampleRate: 1,\n },\n });\n amplitudeInitialized = true;\n } catch (e) {\n console.error(e);\n }\n }\n\n // Log when Amplitude is not initialized (for development/debugging)\n if (!amplitudeInitialized) {\n console.log(\n \"[Tracking] Amplitude not initialized (missing API key or user ID). Events will be logged to console instead.\",\n );\n }\n}\n\ninterface MultiNodeActionProps {\n type:\n | \"row_count\"\n | \"row_count_diff\"\n | \"value_diff\"\n | \"schema_diff\"\n | \"lineage_diff\";\n selected: \"single\" | \"multi\" | \"none\";\n}\n\nexport function trackMultiNodesAction(props: MultiNodeActionProps) {\n track(\"[Web] multi_nodes_action\", props);\n}\n\ninterface HistoryActionProps {\n name: \"show\" | \"hide\" | \"click_run\" | \"add_to_checklist\" | \"go_to_check\";\n}\n\nexport function trackHistoryAction(props: HistoryActionProps) {\n track(\"[Web] history_action\", props);\n}\n\ninterface PreviewChangeProps {\n action: \"explore\" | \"run\" | \"close\";\n node?: string;\n status?: \"success\" | \"failure\";\n}\n\nexport function trackPreviewChange(props: PreviewChangeProps) {\n track(\"[Experiment] preview_change\", props);\n}\n\ninterface PreviewChangeFeedbackProps {\n feedback: \"like\" | \"dislike\" | \"form\";\n node?: string;\n}\n\nexport function trackPreviewChangeFeedback(props: PreviewChangeFeedbackProps) {\n track(\"[Experiment] preview_change\", props);\n}\n\ninterface SingleEnvironmentProps {\n action:\n | \"onboarding\"\n | \"external_link\"\n | \"preview_changes\"\n | `target_base_added`;\n from?: \"onboarding\" | \"preview_changes\";\n node?: string;\n}\n\nexport function trackSingleEnvironment(props: SingleEnvironmentProps) {\n track(\"[Experiment] single_environment\", props);\n}\n\nexport function getExperimentTrackingBreakingChangeEnabled() {\n return false;\n}\n\ninterface ColumnLevelLineageProps {\n action: \"view\";\n source: \"schema_column\" | \"changed_column\" | \"cll_column\";\n}\n\nexport function trackColumnLevelLineage(props: ColumnLevelLineageProps) {\n track(\"[Web] column_level_lineage\", props);\n}\n\ninterface ShareStateProps {\n name: \"enable\" | \"create\" | \"copy\";\n}\n\nexport function trackShareState(props: ShareStateProps) {\n track(\"[Web] share_state\", props);\n}\n\ninterface StateActionProps {\n name: \"import\" | \"export\";\n}\n\nexport function trackStateAction(props: StateActionProps) {\n track(\"[Web] state_action\", props);\n}\n\ninterface CopyToClipboardProps {\n from: \"run\" | \"check\" | \"lineage_view\";\n type: string;\n}\n\nexport function trackCopyToClipboard(props: CopyToClipboardProps) {\n track(\"[Click] copy_to_clipboard\", props);\n}\n\ninterface TrackNavProps {\n from: string;\n to: string;\n}\n\nexport function trackNavigation(props: TrackNavProps) {\n track(\"[Web] navigation_change\", props);\n}\n\nexport interface LineageViewRenderProps {\n node_count: number;\n view_mode: string;\n impact_radius_enabled: boolean;\n cll_column_active?: boolean;\n right_sidebar_open: boolean;\n [status: string]: number | string | boolean | undefined;\n}\n\nexport function trackLineageViewRender(props: LineageViewRenderProps) {\n track(\"[Web] lineage_view_render\", props);\n}\n\nexport interface EnvironmentConfigProps {\n review_mode: boolean;\n adapter_type: string | null;\n has_git_info: boolean;\n has_pr_info: boolean;\n // Adapter-specific (shape varies by adapter_type)\n base?: {\n schema_count?: number;\n dbt_version?: string | null;\n timestamp?: string | null;\n has_env?: boolean;\n };\n current?: {\n schema_count?: number;\n dbt_version?: string | null;\n timestamp?: string | null;\n has_env?: boolean;\n };\n schemas_match?: boolean;\n}\n\nexport function trackEnvironmentConfig(props: EnvironmentConfigProps) {\n track(\"[Web] environment_config\", props);\n}\n\n// Explore action types\nexport const EXPLORE_ACTION = {\n ROW_COUNT: \"row_count\",\n ROW_COUNT_DIFF: \"row_count_diff\",\n PROFILE: \"profile\",\n PROFILE_DIFF: \"profile_diff\",\n VALUE_DIFF: \"value_diff\",\n SCHEMA_DIFF: \"schema_diff\",\n LINEAGE_DIFF: \"lineage_diff\",\n QUERY: \"query\",\n HISTOGRAM_DIFF: \"histogram_diff\",\n TOP_K_DIFF: \"top_k_diff\",\n} as const;\n\n// Explore action sources\nexport const EXPLORE_SOURCE = {\n LINEAGE_VIEW_TOP_BAR: \"lineage_view_top_bar\",\n LINEAGE_VIEW_CONTEXT_MENU: \"lineage_view_context_menu\",\n NODE_KEBAB_MENU: \"node_kebab_menu\",\n NODE_SIDEBAR_SINGLE_ENV: \"node_sidebar_single_env\",\n NODE_SIDEBAR_MULTI_ENV: \"node_sidebar_multi_env\",\n SCHEMA_ROW_COUNT_BUTTON: \"schema_row_count_button\",\n SCHEMA_COLUMN_MENU: \"schema_column_menu\",\n} as const;\n\nexport type ExploreActionType =\n (typeof EXPLORE_ACTION)[keyof typeof EXPLORE_ACTION];\nexport type ExploreSourceType =\n (typeof EXPLORE_SOURCE)[keyof typeof EXPLORE_SOURCE];\n\ninterface ExploreActionProps {\n action: ExploreActionType;\n source: ExploreSourceType;\n node_count?: number;\n}\n\nexport function trackExploreAction(props: ExploreActionProps) {\n track(\"[Web] explore_action\", props);\n}\n\n// Explore action form events\nexport const EXPLORE_FORM_EVENT = {\n EXECUTE: \"execute\",\n CANCEL: \"cancel\",\n} as const;\n\nexport type ExploreFormEventType =\n (typeof EXPLORE_FORM_EVENT)[keyof typeof EXPLORE_FORM_EVENT];\n\ninterface ExploreActionFormProps {\n action: ExploreActionType;\n event: ExploreFormEventType;\n}\n\nexport function trackExploreActionForm(props: ExploreActionFormProps) {\n track(\"[Web] explore_action_form\", props);\n}\n\n// Helper to check if a run type is an explore action\nexport function isExploreAction(type: string): type is ExploreActionType {\n return Object.values(EXPLORE_ACTION).includes(type as ExploreActionType);\n}\n\n// Lineage selection action types\nexport const LINEAGE_SELECTION_ACTION = {\n SELECT_PARENT_NODES: \"select_parent_nodes\",\n SELECT_CHILD_NODES: \"select_child_nodes\",\n SELECT_ALL_UPSTREAM: \"select_all_upstream\",\n SELECT_ALL_DOWNSTREAM: \"select_all_downstream\",\n} as const;\n\nexport type LineageSelectionActionType =\n (typeof LINEAGE_SELECTION_ACTION)[keyof typeof LINEAGE_SELECTION_ACTION];\n\ninterface LineageSelectionProps {\n action: LineageSelectionActionType;\n node_count?: number;\n}\n\nexport function trackLineageSelection(props: LineageSelectionProps) {\n track(\"[Web] lineage_selection\", props);\n}\n","import {\n Box,\n Button,\n CloseButton,\n Dialog,\n Flex,\n Portal,\n useDisclosure,\n} from \"@chakra-ui/react\";\nimport React, { useCallback, useRef, useState } from \"react\";\nimport {\n EXPLORE_ACTION,\n EXPLORE_FORM_EVENT,\n trackExploreActionForm,\n} from \"@/lib/api/track\";\n\nfunction useValueDiffAlertDialog() {\n const { open, onOpen, onClose } = useDisclosure();\n const [nodeCount, setNodeCount] = useState(0);\n const [resolvePromise, setResolvePromise] =\n useState<(value: boolean) => void>();\n const cancelRef = useRef<HTMLButtonElement>(null);\n\n const confirm = useCallback(\n (nodeCount: number) => {\n setNodeCount(nodeCount);\n return new Promise<boolean>((resolve) => {\n setResolvePromise(() => resolve);\n onOpen();\n });\n },\n [onOpen],\n );\n\n const handleConfirm = () => {\n trackExploreActionForm({\n action: EXPLORE_ACTION.VALUE_DIFF,\n event: EXPLORE_FORM_EVENT.EXECUTE,\n });\n resolvePromise?.(true);\n onClose();\n };\n\n const handleCancel = () => {\n trackExploreActionForm({\n action: EXPLORE_ACTION.VALUE_DIFF,\n event: EXPLORE_FORM_EVENT.CANCEL,\n });\n resolvePromise?.(false);\n onClose();\n };\n\n const ValueDiffAlertDialog = (\n <Dialog.Root\n size={\"xl\"}\n open={open}\n role=\"alertdialog\"\n initialFocusEl={() => {\n return cancelRef.current;\n }}\n onOpenChange={handleCancel}\n >\n <Portal>\n <Dialog.Backdrop />\n <Dialog.Positioner>\n <Dialog.Content>\n <Dialog.Header fontSize=\"lg\" fontWeight=\"bold\">\n <Dialog.Title>Value Diff on {nodeCount} nodes</Dialog.Title>\n </Dialog.Header>\n\n <Dialog.Body gap=\"20px\" as={Flex} direction=\"column\">\n <Box>\n Value diff will be executed on {nodeCount} nodes in the Lineage,\n which can add extra costs to your bill.\n </Box>\n </Dialog.Body>\n\n <Dialog.Footer gap={1}>\n <Button\n ref={cancelRef}\n onClick={handleCancel}\n variant=\"outline\"\n colorPalette=\"gray\"\n >\n Cancel\n </Button>\n <Button colorPalette=\"iochmara\" onClick={handleConfirm} ml={3}>\n Execute\n </Button>\n </Dialog.Footer>\n <Dialog.CloseTrigger asChild>\n <CloseButton size=\"sm\" />\n </Dialog.CloseTrigger>\n </Dialog.Content>\n </Dialog.Positioner>\n </Portal>\n </Dialog.Root>\n );\n\n return { confirm, AlertDialog: ValueDiffAlertDialog };\n}\n\nexport default useValueDiffAlertDialog;\n"]}
|
|
1
|
+
{"version":3,"sources":["../recce-source/js/src/lib/api/cacheKeys.ts","../recce-source/js/src/lib/const.ts","../recce-source/js/src/lib/api/axiosClient.ts","../recce-source/js/src/lib/api/instanceInfo.ts","../recce-source/js/src/lib/hooks/useRecceInstanceInfo.tsx","../recce-source/js/src/components/ui/toaster.tsx","../recce-source/js/src/lib/hooks/useCheckToast.tsx","../recce-source/js/src/lib/hooks/useClipBoardToast.tsx","../recce-source/js/src/components/lineage/LineageViewContext.tsx","../recce-source/js/src/lib/api/track.ts","../recce-source/js/src/components/lineage/useValueDiffAlertDialog.tsx"],"names":["axios","QueryClient","useQuery","createContext","useContext","trk","useState","useRef","useCallback","nodeCount","jsxs","MuiDialog","DialogTitle","jsx","IconButton","IoClose","DialogContent","Stack","Box","DialogActions","Button"],"mappings":"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","file":"hooks.js","sourcesContent":["export const cacheKeys = {\n rowCount: (model: string) => [\"row_count\", model],\n lineage: () => [\"lineage\"],\n checks: () => [\"checks\", \"list\"],\n check: (checkId: string) => [\"checks\", checkId],\n checkEvents: (checkId: string) => [\"checks\", checkId, \"events\"],\n runs: () => [\"runs\"],\n run: (runId: string) => [\"runs\", runId],\n runsAggregated: () => [\"runs_aggregated\"],\n flag: () => [\"flag\"],\n instanceInfo: () => [\"instance_info\"],\n user: () => [\"user\"],\n};\n","let apiUrl = process.env.NEXT_PUBLIC_API_URL;\napiUrl ??= typeof window !== \"undefined\" ? window.location.origin : \"\";\n\nexport const PUBLIC_API_URL = apiUrl;\n\nlet cloudWebUrl = process.env.NEXT_PUBLIC_CLOUD_WEB_URL;\ncloudWebUrl ??= \"https://cloud.datarecce.io\";\n\nexport const PUBLIC_CLOUD_WEB_URL = cloudWebUrl;\n","import { QueryClient } from \"@tanstack/react-query\";\nimport axios from \"axios\";\nimport { PUBLIC_API_URL } from \"@/lib/const\";\n\nexport const axiosClient = axios.create({\n baseURL: PUBLIC_API_URL,\n});\n\nexport const reactQueryClient = new QueryClient();\n","import { AxiosResponse } from \"axios\";\nimport { axiosClient } from \"./axiosClient\";\n\nexport interface RecceInstanceInfo {\n server_mode: \"server\" | \"preview\" | \"read-only\";\n single_env: boolean;\n authed: boolean;\n cloud_instance: boolean;\n lifetime_expired_at?: Date;\n idle_timeout?: number;\n share_url?: string;\n session_id?: string;\n organization_name?: string;\n web_url?: string;\n}\n\nexport async function getRecceInstanceInfo(): Promise<RecceInstanceInfo> {\n return (\n await axiosClient.get<never, AxiosResponse<RecceInstanceInfo>>(\n \"/api/instance-info\",\n )\n ).data;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { cacheKeys } from \"../api/cacheKeys\";\nimport { getRecceInstanceInfo, RecceInstanceInfo } from \"../api/instanceInfo\";\n\nexport const useRecceInstanceInfo = () => {\n return useQuery<RecceInstanceInfo>({\n queryKey: cacheKeys.instanceInfo(),\n queryFn: getRecceInstanceInfo,\n });\n};\n","\"use client\";\n\nimport Alert from \"@mui/material/Alert\";\nimport CircularProgress from \"@mui/material/CircularProgress\";\nimport Snackbar from \"@mui/material/Snackbar\";\nimport Stack from \"@mui/material/Stack\";\nimport Typography from \"@mui/material/Typography\";\nimport {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useState,\n} from \"react\";\n\n/**\n * Toast types and interfaces\n */\nexport interface ToastOptions {\n id?: string;\n title?: string;\n description?: ReactNode;\n type?: \"success\" | \"error\" | \"warning\" | \"info\" | \"loading\";\n duration?: number;\n closable?: boolean;\n action?: {\n label: string;\n onClick: () => void;\n };\n}\n\ninterface ToastState extends ToastOptions {\n id: string;\n open: boolean;\n}\n\ninterface ToasterContextValue {\n toast: (options: ToastOptions) => string;\n success: (options: Omit<ToastOptions, \"type\">) => string;\n error: (options: Omit<ToastOptions, \"type\">) => string;\n warning: (options: Omit<ToastOptions, \"type\">) => string;\n info: (options: Omit<ToastOptions, \"type\">) => string;\n loading: (options: Omit<ToastOptions, \"type\">) => string;\n dismiss: (id: string) => void;\n update: (id: string, options: Partial<ToastOptions>) => void;\n}\n\nconst ToasterContext = createContext<ToasterContextValue | null>(null);\n\nlet toastIdCounter = 0;\n\n/**\n * Simple toaster implementation using MUI Snackbar\n */\nexport function ToasterProvider({ children }: { children: ReactNode }) {\n const [toasts, setToasts] = useState<ToastState[]>([]);\n\n const createToast = useCallback((options: ToastOptions): string => {\n const id = options.id || `toast-${++toastIdCounter}`;\n const newToast: ToastState = {\n id,\n open: true,\n duration: options.type === \"loading\" ? null : (options.duration ?? 5000),\n closable: options.closable ?? true,\n ...options,\n } as ToastState;\n\n setToasts((prev) => {\n // Remove existing toast with same id\n const filtered = prev.filter((t) => t.id !== id);\n return [...filtered, newToast];\n });\n\n return id;\n }, []);\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, open: false } : t)),\n );\n // Remove after animation\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, 300);\n }, []);\n\n const update = useCallback((id: string, options: Partial<ToastOptions>) => {\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, ...options } : t)),\n );\n }, []);\n\n const contextValue: ToasterContextValue = {\n toast: createToast,\n success: (opts) => createToast({ ...opts, type: \"success\" }),\n error: (opts) => createToast({ ...opts, type: \"error\" }),\n warning: (opts) => createToast({ ...opts, type: \"warning\" }),\n info: (opts) => createToast({ ...opts, type: \"info\" }),\n loading: (opts) => createToast({ ...opts, type: \"loading\" }),\n dismiss,\n update,\n };\n\n return (\n <ToasterContext.Provider value={contextValue}>\n {children}\n {toasts.map((toast) => (\n <Snackbar\n key={toast.id}\n open={toast.open}\n autoHideDuration={toast.duration}\n onClose={() => toast.closable && dismiss(toast.id)}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"right\" }}\n >\n <Alert\n severity={toast.type === \"loading\" ? \"info\" : toast.type || \"info\"}\n onClose={toast.closable ? () => dismiss(toast.id) : undefined}\n icon={\n toast.type === \"loading\" ? (\n <CircularProgress size={20} color=\"inherit\" />\n ) : undefined\n }\n sx={{ width: \"100%\", minWidth: 300 }}\n >\n <Stack spacing={0.5}>\n {toast.title && (\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n {toast.title}\n </Typography>\n )}\n {toast.description && (\n <Typography variant=\"body2\" component=\"div\">\n {toast.description}\n </Typography>\n )}\n </Stack>\n </Alert>\n </Snackbar>\n ))}\n </ToasterContext.Provider>\n );\n}\n\n/**\n * Hook to use the toaster\n */\nexport function useToaster(): ToasterContextValue {\n const context = useContext(ToasterContext);\n if (!context) {\n throw new Error(\"useToaster must be used within ToasterProvider\");\n }\n return context;\n}\n\n/**\n * Standalone toaster instance for use outside React context\n * Uses a simple event-based system\n */\ninterface ToastEvent {\n type: \"create\" | \"dismiss\" | \"update\";\n options?: ToastOptions;\n id?: string;\n}\n\nconst listeners: Set<(event: ToastEvent) => void> = new Set();\n\nexport const toaster = {\n create: (options: ToastOptions): string => {\n const id = options.id || `toast-${++toastIdCounter}`;\n listeners.forEach((listener) =>\n listener({ type: \"create\", options: { ...options, id } }),\n );\n return id;\n },\n success: (options: Omit<ToastOptions, \"type\">) =>\n toaster.create({ ...options, type: \"success\" }),\n error: (options: Omit<ToastOptions, \"type\">) =>\n toaster.create({ ...options, type: \"error\" }),\n warning: (options: Omit<ToastOptions, \"type\">) =>\n toaster.create({ ...options, type: \"warning\" }),\n info: (options: Omit<ToastOptions, \"type\">) =>\n toaster.create({ ...options, type: \"info\" }),\n loading: (options: Omit<ToastOptions, \"type\">) =>\n toaster.create({ ...options, type: \"loading\" }),\n dismiss: (id: string) => {\n listeners.forEach((listener) => listener({ type: \"dismiss\", id }));\n },\n // Alias for dismiss (for backward compatibility)\n remove: (id: string) => {\n listeners.forEach((listener) => listener({ type: \"dismiss\", id }));\n },\n update: (id: string, options: Partial<ToastOptions>) => {\n listeners.forEach((listener) => listener({ type: \"update\", id, options }));\n },\n subscribe: (listener: (event: ToastEvent) => void) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n};\n\n/**\n * Toaster component that renders toasts from the standalone toaster\n */\nexport function Toaster() {\n const [toasts, setToasts] = useState<ToastState[]>([]);\n\n // Subscribe to toast events\n useState(() => {\n const unsubscribe = toaster.subscribe((event) => {\n if (event.type === \"create\" && event.options) {\n const newToast: ToastState = {\n id: event.options.id || `toast-${++toastIdCounter}`,\n open: true,\n duration:\n event.options.type === \"loading\"\n ? undefined\n : (event.options.duration ?? 5000),\n closable: event.options.closable ?? true,\n ...event.options,\n } as ToastState;\n setToasts((prev) => {\n const filtered = prev.filter((t) => t.id !== newToast.id);\n return [...filtered, newToast];\n });\n } else if (event.type === \"dismiss\" && event.id) {\n const id = event.id;\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, open: false } : t)),\n );\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, 300);\n } else if (event.type === \"update\" && event.id && event.options) {\n setToasts((prev) =>\n prev.map((t) => (t.id === event.id ? { ...t, ...event.options } : t)),\n );\n }\n });\n return unsubscribe;\n });\n\n const handleClose = (id: string) => {\n setToasts((prev) =>\n prev.map((t) => (t.id === id ? { ...t, open: false } : t)),\n );\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, 300);\n };\n\n return (\n <>\n {toasts.map((toast) => (\n <Snackbar\n key={toast.id}\n open={toast.open}\n autoHideDuration={toast.duration}\n onClose={() => toast.closable && handleClose(toast.id)}\n anchorOrigin={{ vertical: \"bottom\", horizontal: \"right\" }}\n >\n <Alert\n severity={toast.type === \"loading\" ? \"info\" : toast.type || \"info\"}\n onClose={toast.closable ? () => handleClose(toast.id) : undefined}\n icon={\n toast.type === \"loading\" ? (\n <CircularProgress size={20} color=\"inherit\" />\n ) : undefined\n }\n sx={{ width: \"100%\", minWidth: 300 }}\n >\n <Stack spacing={0.5}>\n {toast.title && (\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n {toast.title}\n </Typography>\n )}\n {toast.description && (\n <Typography variant=\"body2\" component=\"div\">\n {toast.description}\n </Typography>\n )}\n </Stack>\n </Alert>\n </Snackbar>\n ))}\n </>\n );\n}\n","import { toaster } from \"@/components/ui/toaster\";\n\nexport function useCheckToast() {\n function markedAsApprovedToast() {\n toaster.create({\n title: \"Marked as approved\",\n type: \"success\",\n duration: 2000,\n });\n }\n return {\n markedAsApprovedToast,\n };\n}\n","import { toaster } from \"@/components/ui/toaster\";\n\nexport function useClipBoardToast() {\n function successToast(message: string) {\n toaster.create({\n description: message,\n type: \"info\",\n duration: 5000,\n closable: true,\n });\n }\n\n function failToast(title: string, error: unknown) {\n toaster.create({\n title: title,\n description: String(error),\n type: \"error\",\n duration: 5000,\n closable: true,\n });\n }\n\n return {\n successToast,\n failToast,\n };\n}\n","import React, { createContext, useContext } from \"react\";\nimport { CllInput, ColumnLineageData } from \"@/lib/api/cll\";\nimport { LineageDiffViewOptions } from \"@/lib/api/lineagecheck\";\nimport { Run } from \"@/lib/api/types\";\nimport { LineageGraphNode, LineageGraphNodes } from \"./lineage\";\n\ntype NewType = LineageDiffViewOptions;\ntype ActionMode = \"per_node\" | \"multi_nodes\";\n\ninterface NodeAction {\n mode: ActionMode;\n status?: \"pending\" | \"running\" | \"success\" | \"failure\" | \"skipped\";\n skipReason?: string;\n run?: Run;\n}\n\nexport interface ActionState {\n mode: ActionMode;\n status: \"pending\" | \"running\" | \"canceling\" | \"canceled\" | \"completed\";\n currentRun?: Partial<Run>;\n completed: number;\n total: number;\n actions: Record<string, NodeAction>;\n}\n\nexport interface LineageViewContextType {\n interactive: boolean;\n nodes: LineageGraphNodes[];\n focusedNode?: LineageGraphNode;\n selectedNodes: LineageGraphNode[];\n cll: ColumnLineageData | undefined;\n\n // context menu\n showContextMenu: (event: React.MouseEvent, node: LineageGraphNodes) => void;\n\n // filter\n viewOptions: LineageDiffViewOptions;\n onViewOptionsChanged: (options: NewType) => void;\n\n // Multi nodes selection\n selectMode: \"selecting\" | \"action_result\" | undefined;\n selectNode: (nodeId: string) => void;\n selectParentNodes: (nodeId: string, degree?: number) => void;\n selectChildNodes: (nodeId: string, degree?: number) => void;\n deselect: () => void;\n\n // node state\n isNodeHighlighted: (nodeId: string) => boolean;\n isNodeSelected: (nodeId: string) => boolean;\n isEdgeHighlighted: (source: string, target: string) => boolean;\n getNodeAction: (nodeId: string) => NodeAction;\n getNodeColumnSet: (nodeId: string) => Set<string>;\n isNodeShowingChangeAnalysis: (nodeId: string) => boolean;\n\n //actions\n runRowCount: () => Promise<void>;\n runRowCountDiff: () => Promise<void>;\n runValueDiff: () => Promise<void>;\n addLineageDiffCheck: (viewMode?: string) => void;\n addSchemaDiffCheck: () => void;\n cancel: () => void;\n actionState: ActionState;\n\n // Column Level Lineage\n centerNode: (nodeId: string) => void;\n showColumnLevelLineage: (cll?: CllInput) => Promise<void>;\n resetColumnLevelLineage: (previous?: boolean) => Promise<void>;\n}\n\nexport const LineageViewContext = createContext<\n LineageViewContextType | undefined\n>(undefined);\n\nexport const useLineageViewContextSafe = (): LineageViewContextType => {\n const context = useContext(LineageViewContext);\n if (!context) {\n throw new Error(\n \"useLineageViewContext must be used within a LineageViewProvider\",\n );\n }\n return context;\n};\n\nexport const useLineageViewContext = (): LineageViewContextType | undefined => {\n return useContext(LineageViewContext);\n};\n","import {\n AmplitudeReturn,\n BaseEvent,\n EventOptions,\n Result,\n} from \"@amplitude/analytics-core\";\nimport { initAll, track as trk } from \"@amplitude/unified\";\n\nfunction track(\n eventInput: string | BaseEvent,\n // biome-ignore lint/suspicious/noExplicitAny: Amplitude library uses any for event properties\n eventProperties?: Record<string, any> | undefined,\n eventOptions?: EventOptions | undefined,\n): AmplitudeReturn<Result> {\n // If Amplitude isn't initialized, log to console instead\n if (!amplitudeInitialized) {\n console.log(\"[Tracking]\", eventInput, eventProperties, eventOptions);\n }\n return trk(eventInput, eventProperties, eventOptions);\n}\n\nlet amplitudeInitialized = false;\n\nexport function trackInit() {\n function getCookie(key: string) {\n const b = document.cookie.match(\"(^|;)\\\\s*\" + key + \"\\\\s*=\\\\s*([^;]+)\");\n return b ? b.pop() : \"\";\n }\n\n const userId =\n process.env.NODE_ENV === \"development\"\n ? \"web_dev\"\n : getCookie(\"recce_user_id\");\n const apiKey = process.env.AMPLITUDE_API_KEY;\n if (userId && apiKey) {\n try {\n void initAll(apiKey, {\n analytics: {\n userId,\n autocapture: true,\n },\n sessionReplay: {\n sampleRate: 1,\n },\n });\n amplitudeInitialized = true;\n } catch (e) {\n console.error(e);\n }\n }\n\n // Log when Amplitude is not initialized (for development/debugging)\n if (!amplitudeInitialized) {\n console.log(\n \"[Tracking] Amplitude not initialized (missing API key or user ID). Events will be logged to console instead.\",\n );\n }\n}\n\ninterface MultiNodeActionProps {\n type:\n | \"row_count\"\n | \"row_count_diff\"\n | \"value_diff\"\n | \"schema_diff\"\n | \"lineage_diff\";\n selected: \"single\" | \"multi\" | \"none\";\n}\n\nexport function trackMultiNodesAction(props: MultiNodeActionProps) {\n track(\"[Web] multi_nodes_action\", props);\n}\n\ninterface HistoryActionProps {\n name: \"show\" | \"hide\" | \"click_run\" | \"add_to_checklist\" | \"go_to_check\";\n}\n\nexport function trackHistoryAction(props: HistoryActionProps) {\n track(\"[Web] history_action\", props);\n}\n\ninterface PreviewChangeProps {\n action: \"explore\" | \"run\" | \"close\";\n node?: string;\n status?: \"success\" | \"failure\";\n}\n\nexport function trackPreviewChange(props: PreviewChangeProps) {\n track(\"[Experiment] preview_change\", props);\n}\n\ninterface PreviewChangeFeedbackProps {\n feedback: \"like\" | \"dislike\" | \"form\";\n node?: string;\n}\n\nexport function trackPreviewChangeFeedback(props: PreviewChangeFeedbackProps) {\n track(\"[Experiment] preview_change\", props);\n}\n\ninterface SingleEnvironmentProps {\n action:\n | \"onboarding\"\n | \"external_link\"\n | \"preview_changes\"\n | `target_base_added`;\n from?: \"onboarding\" | \"preview_changes\";\n node?: string;\n}\n\nexport function trackSingleEnvironment(props: SingleEnvironmentProps) {\n track(\"[Experiment] single_environment\", props);\n}\n\nexport function getExperimentTrackingBreakingChangeEnabled() {\n return false;\n}\n\ninterface ColumnLevelLineageProps {\n action: \"view\";\n source: \"schema_column\" | \"changed_column\" | \"cll_column\";\n}\n\nexport function trackColumnLevelLineage(props: ColumnLevelLineageProps) {\n track(\"[Web] column_level_lineage\", props);\n}\n\ninterface ShareStateProps {\n name: \"enable\" | \"create\" | \"copy\";\n}\n\nexport function trackShareState(props: ShareStateProps) {\n track(\"[Web] share_state\", props);\n}\n\ninterface StateActionProps {\n name: \"import\" | \"export\";\n}\n\nexport function trackStateAction(props: StateActionProps) {\n track(\"[Web] state_action\", props);\n}\n\ninterface CopyToClipboardProps {\n from: \"run\" | \"check\" | \"lineage_view\";\n type: string;\n}\n\nexport function trackCopyToClipboard(props: CopyToClipboardProps) {\n track(\"[Click] copy_to_clipboard\", props);\n}\n\ninterface TrackNavProps {\n from: string;\n to: string;\n}\n\nexport function trackNavigation(props: TrackNavProps) {\n track(\"[Web] navigation_change\", props);\n}\n\nexport interface LineageViewRenderProps {\n node_count: number;\n view_mode: string;\n impact_radius_enabled: boolean;\n cll_column_active?: boolean;\n right_sidebar_open: boolean;\n [status: string]: number | string | boolean | undefined;\n}\n\nexport function trackLineageViewRender(props: LineageViewRenderProps) {\n track(\"[Web] lineage_view_render\", props);\n}\n\nexport interface EnvironmentConfigProps {\n review_mode: boolean;\n adapter_type: string | null;\n has_git_info: boolean;\n has_pr_info: boolean;\n // Adapter-specific (shape varies by adapter_type)\n base?: {\n schema_count?: number;\n dbt_version?: string | null;\n timestamp?: string | null;\n has_env?: boolean;\n };\n current?: {\n schema_count?: number;\n dbt_version?: string | null;\n timestamp?: string | null;\n has_env?: boolean;\n };\n schemas_match?: boolean;\n}\n\nexport function trackEnvironmentConfig(props: EnvironmentConfigProps) {\n track(\"[Web] environment_config\", props);\n}\n\n// Explore action types\nexport const EXPLORE_ACTION = {\n ROW_COUNT: \"row_count\",\n ROW_COUNT_DIFF: \"row_count_diff\",\n PROFILE: \"profile\",\n PROFILE_DIFF: \"profile_diff\",\n VALUE_DIFF: \"value_diff\",\n SCHEMA_DIFF: \"schema_diff\",\n LINEAGE_DIFF: \"lineage_diff\",\n QUERY: \"query\",\n HISTOGRAM_DIFF: \"histogram_diff\",\n TOP_K_DIFF: \"top_k_diff\",\n} as const;\n\n// Explore action sources\nexport const EXPLORE_SOURCE = {\n LINEAGE_VIEW_TOP_BAR: \"lineage_view_top_bar\",\n LINEAGE_VIEW_CONTEXT_MENU: \"lineage_view_context_menu\",\n NODE_KEBAB_MENU: \"node_kebab_menu\",\n NODE_SIDEBAR_SINGLE_ENV: \"node_sidebar_single_env\",\n NODE_SIDEBAR_MULTI_ENV: \"node_sidebar_multi_env\",\n SCHEMA_ROW_COUNT_BUTTON: \"schema_row_count_button\",\n SCHEMA_COLUMN_MENU: \"schema_column_menu\",\n} as const;\n\nexport type ExploreActionType =\n (typeof EXPLORE_ACTION)[keyof typeof EXPLORE_ACTION];\nexport type ExploreSourceType =\n (typeof EXPLORE_SOURCE)[keyof typeof EXPLORE_SOURCE];\n\ninterface ExploreActionProps {\n action: ExploreActionType;\n source: ExploreSourceType;\n node_count?: number;\n}\n\nexport function trackExploreAction(props: ExploreActionProps) {\n track(\"[Web] explore_action\", props);\n}\n\n// Explore action form events\nexport const EXPLORE_FORM_EVENT = {\n EXECUTE: \"execute\",\n CANCEL: \"cancel\",\n} as const;\n\nexport type ExploreFormEventType =\n (typeof EXPLORE_FORM_EVENT)[keyof typeof EXPLORE_FORM_EVENT];\n\ninterface ExploreActionFormProps {\n action: ExploreActionType;\n event: ExploreFormEventType;\n}\n\nexport function trackExploreActionForm(props: ExploreActionFormProps) {\n track(\"[Web] explore_action_form\", props);\n}\n\n// Helper to check if a run type is an explore action\nexport function isExploreAction(type: string): type is ExploreActionType {\n return Object.values(EXPLORE_ACTION).includes(type as ExploreActionType);\n}\n\n// Lineage selection action types\nexport const LINEAGE_SELECTION_ACTION = {\n SELECT_PARENT_NODES: \"select_parent_nodes\",\n SELECT_CHILD_NODES: \"select_child_nodes\",\n SELECT_ALL_UPSTREAM: \"select_all_upstream\",\n SELECT_ALL_DOWNSTREAM: \"select_all_downstream\",\n} as const;\n\nexport type LineageSelectionActionType =\n (typeof LINEAGE_SELECTION_ACTION)[keyof typeof LINEAGE_SELECTION_ACTION];\n\ninterface LineageSelectionProps {\n action: LineageSelectionActionType;\n node_count?: number;\n}\n\nexport function trackLineageSelection(props: LineageSelectionProps) {\n track(\"[Web] lineage_selection\", props);\n}\n","import Box from \"@mui/material/Box\";\nimport Button from \"@mui/material/Button\";\nimport MuiDialog from \"@mui/material/Dialog\";\nimport DialogActions from \"@mui/material/DialogActions\";\nimport DialogContent from \"@mui/material/DialogContent\";\nimport DialogTitle from \"@mui/material/DialogTitle\";\nimport IconButton from \"@mui/material/IconButton\";\nimport Stack from \"@mui/material/Stack\";\nimport React, { useCallback, useRef, useState } from \"react\";\nimport { IoClose } from \"react-icons/io5\";\nimport {\n EXPLORE_ACTION,\n EXPLORE_FORM_EVENT,\n trackExploreActionForm,\n} from \"@/lib/api/track\";\n\nfunction useValueDiffAlertDialog() {\n const [open, setOpen] = useState(false);\n const [nodeCount, setNodeCount] = useState(0);\n const [resolvePromise, setResolvePromise] =\n useState<(value: boolean) => void>();\n const cancelRef = useRef<HTMLButtonElement>(null);\n\n const confirm = useCallback((nodeCount: number) => {\n setNodeCount(nodeCount);\n return new Promise<boolean>((resolve) => {\n setResolvePromise(() => resolve);\n setOpen(true);\n });\n }, []);\n\n const handleConfirm = () => {\n trackExploreActionForm({\n action: EXPLORE_ACTION.VALUE_DIFF,\n event: EXPLORE_FORM_EVENT.EXECUTE,\n });\n resolvePromise?.(true);\n setOpen(false);\n };\n\n const handleCancel = () => {\n trackExploreActionForm({\n action: EXPLORE_ACTION.VALUE_DIFF,\n event: EXPLORE_FORM_EVENT.CANCEL,\n });\n resolvePromise?.(false);\n setOpen(false);\n };\n\n const ValueDiffAlertDialog = (\n <MuiDialog\n open={open}\n onClose={handleCancel}\n maxWidth=\"md\"\n fullWidth\n aria-labelledby=\"value-diff-alert-dialog-title\"\n >\n <DialogTitle\n id=\"value-diff-alert-dialog-title\"\n sx={{ fontSize: \"1.125rem\", fontWeight: \"bold\" }}\n >\n Value Diff on {nodeCount} nodes\n </DialogTitle>\n <IconButton\n aria-label=\"close\"\n onClick={handleCancel}\n sx={{\n position: \"absolute\",\n right: 8,\n top: 8,\n color: \"grey.500\",\n }}\n >\n <IoClose />\n </IconButton>\n <DialogContent>\n <Stack spacing=\"20px\">\n <Box>\n Value diff will be executed on {nodeCount} nodes in the Lineage,\n which can add extra costs to your bill.\n </Box>\n </Stack>\n </DialogContent>\n <DialogActions sx={{ gap: 0.5 }}>\n <Button\n ref={cancelRef}\n onClick={handleCancel}\n variant=\"outlined\"\n color=\"neutral\"\n >\n Cancel\n </Button>\n <Button\n color=\"iochmara\"\n variant=\"contained\"\n onClick={handleConfirm}\n sx={{ ml: 1.5 }}\n >\n Execute\n </Button>\n </DialogActions>\n </MuiDialog>\n );\n\n return { confirm, AlertDialog: ValueDiffAlertDialog };\n}\n\nexport default useValueDiffAlertDialog;\n"]}
|
package/dist/hooks.mjs
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import { QueryClient, useQuery } from '@tanstack/react-query';
|
|
2
2
|
import axios from 'axios';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import '@mui/material/Alert';
|
|
4
|
+
import '@mui/material/CircularProgress';
|
|
5
|
+
import '@mui/material/Snackbar';
|
|
6
|
+
import Stack2 from '@mui/material/Stack';
|
|
7
|
+
import '@mui/material/Typography';
|
|
5
8
|
import { createContext, useContext, useState, useRef, useCallback } from 'react';
|
|
9
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
10
|
+
import Box from '@mui/material/Box';
|
|
11
|
+
import Button from '@mui/material/Button';
|
|
12
|
+
import MuiDialog from '@mui/material/Dialog';
|
|
13
|
+
import DialogActions from '@mui/material/DialogActions';
|
|
14
|
+
import DialogContent from '@mui/material/DialogContent';
|
|
15
|
+
import DialogTitle from '@mui/material/DialogTitle';
|
|
16
|
+
import IconButton from '@mui/material/IconButton';
|
|
17
|
+
import { IoClose } from 'react-icons/io5';
|
|
6
18
|
import { track as track$1 } from '@amplitude/unified';
|
|
7
19
|
|
|
8
20
|
// recce-source/js/src/lib/api/cacheKeys.ts
|
|
@@ -46,10 +58,37 @@ var useRecceInstanceInfo = () => {
|
|
|
46
58
|
queryFn: getRecceInstanceInfo
|
|
47
59
|
});
|
|
48
60
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
createContext(null);
|
|
62
|
+
var toastIdCounter = 0;
|
|
63
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
64
|
+
var toaster = {
|
|
65
|
+
create: (options) => {
|
|
66
|
+
const id = options.id || `toast-${++toastIdCounter}`;
|
|
67
|
+
listeners.forEach(
|
|
68
|
+
(listener) => listener({ type: "create", options: { ...options, id } })
|
|
69
|
+
);
|
|
70
|
+
return id;
|
|
71
|
+
},
|
|
72
|
+
success: (options) => toaster.create({ ...options, type: "success" }),
|
|
73
|
+
error: (options) => toaster.create({ ...options, type: "error" }),
|
|
74
|
+
warning: (options) => toaster.create({ ...options, type: "warning" }),
|
|
75
|
+
info: (options) => toaster.create({ ...options, type: "info" }),
|
|
76
|
+
loading: (options) => toaster.create({ ...options, type: "loading" }),
|
|
77
|
+
dismiss: (id) => {
|
|
78
|
+
listeners.forEach((listener) => listener({ type: "dismiss", id }));
|
|
79
|
+
},
|
|
80
|
+
// Alias for dismiss (for backward compatibility)
|
|
81
|
+
remove: (id) => {
|
|
82
|
+
listeners.forEach((listener) => listener({ type: "dismiss", id }));
|
|
83
|
+
},
|
|
84
|
+
update: (id, options) => {
|
|
85
|
+
listeners.forEach((listener) => listener({ type: "update", id, options }));
|
|
86
|
+
},
|
|
87
|
+
subscribe: (listener) => {
|
|
88
|
+
listeners.add(listener);
|
|
89
|
+
return () => listeners.delete(listener);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
53
92
|
|
|
54
93
|
// recce-source/js/src/lib/hooks/useCheckToast.tsx
|
|
55
94
|
function useCheckToast() {
|
|
@@ -109,27 +148,24 @@ function trackExploreActionForm(props) {
|
|
|
109
148
|
track("[Web] explore_action_form", props);
|
|
110
149
|
}
|
|
111
150
|
function useValueDiffAlertDialog() {
|
|
112
|
-
const
|
|
151
|
+
const [open, setOpen] = useState(false);
|
|
113
152
|
const [nodeCount, setNodeCount] = useState(0);
|
|
114
153
|
const [resolvePromise, setResolvePromise] = useState();
|
|
115
154
|
const cancelRef = useRef(null);
|
|
116
|
-
const confirm = useCallback(
|
|
117
|
-
(nodeCount2)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
},
|
|
124
|
-
[onOpen]
|
|
125
|
-
);
|
|
155
|
+
const confirm = useCallback((nodeCount2) => {
|
|
156
|
+
setNodeCount(nodeCount2);
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
setResolvePromise(() => resolve);
|
|
159
|
+
setOpen(true);
|
|
160
|
+
});
|
|
161
|
+
}, []);
|
|
126
162
|
const handleConfirm = () => {
|
|
127
163
|
trackExploreActionForm({
|
|
128
164
|
action: EXPLORE_ACTION.VALUE_DIFF,
|
|
129
165
|
event: EXPLORE_FORM_EVENT.EXECUTE
|
|
130
166
|
});
|
|
131
167
|
resolvePromise?.(true);
|
|
132
|
-
|
|
168
|
+
setOpen(false);
|
|
133
169
|
};
|
|
134
170
|
const handleCancel = () => {
|
|
135
171
|
trackExploreActionForm({
|
|
@@ -137,47 +173,71 @@ function useValueDiffAlertDialog() {
|
|
|
137
173
|
event: EXPLORE_FORM_EVENT.CANCEL
|
|
138
174
|
});
|
|
139
175
|
resolvePromise?.(false);
|
|
140
|
-
|
|
176
|
+
setOpen(false);
|
|
141
177
|
};
|
|
142
|
-
const ValueDiffAlertDialog = /* @__PURE__ */
|
|
143
|
-
|
|
178
|
+
const ValueDiffAlertDialog = /* @__PURE__ */ jsxs(
|
|
179
|
+
MuiDialog,
|
|
144
180
|
{
|
|
145
|
-
size: "xl",
|
|
146
181
|
open,
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
182
|
+
onClose: handleCancel,
|
|
183
|
+
maxWidth: "md",
|
|
184
|
+
fullWidth: true,
|
|
185
|
+
"aria-labelledby": "value-diff-alert-dialog-title",
|
|
186
|
+
children: [
|
|
187
|
+
/* @__PURE__ */ jsxs(
|
|
188
|
+
DialogTitle,
|
|
189
|
+
{
|
|
190
|
+
id: "value-diff-alert-dialog-title",
|
|
191
|
+
sx: { fontSize: "1.125rem", fontWeight: "bold" },
|
|
192
|
+
children: [
|
|
193
|
+
"Value Diff on ",
|
|
194
|
+
nodeCount,
|
|
195
|
+
" nodes"
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
),
|
|
199
|
+
/* @__PURE__ */ jsx(
|
|
200
|
+
IconButton,
|
|
201
|
+
{
|
|
202
|
+
"aria-label": "close",
|
|
203
|
+
onClick: handleCancel,
|
|
204
|
+
sx: {
|
|
205
|
+
position: "absolute",
|
|
206
|
+
right: 8,
|
|
207
|
+
top: 8,
|
|
208
|
+
color: "grey.500"
|
|
209
|
+
},
|
|
210
|
+
children: /* @__PURE__ */ jsx(IoClose, {})
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(Stack2, { spacing: "20px", children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
214
|
+
"Value diff will be executed on ",
|
|
215
|
+
nodeCount,
|
|
216
|
+
" nodes in the Lineage, which can add extra costs to your bill."
|
|
217
|
+
] }) }) }),
|
|
218
|
+
/* @__PURE__ */ jsxs(DialogActions, { sx: { gap: 0.5 }, children: [
|
|
219
|
+
/* @__PURE__ */ jsx(
|
|
220
|
+
Button,
|
|
221
|
+
{
|
|
222
|
+
ref: cancelRef,
|
|
223
|
+
onClick: handleCancel,
|
|
224
|
+
variant: "outlined",
|
|
225
|
+
color: "neutral",
|
|
226
|
+
children: "Cancel"
|
|
227
|
+
}
|
|
228
|
+
),
|
|
229
|
+
/* @__PURE__ */ jsx(
|
|
230
|
+
Button,
|
|
231
|
+
{
|
|
232
|
+
color: "iochmara",
|
|
233
|
+
variant: "contained",
|
|
234
|
+
onClick: handleConfirm,
|
|
235
|
+
sx: { ml: 1.5 },
|
|
236
|
+
children: "Execute"
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
] })
|
|
240
|
+
]
|
|
181
241
|
}
|
|
182
242
|
);
|
|
183
243
|
return { confirm, AlertDialog: ValueDiffAlertDialog };
|