@workflow/web 5.0.0-beta.5 → 5.0.0-beta.51
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 +1 -0
- package/build/client/assets/app-9JVnf-IU.css +1 -0
- package/build/client/assets/arrow-up-right-D35zSWdr.js +15 -0
- package/build/client/assets/{entry.client-DtOpLtMQ.js → entry.client-DmlDFlyx.js} +25 -185
- package/build/client/assets/{highlighted-body-B3W2YXNL-L1CrwoL_.js → highlighted-body-B3W2YXNL-CaN05-wF.js} +2 -2
- package/build/client/assets/{home-B6UmDDP6.js → home-CERPMYFB.js} +1762 -291
- package/build/client/assets/index-HqNj_XIX.js +200 -0
- package/build/client/assets/{index-BsV8i_Jn.js → index-thGVuYbY.js} +19 -19
- package/build/client/assets/loader-circle-BS067e3l.js +12 -0
- package/build/client/assets/manifest-e59a5df7.js +1 -0
- package/build/client/assets/mermaid-3ZIDBTTL-D8CjRQta.css +1 -0
- package/build/client/assets/{mermaid-3ZIDBTTL-BQLU7GUr.js → mermaid-3ZIDBTTL-DX-qOY9c.js} +17613 -12954
- package/build/client/assets/root-Bl5xphvU.css +1 -0
- package/build/client/assets/{root-Yk3JVwUh.js → root-D0H-cabN.js} +17 -42
- package/build/client/assets/{run-detail-DMUaWXhb.js → run-detail-C7nNgL_7.js} +2215 -1599
- package/build/client/assets/run-detail-CWoGxu_0.css +1 -0
- package/build/client/assets/{workflow-graph-viewer-yqeN-U_2.js → workflow-graph-viewer-nSzDqm6s.js} +5111 -5254
- package/build/client/assets/zstd-B5R2yJjB.wasm +0 -0
- package/build/client/assets/zstd-browser-decoder-DtSP7rJ_.js +27 -0
- package/build/server/assets/{server-build-DtcOUEHS.js → app-8hyjFpMO.js} +77875 -59603
- package/build/server/assets/{highlighted-body-B3W2YXNL-CZjJIpdD.js → highlighted-body-B3W2YXNL-DY_BqM6l.js} +16 -8
- package/build/server/assets/index-Az8HzIf_.js +174 -0
- package/build/server/assets/index-BfLBLRRi.js +204 -0
- package/build/server/assets/index-CETb4fkq.js +1164 -0
- package/build/server/assets/index-CvyMHP_b.js +1262 -0
- package/build/server/assets/{mermaid-3ZIDBTTL-Cc8IPTBj.js → mermaid-3ZIDBTTL-Bca_z0-z.js} +17 -9
- package/build/server/assets/{token-DHnArVm7.js → token-BcUtceXk.js} +5 -2
- package/build/server/assets/{token-util-B3uKeZ0s.js → token-util-BgQCuyAc.js} +5 -2
- package/build/server/assets/websocket-server-D2905vlr.js +3669 -0
- package/build/server/assets/wrapper-BxY6HvLW.js +69 -0
- package/build/server/assets/ws-transport-nlG6b7qI.js +551 -0
- package/build/server/assets/zstd-browser-decoder-Ce8lEOjC.js +72 -0
- package/build/server/index.js +50 -2
- package/handler.d.ts +22 -0
- package/handler.js +186 -0
- package/package.json +27 -13
- package/registry.d.ts +29 -0
- package/registry.js +89 -0
- package/build/client/assets/encryption-CEh0YXii.js +0 -28
- package/build/client/assets/index-B4xuge0I.js +0 -249
- package/build/client/assets/manifest-e4c1c787.js +0 -1
- package/build/client/assets/mermaid-3ZIDBTTL-DKxHcEOp.css +0 -1
- package/build/client/assets/root-C0Tu5TVN.css +0 -1
- package/build/client/assets/server-build-DqaxIrF0.css +0 -1
- package/build/client/assets/worker-CqHKTA7D.js +0 -115
- package/build/server/assets/app-L1V62FgT.js +0 -9213
- package/build/server/assets/index-BwtNigf1.js +0 -80
- package/build/server/assets/index-meg9qk8y.js +0 -1282
|
@@ -1,61 +1,43 @@
|
|
|
1
|
-
import { r as reactExports,
|
|
2
|
-
import { R as ResolveHookModal, S as Send,
|
|
3
|
-
import {
|
|
4
|
-
import "./
|
|
5
|
-
var PORTAL_NAME$2 = "Portal";
|
|
6
|
-
var Portal$2 = reactExports.forwardRef((props, forwardedRef) => {
|
|
7
|
-
var _a;
|
|
8
|
-
const { container: containerProp, ...portalProps } = props;
|
|
9
|
-
const [mounted, setMounted] = reactExports.useState(false);
|
|
10
|
-
useLayoutEffect2(() => setMounted(true), []);
|
|
11
|
-
const container = containerProp || mounted && ((_a = globalThis == null ? void 0 : globalThis.document) == null ? void 0 : _a.body);
|
|
12
|
-
return container ? ReactDOM.createPortal(/* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
|
|
13
|
-
});
|
|
14
|
-
Portal$2.displayName = PORTAL_NAME$2;
|
|
1
|
+
import { r as reactExports, j as jsxRuntimeExports, z as Link, R as ReactExports, f as reactDomExports, B as useSearchParams, A as useNavigate, C as useLocation, w as withComponentProps } from "./index-thGVuYbY.js";
|
|
2
|
+
import { R as ResolveHookModal, S as Send, r as requireShim, u as unwrapOrThrow, W as WorkflowWebAPIError, f as fetchHookToken, a as Skeleton, b as RelativeTime, A as Alert, C as CircleAlert, c as AlertTitle, g as getErrorTitle, d as AlertDescription, e as getErrorMessage, h as CopyableText, D as DropdownMenu, i as DropdownMenuTrigger, E as Ellipsis, j as DropdownMenuContent, k as DropdownMenuItem, l as resumeHook, m as createCollection, n as hideOthers, o as ReactRemoveScroll, p as useDirection, q as ChevronUp, X, s as useControllableState$1, P as Primitive$1, t as composeEventHandlers$1, v as Presence, w as useSize, x as createContextScope$1, y as bulkCancelRuns, z as reenqueueRun, B as parseWorkflowName, F as StatusBadge, Z as Zap, G as CircleX, H as RunActionsDropdownItems, I as unwrapServerActionResult, J as WorkflowGraphViewer, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, N as ErrorBoundary } from "./workflow-graph-viewer-nSzDqm6s.js";
|
|
3
|
+
import { c as createLucideIcon, h as useToast, e as cn, i as fetchRuns, j as fetchHooks, k as getPaginationDisplay, T as Tooltip, a as TooltipTrigger, C as Check, l as Copy, b as TooltipContent, D as DEFAULT_PAGE_SIZE, B as Button, m as ChevronRight, n as fetchEvents, o as useCallbackRef, p as useComposedRefs, P as Primitive, A as Anchor, q as composeEventHandlers, s as useLayoutEffect2, v as Portal$2, w as useId, x as createPopperScope, y as DismissableLayer, z as createContextScope, E as createSlot, F as Content$1, G as useControllableState, H as Root2$1, V as VISUALLY_HIDDEN_STYLES, I as Arrow, J as ChevronDown, L as useComposedRefs$1, u as useServerConfig, M as BULK_CANCEL_MAX_RUN_IDS, t as toast, N as fetchRun, O as cva, U as Presence$1, W as createContext2, X as fetchWorkflowsManifest } from "./mermaid-3ZIDBTTL-DX-qOY9c.js";
|
|
4
|
+
import { L as LoaderCircle } from "./loader-circle-BS067e3l.js";
|
|
15
5
|
/**
|
|
16
6
|
* @license lucide-react v0.575.0 - ISC
|
|
17
7
|
*
|
|
18
8
|
* This source code is licensed under the ISC license.
|
|
19
9
|
* See the LICENSE file in the root directory of this source tree.
|
|
20
10
|
*/
|
|
21
|
-
const __iconNode$
|
|
11
|
+
const __iconNode$6 = [
|
|
22
12
|
["path", { d: "m3 16 4 4 4-4", key: "1co6wj" }],
|
|
23
13
|
["path", { d: "M7 20V4", key: "1yoxec" }],
|
|
24
14
|
["path", { d: "M20 8h-5", key: "1vsyxs" }],
|
|
25
15
|
["path", { d: "M15 10V6.5a2.5 2.5 0 0 1 5 0V10", key: "ag13bf" }],
|
|
26
16
|
["path", { d: "M15 14h5l-5 6h5", key: "ur5jdg" }]
|
|
27
17
|
];
|
|
28
|
-
const ArrowDownAZ = createLucideIcon("arrow-down-a-z", __iconNode$
|
|
18
|
+
const ArrowDownAZ = createLucideIcon("arrow-down-a-z", __iconNode$6);
|
|
29
19
|
/**
|
|
30
20
|
* @license lucide-react v0.575.0 - ISC
|
|
31
21
|
*
|
|
32
22
|
* This source code is licensed under the ISC license.
|
|
33
23
|
* See the LICENSE file in the root directory of this source tree.
|
|
34
24
|
*/
|
|
35
|
-
const __iconNode$
|
|
25
|
+
const __iconNode$5 = [
|
|
36
26
|
["path", { d: "m3 8 4-4 4 4", key: "11wl7u" }],
|
|
37
27
|
["path", { d: "M7 4v16", key: "1glfcx" }],
|
|
38
28
|
["path", { d: "M20 8h-5", key: "1vsyxs" }],
|
|
39
29
|
["path", { d: "M15 10V6.5a2.5 2.5 0 0 1 5 0V10", key: "ag13bf" }],
|
|
40
30
|
["path", { d: "M15 14h5l-5 6h5", key: "ur5jdg" }]
|
|
41
31
|
];
|
|
42
|
-
const ArrowUpAZ = createLucideIcon("arrow-up-a-z", __iconNode$
|
|
32
|
+
const ArrowUpAZ = createLucideIcon("arrow-up-a-z", __iconNode$5);
|
|
43
33
|
/**
|
|
44
34
|
* @license lucide-react v0.575.0 - ISC
|
|
45
35
|
*
|
|
46
36
|
* This source code is licensed under the ISC license.
|
|
47
37
|
* See the LICENSE file in the root directory of this source tree.
|
|
48
38
|
*/
|
|
49
|
-
const __iconNode$
|
|
50
|
-
const ChevronLeft = createLucideIcon("chevron-left", __iconNode$
|
|
51
|
-
/**
|
|
52
|
-
* @license lucide-react v0.575.0 - ISC
|
|
53
|
-
*
|
|
54
|
-
* This source code is licensed under the ISC license.
|
|
55
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
-
*/
|
|
57
|
-
const __iconNode$4 = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]];
|
|
58
|
-
const ChevronUp = createLucideIcon("chevron-up", __iconNode$4);
|
|
39
|
+
const __iconNode$4 = [["path", { d: "m15 18-6-6 6-6", key: "1wnfg3" }]];
|
|
40
|
+
const ChevronLeft = createLucideIcon("chevron-left", __iconNode$4);
|
|
59
41
|
/**
|
|
60
42
|
* @license lucide-react v0.575.0 - ISC
|
|
61
43
|
*
|
|
@@ -101,6 +83,9 @@ const __iconNode = [
|
|
|
101
83
|
["rect", { width: "8", height: "8", x: "13", y: "13", rx: "2", key: "1cgmvn" }]
|
|
102
84
|
];
|
|
103
85
|
const Workflow = createLucideIcon("workflow", __iconNode);
|
|
86
|
+
function pluralize(singular, plural, count2) {
|
|
87
|
+
return count2 === 1 ? singular : plural;
|
|
88
|
+
}
|
|
104
89
|
function useHookActions({ onResolve, callbacks }) {
|
|
105
90
|
const toast2 = useToast();
|
|
106
91
|
const [isResolving, setIsResolving] = reactExports.useState(false);
|
|
@@ -303,101 +288,1309 @@ const TableCaption = reactExports.forwardRef(({ className, ...props }, ref) => /
|
|
|
303
288
|
}
|
|
304
289
|
));
|
|
305
290
|
TableCaption.displayName = "TableCaption";
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
291
|
+
var shimExports = requireShim();
|
|
292
|
+
const FOCUS_EVENT = 0;
|
|
293
|
+
const RECONNECT_EVENT = 1;
|
|
294
|
+
const MUTATE_EVENT = 2;
|
|
295
|
+
const ERROR_REVALIDATE_EVENT = 3;
|
|
296
|
+
var has = Object.prototype.hasOwnProperty;
|
|
297
|
+
function dequal(foo, bar) {
|
|
298
|
+
var ctor, len;
|
|
299
|
+
if (foo === bar) return true;
|
|
300
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
301
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
302
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
303
|
+
if (ctor === Array) {
|
|
304
|
+
if ((len = foo.length) === bar.length) {
|
|
305
|
+
while (len-- && dequal(foo[len], bar[len])) ;
|
|
306
|
+
}
|
|
307
|
+
return len === -1;
|
|
308
|
+
}
|
|
309
|
+
if (!ctor || typeof foo === "object") {
|
|
310
|
+
len = 0;
|
|
311
|
+
for (ctor in foo) {
|
|
312
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
313
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
314
|
+
}
|
|
315
|
+
return Object.keys(bar).length === len;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return foo !== foo && bar !== bar;
|
|
319
|
+
}
|
|
320
|
+
const SWRGlobalState = /* @__PURE__ */ new WeakMap();
|
|
321
|
+
const noop$1 = () => {
|
|
322
|
+
};
|
|
323
|
+
const UNDEFINED$1 = (
|
|
324
|
+
/*#__NOINLINE__*/
|
|
325
|
+
noop$1()
|
|
326
|
+
);
|
|
327
|
+
const OBJECT$1 = Object;
|
|
328
|
+
const isUndefined$1 = (v) => v === UNDEFINED$1;
|
|
329
|
+
const isFunction$1 = (v) => typeof v == "function";
|
|
330
|
+
const mergeObjects = (a, b) => ({
|
|
331
|
+
...a,
|
|
332
|
+
...b
|
|
333
|
+
});
|
|
334
|
+
const isPromiseLike = (x) => isFunction$1(x.then);
|
|
335
|
+
const EMPTY_CACHE = {};
|
|
336
|
+
const INITIAL_CACHE = {};
|
|
337
|
+
const STR_UNDEFINED = "undefined";
|
|
338
|
+
const isWindowDefined = typeof window != STR_UNDEFINED;
|
|
339
|
+
const isDocumentDefined = typeof document != STR_UNDEFINED;
|
|
340
|
+
const isLegacyDeno = isWindowDefined && "Deno" in window;
|
|
341
|
+
const hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED;
|
|
342
|
+
const createCacheHelper = (cache2, key) => {
|
|
343
|
+
const state = SWRGlobalState.get(cache2);
|
|
344
|
+
return [
|
|
345
|
+
// Getter
|
|
346
|
+
() => !isUndefined$1(key) && cache2.get(key) || EMPTY_CACHE,
|
|
347
|
+
// Setter
|
|
348
|
+
(info) => {
|
|
349
|
+
if (!isUndefined$1(key)) {
|
|
350
|
+
const prev = cache2.get(key);
|
|
351
|
+
if (!(key in INITIAL_CACHE)) {
|
|
352
|
+
INITIAL_CACHE[key] = prev;
|
|
353
|
+
}
|
|
354
|
+
state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
// Subscriber
|
|
358
|
+
state[6],
|
|
359
|
+
// Get server cache snapshot
|
|
360
|
+
() => {
|
|
361
|
+
if (!isUndefined$1(key)) {
|
|
362
|
+
if (key in INITIAL_CACHE) return INITIAL_CACHE[key];
|
|
363
|
+
}
|
|
364
|
+
return !isUndefined$1(key) && cache2.get(key) || EMPTY_CACHE;
|
|
362
365
|
}
|
|
366
|
+
];
|
|
367
|
+
};
|
|
368
|
+
let online = true;
|
|
369
|
+
const isOnline = () => online;
|
|
370
|
+
const [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
|
|
371
|
+
window.addEventListener.bind(window),
|
|
372
|
+
window.removeEventListener.bind(window)
|
|
373
|
+
] : [
|
|
374
|
+
noop$1,
|
|
375
|
+
noop$1
|
|
376
|
+
];
|
|
377
|
+
const isVisible = () => {
|
|
378
|
+
const visibilityState = isDocumentDefined && document.visibilityState;
|
|
379
|
+
return isUndefined$1(visibilityState) || visibilityState !== "hidden";
|
|
380
|
+
};
|
|
381
|
+
const initFocus = (callback) => {
|
|
382
|
+
if (isDocumentDefined) {
|
|
383
|
+
document.addEventListener("visibilitychange", callback);
|
|
384
|
+
}
|
|
385
|
+
onWindowEvent("focus", callback);
|
|
386
|
+
return () => {
|
|
387
|
+
if (isDocumentDefined) {
|
|
388
|
+
document.removeEventListener("visibilitychange", callback);
|
|
389
|
+
}
|
|
390
|
+
offWindowEvent("focus", callback);
|
|
363
391
|
};
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
+
};
|
|
393
|
+
const initReconnect = (callback) => {
|
|
394
|
+
const onOnline = () => {
|
|
395
|
+
online = true;
|
|
396
|
+
callback();
|
|
397
|
+
};
|
|
398
|
+
const onOffline = () => {
|
|
399
|
+
online = false;
|
|
400
|
+
};
|
|
401
|
+
onWindowEvent("online", onOnline);
|
|
402
|
+
onWindowEvent("offline", onOffline);
|
|
403
|
+
return () => {
|
|
404
|
+
offWindowEvent("online", onOnline);
|
|
405
|
+
offWindowEvent("offline", onOffline);
|
|
406
|
+
};
|
|
407
|
+
};
|
|
408
|
+
const preset = {
|
|
409
|
+
isOnline,
|
|
410
|
+
isVisible
|
|
411
|
+
};
|
|
412
|
+
const defaultConfigOptions = {
|
|
413
|
+
initFocus,
|
|
414
|
+
initReconnect
|
|
415
|
+
};
|
|
416
|
+
const IS_REACT_LEGACY = !ReactExports.useId;
|
|
417
|
+
const IS_SERVER = !isWindowDefined || isLegacyDeno;
|
|
418
|
+
const rAF = (f) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f) : setTimeout(f, 1);
|
|
419
|
+
const useIsomorphicLayoutEffect = IS_SERVER ? reactExports.useEffect : reactExports.useLayoutEffect;
|
|
420
|
+
const navigatorConnection = typeof navigator !== "undefined" && navigator.connection;
|
|
421
|
+
const slowConnection = !IS_SERVER && navigatorConnection && ([
|
|
422
|
+
"slow-2g",
|
|
423
|
+
"2g"
|
|
424
|
+
].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
|
|
425
|
+
const table$1 = /* @__PURE__ */ new WeakMap();
|
|
426
|
+
const getTypeName$1 = (value) => OBJECT$1.prototype.toString.call(value);
|
|
427
|
+
const isObjectTypeName$1 = (typeName, type) => typeName === `[object ${type}]`;
|
|
428
|
+
let counter$1 = 0;
|
|
429
|
+
const stableHash$1 = (arg) => {
|
|
430
|
+
const type = typeof arg;
|
|
431
|
+
const typeName = getTypeName$1(arg);
|
|
432
|
+
const isDate = isObjectTypeName$1(typeName, "Date");
|
|
433
|
+
const isRegex = isObjectTypeName$1(typeName, "RegExp");
|
|
434
|
+
const isPlainObject = isObjectTypeName$1(typeName, "Object");
|
|
435
|
+
let result;
|
|
436
|
+
let index;
|
|
437
|
+
if (OBJECT$1(arg) === arg && !isDate && !isRegex) {
|
|
438
|
+
result = table$1.get(arg);
|
|
439
|
+
if (result) return result;
|
|
440
|
+
result = ++counter$1 + "~";
|
|
441
|
+
table$1.set(arg, result);
|
|
442
|
+
if (Array.isArray(arg)) {
|
|
443
|
+
result = "@";
|
|
444
|
+
for (index = 0; index < arg.length; index++) {
|
|
445
|
+
result += stableHash$1(arg[index]) + ",";
|
|
446
|
+
}
|
|
447
|
+
table$1.set(arg, result);
|
|
448
|
+
}
|
|
449
|
+
if (isPlainObject) {
|
|
450
|
+
result = "#";
|
|
451
|
+
const keys = OBJECT$1.keys(arg).sort();
|
|
452
|
+
while (!isUndefined$1(index = keys.pop())) {
|
|
453
|
+
if (!isUndefined$1(arg[index])) {
|
|
454
|
+
result += index + ":" + stableHash$1(arg[index]) + ",";
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
table$1.set(arg, result);
|
|
392
458
|
}
|
|
459
|
+
} else {
|
|
460
|
+
result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
|
|
461
|
+
}
|
|
462
|
+
return result;
|
|
463
|
+
};
|
|
464
|
+
const serialize$1 = (key) => {
|
|
465
|
+
if (isFunction$1(key)) {
|
|
466
|
+
try {
|
|
467
|
+
key = key();
|
|
468
|
+
} catch (err) {
|
|
469
|
+
key = "";
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
const args = key;
|
|
473
|
+
key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash$1(key) : "";
|
|
474
|
+
return [
|
|
475
|
+
key,
|
|
476
|
+
args
|
|
477
|
+
];
|
|
478
|
+
};
|
|
479
|
+
let __timestamp = 0;
|
|
480
|
+
const getTimestamp = () => ++__timestamp;
|
|
481
|
+
async function internalMutate(...args) {
|
|
482
|
+
const [cache2, _key, _data, _opts] = args;
|
|
483
|
+
const options = mergeObjects({
|
|
484
|
+
populateCache: true,
|
|
485
|
+
throwOnError: true
|
|
486
|
+
}, typeof _opts === "boolean" ? {
|
|
487
|
+
revalidate: _opts
|
|
488
|
+
} : _opts || {});
|
|
489
|
+
let populateCache = options.populateCache;
|
|
490
|
+
const rollbackOnErrorOption = options.rollbackOnError;
|
|
491
|
+
let optimisticData = options.optimisticData;
|
|
492
|
+
const rollbackOnError = (error) => {
|
|
493
|
+
return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false;
|
|
393
494
|
};
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
495
|
+
const throwOnError = options.throwOnError;
|
|
496
|
+
if (isFunction$1(_key)) {
|
|
497
|
+
const keyFilter = _key;
|
|
498
|
+
const matchedKeys = [];
|
|
499
|
+
const it = cache2.keys();
|
|
500
|
+
for (const key of it) {
|
|
501
|
+
if (
|
|
502
|
+
// Skip the special useSWRInfinite and useSWRSubscription keys.
|
|
503
|
+
!/^\$(inf|sub)\$/.test(key) && keyFilter(cache2.get(key)._k)
|
|
504
|
+
) {
|
|
505
|
+
matchedKeys.push(key);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return Promise.all(matchedKeys.map(mutateByKey));
|
|
509
|
+
}
|
|
510
|
+
return mutateByKey(_key);
|
|
511
|
+
async function mutateByKey(_k) {
|
|
512
|
+
const [key] = serialize$1(_k);
|
|
513
|
+
if (!key) return;
|
|
514
|
+
const [get, set] = createCacheHelper(cache2, key);
|
|
515
|
+
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
|
|
516
|
+
const startRevalidate = () => {
|
|
517
|
+
const revalidators = EVENT_REVALIDATORS[key];
|
|
518
|
+
const revalidate = isFunction$1(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false;
|
|
519
|
+
if (revalidate) {
|
|
520
|
+
delete FETCH[key];
|
|
521
|
+
delete PRELOAD[key];
|
|
522
|
+
if (revalidators && revalidators[0]) {
|
|
523
|
+
return revalidators[0](MUTATE_EVENT).then(() => get().data);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return get().data;
|
|
527
|
+
};
|
|
528
|
+
if (args.length < 3) {
|
|
529
|
+
return startRevalidate();
|
|
530
|
+
}
|
|
531
|
+
let data = _data;
|
|
532
|
+
let error;
|
|
533
|
+
let isError = false;
|
|
534
|
+
const beforeMutationTs = getTimestamp();
|
|
535
|
+
MUTATION[key] = [
|
|
536
|
+
beforeMutationTs,
|
|
537
|
+
0
|
|
538
|
+
];
|
|
539
|
+
const hasOptimisticData = !isUndefined$1(optimisticData);
|
|
540
|
+
const state = get();
|
|
541
|
+
const displayedData = state.data;
|
|
542
|
+
const currentData = state._c;
|
|
543
|
+
const committedData = isUndefined$1(currentData) ? displayedData : currentData;
|
|
544
|
+
if (hasOptimisticData) {
|
|
545
|
+
optimisticData = isFunction$1(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
|
|
546
|
+
set({
|
|
547
|
+
data: optimisticData,
|
|
548
|
+
_c: committedData
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
if (isFunction$1(data)) {
|
|
552
|
+
try {
|
|
553
|
+
data = data(committedData);
|
|
554
|
+
} catch (err) {
|
|
555
|
+
error = err;
|
|
556
|
+
isError = true;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (data && isPromiseLike(data)) {
|
|
560
|
+
data = await data.catch((err) => {
|
|
561
|
+
error = err;
|
|
562
|
+
isError = true;
|
|
563
|
+
});
|
|
564
|
+
if (beforeMutationTs !== MUTATION[key][0]) {
|
|
565
|
+
if (isError) throw error;
|
|
566
|
+
return data;
|
|
567
|
+
} else if (isError && hasOptimisticData && rollbackOnError(error)) {
|
|
568
|
+
populateCache = true;
|
|
569
|
+
set({
|
|
570
|
+
data: committedData,
|
|
571
|
+
_c: UNDEFINED$1
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
if (populateCache) {
|
|
576
|
+
if (!isError) {
|
|
577
|
+
if (isFunction$1(populateCache)) {
|
|
578
|
+
const populateCachedData = populateCache(data, committedData);
|
|
579
|
+
set({
|
|
580
|
+
data: populateCachedData,
|
|
581
|
+
error: UNDEFINED$1,
|
|
582
|
+
_c: UNDEFINED$1
|
|
583
|
+
});
|
|
584
|
+
} else {
|
|
585
|
+
set({
|
|
586
|
+
data,
|
|
587
|
+
error: UNDEFINED$1,
|
|
588
|
+
_c: UNDEFINED$1
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
MUTATION[key][1] = getTimestamp();
|
|
594
|
+
Promise.resolve(startRevalidate()).then(() => {
|
|
595
|
+
set({
|
|
596
|
+
_c: UNDEFINED$1
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
if (isError) {
|
|
600
|
+
if (throwOnError) throw error;
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
return data;
|
|
604
|
+
}
|
|
398
605
|
}
|
|
399
|
-
|
|
400
|
-
|
|
606
|
+
const revalidateAllKeys = (revalidators, type) => {
|
|
607
|
+
for (const key in revalidators) {
|
|
608
|
+
if (revalidators[key][0]) revalidators[key][0](type);
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
const initCache = (provider, options) => {
|
|
612
|
+
if (!SWRGlobalState.has(provider)) {
|
|
613
|
+
const opts = mergeObjects(defaultConfigOptions, options);
|
|
614
|
+
const EVENT_REVALIDATORS = /* @__PURE__ */ Object.create(null);
|
|
615
|
+
const mutate2 = internalMutate.bind(UNDEFINED$1, provider);
|
|
616
|
+
let unmount = noop$1;
|
|
617
|
+
const subscriptions = /* @__PURE__ */ Object.create(null);
|
|
618
|
+
const subscribe = (key, callback) => {
|
|
619
|
+
const subs = subscriptions[key] || [];
|
|
620
|
+
subscriptions[key] = subs;
|
|
621
|
+
subs.push(callback);
|
|
622
|
+
return () => subs.splice(subs.indexOf(callback), 1);
|
|
623
|
+
};
|
|
624
|
+
const setter = (key, value, prev) => {
|
|
625
|
+
provider.set(key, value);
|
|
626
|
+
const subs = subscriptions[key];
|
|
627
|
+
if (subs) {
|
|
628
|
+
for (const fn of subs) {
|
|
629
|
+
fn(value, prev);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
const initProvider = () => {
|
|
634
|
+
if (!SWRGlobalState.has(provider)) {
|
|
635
|
+
SWRGlobalState.set(provider, [
|
|
636
|
+
EVENT_REVALIDATORS,
|
|
637
|
+
/* @__PURE__ */ Object.create(null),
|
|
638
|
+
/* @__PURE__ */ Object.create(null),
|
|
639
|
+
/* @__PURE__ */ Object.create(null),
|
|
640
|
+
mutate2,
|
|
641
|
+
setter,
|
|
642
|
+
subscribe
|
|
643
|
+
]);
|
|
644
|
+
if (!IS_SERVER) {
|
|
645
|
+
const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED$1, revalidateAllKeys.bind(UNDEFINED$1, EVENT_REVALIDATORS, FOCUS_EVENT)));
|
|
646
|
+
const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED$1, revalidateAllKeys.bind(UNDEFINED$1, EVENT_REVALIDATORS, RECONNECT_EVENT)));
|
|
647
|
+
unmount = () => {
|
|
648
|
+
releaseFocus && releaseFocus();
|
|
649
|
+
releaseReconnect && releaseReconnect();
|
|
650
|
+
SWRGlobalState.delete(provider);
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
initProvider();
|
|
656
|
+
return [
|
|
657
|
+
provider,
|
|
658
|
+
mutate2,
|
|
659
|
+
initProvider,
|
|
660
|
+
unmount
|
|
661
|
+
];
|
|
662
|
+
}
|
|
663
|
+
return [
|
|
664
|
+
provider,
|
|
665
|
+
SWRGlobalState.get(provider)[4]
|
|
666
|
+
];
|
|
667
|
+
};
|
|
668
|
+
const onErrorRetry = (_, __, config, revalidate, opts) => {
|
|
669
|
+
const maxRetryCount = config.errorRetryCount;
|
|
670
|
+
const currentRetryCount = opts.retryCount;
|
|
671
|
+
const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
|
|
672
|
+
if (!isUndefined$1(maxRetryCount) && currentRetryCount > maxRetryCount) {
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
setTimeout(revalidate, timeout, opts);
|
|
676
|
+
};
|
|
677
|
+
const compare = dequal;
|
|
678
|
+
const [cache, mutate] = initCache(/* @__PURE__ */ new Map());
|
|
679
|
+
const defaultConfig = mergeObjects(
|
|
680
|
+
{
|
|
681
|
+
// events
|
|
682
|
+
onLoadingSlow: noop$1,
|
|
683
|
+
onSuccess: noop$1,
|
|
684
|
+
onError: noop$1,
|
|
685
|
+
onErrorRetry,
|
|
686
|
+
onDiscarded: noop$1,
|
|
687
|
+
// switches
|
|
688
|
+
revalidateOnFocus: true,
|
|
689
|
+
revalidateOnReconnect: true,
|
|
690
|
+
revalidateIfStale: true,
|
|
691
|
+
shouldRetryOnError: true,
|
|
692
|
+
// timeouts
|
|
693
|
+
errorRetryInterval: slowConnection ? 1e4 : 5e3,
|
|
694
|
+
focusThrottleInterval: 5 * 1e3,
|
|
695
|
+
dedupingInterval: 2 * 1e3,
|
|
696
|
+
loadingTimeout: slowConnection ? 5e3 : 3e3,
|
|
697
|
+
// providers
|
|
698
|
+
compare,
|
|
699
|
+
isPaused: () => false,
|
|
700
|
+
cache,
|
|
701
|
+
mutate,
|
|
702
|
+
fallback: {}
|
|
703
|
+
},
|
|
704
|
+
// use web preset by default
|
|
705
|
+
preset
|
|
706
|
+
);
|
|
707
|
+
const mergeConfigs = (a, b) => {
|
|
708
|
+
const v = mergeObjects(a, b);
|
|
709
|
+
if (b) {
|
|
710
|
+
const { use: u1, fallback: f1 } = a;
|
|
711
|
+
const { use: u2, fallback: f2 } = b;
|
|
712
|
+
if (u1 && u2) {
|
|
713
|
+
v.use = u1.concat(u2);
|
|
714
|
+
}
|
|
715
|
+
if (f1 && f2) {
|
|
716
|
+
v.fallback = mergeObjects(f1, f2);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return v;
|
|
720
|
+
};
|
|
721
|
+
const SWRConfigContext = reactExports.createContext({});
|
|
722
|
+
const INFINITE_PREFIX = "$inf$";
|
|
723
|
+
const enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
|
|
724
|
+
const use$1 = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
|
|
725
|
+
const setupDevTools = () => {
|
|
726
|
+
if (enableDevtools) {
|
|
727
|
+
window.__SWR_DEVTOOLS_REACT__ = ReactExports;
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
const normalize = (args) => {
|
|
731
|
+
return isFunction$1(args[1]) ? [
|
|
732
|
+
args[0],
|
|
733
|
+
args[1],
|
|
734
|
+
args[2] || {}
|
|
735
|
+
] : [
|
|
736
|
+
args[0],
|
|
737
|
+
null,
|
|
738
|
+
(args[1] === null ? args[2] : args[1]) || {}
|
|
739
|
+
];
|
|
740
|
+
};
|
|
741
|
+
const useSWRConfig = () => {
|
|
742
|
+
const parentConfig = reactExports.useContext(SWRConfigContext);
|
|
743
|
+
const mergedConfig = reactExports.useMemo(() => mergeObjects(defaultConfig, parentConfig), [
|
|
744
|
+
parentConfig
|
|
745
|
+
]);
|
|
746
|
+
return mergedConfig;
|
|
747
|
+
};
|
|
748
|
+
const middleware = (useSWRNext) => (key_, fetcher_, config) => {
|
|
749
|
+
const fetcher = fetcher_ && ((...args) => {
|
|
750
|
+
const [key] = serialize$1(key_);
|
|
751
|
+
const [, , , PRELOAD] = SWRGlobalState.get(cache);
|
|
752
|
+
if (key.startsWith(INFINITE_PREFIX)) {
|
|
753
|
+
return fetcher_(...args);
|
|
754
|
+
}
|
|
755
|
+
const req = PRELOAD[key];
|
|
756
|
+
if (isUndefined$1(req)) return fetcher_(...args);
|
|
757
|
+
delete PRELOAD[key];
|
|
758
|
+
return req;
|
|
759
|
+
});
|
|
760
|
+
return useSWRNext(key_, fetcher, config);
|
|
761
|
+
};
|
|
762
|
+
const BUILT_IN_MIDDLEWARE = use$1.concat(middleware);
|
|
763
|
+
const withArgs = (hook) => {
|
|
764
|
+
return function useSWRArgs(...args) {
|
|
765
|
+
const fallbackConfig = useSWRConfig();
|
|
766
|
+
const [key, fn, _config] = normalize(args);
|
|
767
|
+
const config = mergeConfigs(fallbackConfig, _config);
|
|
768
|
+
let next = hook;
|
|
769
|
+
const { use: use2 } = config;
|
|
770
|
+
const middleware2 = (use2 || []).concat(BUILT_IN_MIDDLEWARE);
|
|
771
|
+
for (let i = middleware2.length; i--; ) {
|
|
772
|
+
next = middleware2[i](next);
|
|
773
|
+
}
|
|
774
|
+
return next(key, fn || config.fetcher || null, config);
|
|
775
|
+
};
|
|
776
|
+
};
|
|
777
|
+
const subscribeCallback = (key, callbacks, callback) => {
|
|
778
|
+
const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
|
|
779
|
+
keyedRevalidators.push(callback);
|
|
780
|
+
return () => {
|
|
781
|
+
const index = keyedRevalidators.indexOf(callback);
|
|
782
|
+
if (index >= 0) {
|
|
783
|
+
keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
|
|
784
|
+
keyedRevalidators.pop();
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
};
|
|
788
|
+
const withMiddleware = (useSWR2, middleware2) => {
|
|
789
|
+
return (...args) => {
|
|
790
|
+
const [key, fn, config] = normalize(args);
|
|
791
|
+
const uses = (config.use || []).concat(middleware2);
|
|
792
|
+
return useSWR2(key, fn, {
|
|
793
|
+
...config,
|
|
794
|
+
use: uses
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
setupDevTools();
|
|
799
|
+
const use = ReactExports.use || // This extra generic is to avoid TypeScript mixing up the generic and JSX sytax
|
|
800
|
+
// and emitting an error.
|
|
801
|
+
// We assume that this is only for the `use(thenable)` case, not `use(context)`.
|
|
802
|
+
// https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45
|
|
803
|
+
((thenable) => {
|
|
804
|
+
switch (thenable.status) {
|
|
805
|
+
case "pending":
|
|
806
|
+
throw thenable;
|
|
807
|
+
case "fulfilled":
|
|
808
|
+
return thenable.value;
|
|
809
|
+
case "rejected":
|
|
810
|
+
throw thenable.reason;
|
|
811
|
+
default:
|
|
812
|
+
thenable.status = "pending";
|
|
813
|
+
thenable.then((v) => {
|
|
814
|
+
thenable.status = "fulfilled";
|
|
815
|
+
thenable.value = v;
|
|
816
|
+
}, (e) => {
|
|
817
|
+
thenable.status = "rejected";
|
|
818
|
+
thenable.reason = e;
|
|
819
|
+
});
|
|
820
|
+
throw thenable;
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
const WITH_DEDUPE = {
|
|
824
|
+
dedupe: true
|
|
825
|
+
};
|
|
826
|
+
const resolvedUndef = Promise.resolve(UNDEFINED$1);
|
|
827
|
+
const useSWRHandler = (_key, fetcher, config) => {
|
|
828
|
+
const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config;
|
|
829
|
+
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
|
|
830
|
+
const [key, fnArg] = serialize$1(_key);
|
|
831
|
+
const initialMountedRef = reactExports.useRef(false);
|
|
832
|
+
const unmountedRef = reactExports.useRef(false);
|
|
833
|
+
const keyRef = reactExports.useRef(key);
|
|
834
|
+
const fetcherRef = reactExports.useRef(fetcher);
|
|
835
|
+
const configRef = reactExports.useRef(config);
|
|
836
|
+
const getConfig = () => configRef.current;
|
|
837
|
+
const isActive = () => getConfig().isVisible() && getConfig().isOnline();
|
|
838
|
+
const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key);
|
|
839
|
+
const stateDependencies = reactExports.useRef({}).current;
|
|
840
|
+
const fallback = isUndefined$1(fallbackData) ? isUndefined$1(config.fallback) ? UNDEFINED$1 : config.fallback[key] : fallbackData;
|
|
841
|
+
const isEqual = (prev, current) => {
|
|
842
|
+
for (const _ in stateDependencies) {
|
|
843
|
+
const t = _;
|
|
844
|
+
if (t === "data") {
|
|
845
|
+
if (!compare2(prev[t], current[t])) {
|
|
846
|
+
if (!isUndefined$1(prev[t])) {
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
849
|
+
if (!compare2(returnedData, current[t])) {
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
} else {
|
|
854
|
+
if (current[t] !== prev[t]) {
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return true;
|
|
860
|
+
};
|
|
861
|
+
const getSnapshot = reactExports.useMemo(() => {
|
|
862
|
+
const shouldStartRequest = (() => {
|
|
863
|
+
if (!key) return false;
|
|
864
|
+
if (!fetcher) return false;
|
|
865
|
+
if (!isUndefined$1(revalidateOnMount)) return revalidateOnMount;
|
|
866
|
+
if (getConfig().isPaused()) return false;
|
|
867
|
+
if (suspense) return false;
|
|
868
|
+
return revalidateIfStale !== false;
|
|
869
|
+
})();
|
|
870
|
+
const getSelectedCache = (state) => {
|
|
871
|
+
const snapshot = mergeObjects(state);
|
|
872
|
+
delete snapshot._k;
|
|
873
|
+
if (!shouldStartRequest) {
|
|
874
|
+
return snapshot;
|
|
875
|
+
}
|
|
876
|
+
return {
|
|
877
|
+
isValidating: true,
|
|
878
|
+
isLoading: true,
|
|
879
|
+
...snapshot
|
|
880
|
+
};
|
|
881
|
+
};
|
|
882
|
+
const cachedData2 = getCache();
|
|
883
|
+
const initialData = getInitialCache();
|
|
884
|
+
const clientSnapshot = getSelectedCache(cachedData2);
|
|
885
|
+
const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData);
|
|
886
|
+
let memorizedSnapshot = clientSnapshot;
|
|
887
|
+
return [
|
|
888
|
+
() => {
|
|
889
|
+
const newSnapshot = getSelectedCache(getCache());
|
|
890
|
+
const compareResult = isEqual(newSnapshot, memorizedSnapshot);
|
|
891
|
+
if (compareResult) {
|
|
892
|
+
memorizedSnapshot.data = newSnapshot.data;
|
|
893
|
+
memorizedSnapshot.isLoading = newSnapshot.isLoading;
|
|
894
|
+
memorizedSnapshot.isValidating = newSnapshot.isValidating;
|
|
895
|
+
memorizedSnapshot.error = newSnapshot.error;
|
|
896
|
+
return memorizedSnapshot;
|
|
897
|
+
} else {
|
|
898
|
+
memorizedSnapshot = newSnapshot;
|
|
899
|
+
return newSnapshot;
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
() => serverSnapshot
|
|
903
|
+
];
|
|
904
|
+
}, [
|
|
905
|
+
cache2,
|
|
906
|
+
key
|
|
907
|
+
]);
|
|
908
|
+
const cached = shimExports.useSyncExternalStore(reactExports.useCallback(
|
|
909
|
+
(callback) => subscribeCache(key, (current, prev) => {
|
|
910
|
+
if (!isEqual(prev, current)) callback();
|
|
911
|
+
}),
|
|
912
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
913
|
+
[
|
|
914
|
+
cache2,
|
|
915
|
+
key
|
|
916
|
+
]
|
|
917
|
+
), getSnapshot[0], getSnapshot[1]);
|
|
918
|
+
const isInitialMount = !initialMountedRef.current;
|
|
919
|
+
const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
|
|
920
|
+
const cachedData = cached.data;
|
|
921
|
+
const data = isUndefined$1(cachedData) ? fallback && isPromiseLike(fallback) ? use(fallback) : fallback : cachedData;
|
|
922
|
+
const error = cached.error;
|
|
923
|
+
const laggyDataRef = reactExports.useRef(data);
|
|
924
|
+
const returnedData = keepPreviousData ? isUndefined$1(cachedData) ? isUndefined$1(laggyDataRef.current) ? data : laggyDataRef.current : cachedData : data;
|
|
925
|
+
const shouldDoInitialRevalidation = (() => {
|
|
926
|
+
if (hasRevalidator && !isUndefined$1(error)) return false;
|
|
927
|
+
if (isInitialMount && !isUndefined$1(revalidateOnMount)) return revalidateOnMount;
|
|
928
|
+
if (getConfig().isPaused()) return false;
|
|
929
|
+
if (suspense) return isUndefined$1(data) ? false : revalidateIfStale;
|
|
930
|
+
return isUndefined$1(data) || revalidateIfStale;
|
|
931
|
+
})();
|
|
932
|
+
const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation);
|
|
933
|
+
const isValidating = isUndefined$1(cached.isValidating) ? defaultValidatingState : cached.isValidating;
|
|
934
|
+
const isLoading = isUndefined$1(cached.isLoading) ? defaultValidatingState : cached.isLoading;
|
|
935
|
+
const revalidate = reactExports.useCallback(
|
|
936
|
+
async (revalidateOpts) => {
|
|
937
|
+
const currentFetcher = fetcherRef.current;
|
|
938
|
+
if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
|
|
939
|
+
return false;
|
|
940
|
+
}
|
|
941
|
+
let newData;
|
|
942
|
+
let startAt;
|
|
943
|
+
let loading = true;
|
|
944
|
+
const opts = revalidateOpts || {};
|
|
945
|
+
const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
|
|
946
|
+
const callbackSafeguard = () => {
|
|
947
|
+
if (IS_REACT_LEGACY) {
|
|
948
|
+
return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
|
|
949
|
+
}
|
|
950
|
+
return key === keyRef.current;
|
|
951
|
+
};
|
|
952
|
+
const finalState = {
|
|
953
|
+
isValidating: false,
|
|
954
|
+
isLoading: false
|
|
955
|
+
};
|
|
956
|
+
const finishRequestAndUpdateState = () => {
|
|
957
|
+
setCache(finalState);
|
|
958
|
+
};
|
|
959
|
+
const cleanupState = () => {
|
|
960
|
+
const requestInfo = FETCH[key];
|
|
961
|
+
if (requestInfo && requestInfo[1] === startAt) {
|
|
962
|
+
delete FETCH[key];
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
const initialState = {
|
|
966
|
+
isValidating: true
|
|
967
|
+
};
|
|
968
|
+
if (isUndefined$1(getCache().data)) {
|
|
969
|
+
initialState.isLoading = true;
|
|
970
|
+
}
|
|
971
|
+
try {
|
|
972
|
+
if (shouldStartNewRequest) {
|
|
973
|
+
setCache(initialState);
|
|
974
|
+
if (config.loadingTimeout && isUndefined$1(getCache().data)) {
|
|
975
|
+
setTimeout(() => {
|
|
976
|
+
if (loading && callbackSafeguard()) {
|
|
977
|
+
getConfig().onLoadingSlow(key, config);
|
|
978
|
+
}
|
|
979
|
+
}, config.loadingTimeout);
|
|
980
|
+
}
|
|
981
|
+
FETCH[key] = [
|
|
982
|
+
currentFetcher(fnArg),
|
|
983
|
+
getTimestamp()
|
|
984
|
+
];
|
|
985
|
+
}
|
|
986
|
+
;
|
|
987
|
+
[newData, startAt] = FETCH[key];
|
|
988
|
+
newData = await newData;
|
|
989
|
+
if (shouldStartNewRequest) {
|
|
990
|
+
setTimeout(cleanupState, config.dedupingInterval);
|
|
991
|
+
}
|
|
992
|
+
if (!FETCH[key] || FETCH[key][1] !== startAt) {
|
|
993
|
+
if (shouldStartNewRequest) {
|
|
994
|
+
if (callbackSafeguard()) {
|
|
995
|
+
getConfig().onDiscarded(key);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
finalState.error = UNDEFINED$1;
|
|
1001
|
+
const mutationInfo = MUTATION[key];
|
|
1002
|
+
if (!isUndefined$1(mutationInfo) && // case 1
|
|
1003
|
+
(startAt <= mutationInfo[0] || // case 2
|
|
1004
|
+
startAt <= mutationInfo[1] || // case 3
|
|
1005
|
+
mutationInfo[1] === 0)) {
|
|
1006
|
+
finishRequestAndUpdateState();
|
|
1007
|
+
if (shouldStartNewRequest) {
|
|
1008
|
+
if (callbackSafeguard()) {
|
|
1009
|
+
getConfig().onDiscarded(key);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return false;
|
|
1013
|
+
}
|
|
1014
|
+
const cacheData = getCache().data;
|
|
1015
|
+
finalState.data = compare2(cacheData, newData) ? cacheData : newData;
|
|
1016
|
+
if (shouldStartNewRequest) {
|
|
1017
|
+
if (callbackSafeguard()) {
|
|
1018
|
+
getConfig().onSuccess(newData, key, config);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
} catch (err) {
|
|
1022
|
+
cleanupState();
|
|
1023
|
+
const currentConfig = getConfig();
|
|
1024
|
+
const { shouldRetryOnError } = currentConfig;
|
|
1025
|
+
if (!currentConfig.isPaused()) {
|
|
1026
|
+
finalState.error = err;
|
|
1027
|
+
if (shouldStartNewRequest && callbackSafeguard()) {
|
|
1028
|
+
currentConfig.onError(err, key, currentConfig);
|
|
1029
|
+
if (shouldRetryOnError === true || isFunction$1(shouldRetryOnError) && shouldRetryOnError(err)) {
|
|
1030
|
+
if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) {
|
|
1031
|
+
currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => {
|
|
1032
|
+
const revalidators = EVENT_REVALIDATORS[key];
|
|
1033
|
+
if (revalidators && revalidators[0]) {
|
|
1034
|
+
revalidators[0](ERROR_REVALIDATE_EVENT, _opts);
|
|
1035
|
+
}
|
|
1036
|
+
}, {
|
|
1037
|
+
retryCount: (opts.retryCount || 0) + 1,
|
|
1038
|
+
dedupe: true
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
loading = false;
|
|
1046
|
+
finishRequestAndUpdateState();
|
|
1047
|
+
return true;
|
|
1048
|
+
},
|
|
1049
|
+
// `setState` is immutable, and `eventsCallback`, `fnArg`, and
|
|
1050
|
+
// `keyValidating` are depending on `key`, so we can exclude them from
|
|
1051
|
+
// the deps array.
|
|
1052
|
+
//
|
|
1053
|
+
// FIXME:
|
|
1054
|
+
// `fn` and `config` might be changed during the lifecycle,
|
|
1055
|
+
// but they might be changed every render like this.
|
|
1056
|
+
// `useSWR('key', () => fetch('/api/'), { suspense: true })`
|
|
1057
|
+
// So we omit the values from the deps array
|
|
1058
|
+
// even though it might cause unexpected behaviors.
|
|
1059
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1060
|
+
[
|
|
1061
|
+
key,
|
|
1062
|
+
cache2
|
|
1063
|
+
]
|
|
1064
|
+
);
|
|
1065
|
+
const boundMutate = reactExports.useCallback(
|
|
1066
|
+
// Use callback to make sure `keyRef.current` returns latest result every time
|
|
1067
|
+
(...args) => {
|
|
1068
|
+
return internalMutate(cache2, keyRef.current, ...args);
|
|
1069
|
+
},
|
|
1070
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1071
|
+
[]
|
|
1072
|
+
);
|
|
1073
|
+
useIsomorphicLayoutEffect(() => {
|
|
1074
|
+
fetcherRef.current = fetcher;
|
|
1075
|
+
configRef.current = config;
|
|
1076
|
+
if (!isUndefined$1(cachedData)) {
|
|
1077
|
+
laggyDataRef.current = cachedData;
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
useIsomorphicLayoutEffect(() => {
|
|
1081
|
+
if (!key) return;
|
|
1082
|
+
const softRevalidate = revalidate.bind(UNDEFINED$1, WITH_DEDUPE);
|
|
1083
|
+
let nextFocusRevalidatedAt = 0;
|
|
1084
|
+
if (getConfig().revalidateOnFocus) {
|
|
1085
|
+
const initNow = Date.now();
|
|
1086
|
+
nextFocusRevalidatedAt = initNow + getConfig().focusThrottleInterval;
|
|
1087
|
+
}
|
|
1088
|
+
const onRevalidate = (type, opts = {}) => {
|
|
1089
|
+
if (type == FOCUS_EVENT) {
|
|
1090
|
+
const now = Date.now();
|
|
1091
|
+
if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) {
|
|
1092
|
+
nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval;
|
|
1093
|
+
softRevalidate();
|
|
1094
|
+
}
|
|
1095
|
+
} else if (type == RECONNECT_EVENT) {
|
|
1096
|
+
if (getConfig().revalidateOnReconnect && isActive()) {
|
|
1097
|
+
softRevalidate();
|
|
1098
|
+
}
|
|
1099
|
+
} else if (type == MUTATE_EVENT) {
|
|
1100
|
+
return revalidate();
|
|
1101
|
+
} else if (type == ERROR_REVALIDATE_EVENT) {
|
|
1102
|
+
return revalidate(opts);
|
|
1103
|
+
}
|
|
1104
|
+
return;
|
|
1105
|
+
};
|
|
1106
|
+
const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
|
|
1107
|
+
unmountedRef.current = false;
|
|
1108
|
+
keyRef.current = key;
|
|
1109
|
+
initialMountedRef.current = true;
|
|
1110
|
+
setCache({
|
|
1111
|
+
_k: fnArg
|
|
1112
|
+
});
|
|
1113
|
+
if (shouldDoInitialRevalidation) {
|
|
1114
|
+
if (!FETCH[key]) {
|
|
1115
|
+
if (isUndefined$1(data) || IS_SERVER) {
|
|
1116
|
+
softRevalidate();
|
|
1117
|
+
} else {
|
|
1118
|
+
rAF(softRevalidate);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
return () => {
|
|
1123
|
+
unmountedRef.current = true;
|
|
1124
|
+
unsubEvents();
|
|
1125
|
+
};
|
|
1126
|
+
}, [
|
|
1127
|
+
key
|
|
1128
|
+
]);
|
|
1129
|
+
useIsomorphicLayoutEffect(() => {
|
|
1130
|
+
let timer;
|
|
1131
|
+
function next() {
|
|
1132
|
+
const interval = isFunction$1(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
|
|
1133
|
+
if (interval && timer !== -1) {
|
|
1134
|
+
timer = setTimeout(execute, interval);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function execute() {
|
|
1138
|
+
if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
|
|
1139
|
+
revalidate(WITH_DEDUPE).then(next);
|
|
1140
|
+
} else {
|
|
1141
|
+
next();
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
next();
|
|
1145
|
+
return () => {
|
|
1146
|
+
if (timer) {
|
|
1147
|
+
clearTimeout(timer);
|
|
1148
|
+
timer = -1;
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
}, [
|
|
1152
|
+
refreshInterval,
|
|
1153
|
+
refreshWhenHidden,
|
|
1154
|
+
refreshWhenOffline,
|
|
1155
|
+
key
|
|
1156
|
+
]);
|
|
1157
|
+
reactExports.useDebugValue(returnedData);
|
|
1158
|
+
if (suspense) {
|
|
1159
|
+
const hasKeyButNoData = key && isUndefined$1(data);
|
|
1160
|
+
if (!IS_REACT_LEGACY && IS_SERVER && hasKeyButNoData) {
|
|
1161
|
+
throw new Error("Fallback data is required when using Suspense in SSR.");
|
|
1162
|
+
}
|
|
1163
|
+
if (hasKeyButNoData) {
|
|
1164
|
+
fetcherRef.current = fetcher;
|
|
1165
|
+
configRef.current = config;
|
|
1166
|
+
unmountedRef.current = false;
|
|
1167
|
+
}
|
|
1168
|
+
const req = PRELOAD[key];
|
|
1169
|
+
const mutateReq = !isUndefined$1(req) && hasKeyButNoData ? boundMutate(req) : resolvedUndef;
|
|
1170
|
+
use(mutateReq);
|
|
1171
|
+
if (!isUndefined$1(error) && hasKeyButNoData) {
|
|
1172
|
+
throw error;
|
|
1173
|
+
}
|
|
1174
|
+
const revalidation = hasKeyButNoData ? revalidate(WITH_DEDUPE) : resolvedUndef;
|
|
1175
|
+
if (!isUndefined$1(returnedData) && hasKeyButNoData) {
|
|
1176
|
+
revalidation.status = "fulfilled";
|
|
1177
|
+
revalidation.value = true;
|
|
1178
|
+
}
|
|
1179
|
+
use(revalidation);
|
|
1180
|
+
}
|
|
1181
|
+
const swrResponse = {
|
|
1182
|
+
mutate: boundMutate,
|
|
1183
|
+
get data() {
|
|
1184
|
+
stateDependencies.data = true;
|
|
1185
|
+
return returnedData;
|
|
1186
|
+
},
|
|
1187
|
+
get error() {
|
|
1188
|
+
stateDependencies.error = true;
|
|
1189
|
+
return error;
|
|
1190
|
+
},
|
|
1191
|
+
get isValidating() {
|
|
1192
|
+
stateDependencies.isValidating = true;
|
|
1193
|
+
return isValidating;
|
|
1194
|
+
},
|
|
1195
|
+
get isLoading() {
|
|
1196
|
+
stateDependencies.isLoading = true;
|
|
1197
|
+
return isLoading;
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1200
|
+
return swrResponse;
|
|
1201
|
+
};
|
|
1202
|
+
const useSWR = withArgs(useSWRHandler);
|
|
1203
|
+
const noop = () => {
|
|
1204
|
+
};
|
|
1205
|
+
const UNDEFINED = (
|
|
1206
|
+
/*#__NOINLINE__*/
|
|
1207
|
+
noop()
|
|
1208
|
+
);
|
|
1209
|
+
const OBJECT = Object;
|
|
1210
|
+
const isUndefined = (v) => v === UNDEFINED;
|
|
1211
|
+
const isFunction = (v) => typeof v == "function";
|
|
1212
|
+
const table = /* @__PURE__ */ new WeakMap();
|
|
1213
|
+
const getTypeName = (value) => OBJECT.prototype.toString.call(value);
|
|
1214
|
+
const isObjectTypeName = (typeName, type) => typeName === `[object ${type}]`;
|
|
1215
|
+
let counter = 0;
|
|
1216
|
+
const stableHash = (arg) => {
|
|
1217
|
+
const type = typeof arg;
|
|
1218
|
+
const typeName = getTypeName(arg);
|
|
1219
|
+
const isDate = isObjectTypeName(typeName, "Date");
|
|
1220
|
+
const isRegex = isObjectTypeName(typeName, "RegExp");
|
|
1221
|
+
const isPlainObject = isObjectTypeName(typeName, "Object");
|
|
1222
|
+
let result;
|
|
1223
|
+
let index;
|
|
1224
|
+
if (OBJECT(arg) === arg && !isDate && !isRegex) {
|
|
1225
|
+
result = table.get(arg);
|
|
1226
|
+
if (result) return result;
|
|
1227
|
+
result = ++counter + "~";
|
|
1228
|
+
table.set(arg, result);
|
|
1229
|
+
if (Array.isArray(arg)) {
|
|
1230
|
+
result = "@";
|
|
1231
|
+
for (index = 0; index < arg.length; index++) {
|
|
1232
|
+
result += stableHash(arg[index]) + ",";
|
|
1233
|
+
}
|
|
1234
|
+
table.set(arg, result);
|
|
1235
|
+
}
|
|
1236
|
+
if (isPlainObject) {
|
|
1237
|
+
result = "#";
|
|
1238
|
+
const keys = OBJECT.keys(arg).sort();
|
|
1239
|
+
while (!isUndefined(index = keys.pop())) {
|
|
1240
|
+
if (!isUndefined(arg[index])) {
|
|
1241
|
+
result += index + ":" + stableHash(arg[index]) + ",";
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
table.set(arg, result);
|
|
1245
|
+
}
|
|
1246
|
+
} else {
|
|
1247
|
+
result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
|
|
1248
|
+
}
|
|
1249
|
+
return result;
|
|
1250
|
+
};
|
|
1251
|
+
const serialize = (key) => {
|
|
1252
|
+
if (isFunction(key)) {
|
|
1253
|
+
try {
|
|
1254
|
+
key = key();
|
|
1255
|
+
} catch (err) {
|
|
1256
|
+
key = "";
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
const args = key;
|
|
1260
|
+
key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : "";
|
|
1261
|
+
return [
|
|
1262
|
+
key,
|
|
1263
|
+
args
|
|
1264
|
+
];
|
|
1265
|
+
};
|
|
1266
|
+
const getFirstPageKey = (getKey) => {
|
|
1267
|
+
return serialize(getKey ? getKey(0, null) : null)[0];
|
|
1268
|
+
};
|
|
1269
|
+
const EMPTY_PROMISE = Promise.resolve();
|
|
1270
|
+
const infinite = (useSWRNext) => (getKey, fn, config) => {
|
|
1271
|
+
const didMountRef = reactExports.useRef(false);
|
|
1272
|
+
const { cache: cache$1, initialSize = 1, revalidateAll = false, persistSize = false, revalidateFirstPage = true, revalidateOnMount = false, parallel = false } = config;
|
|
1273
|
+
const [, , , PRELOAD] = SWRGlobalState.get(cache);
|
|
1274
|
+
let infiniteKey;
|
|
1275
|
+
try {
|
|
1276
|
+
infiniteKey = getFirstPageKey(getKey);
|
|
1277
|
+
if (infiniteKey) infiniteKey = INFINITE_PREFIX + infiniteKey;
|
|
1278
|
+
} catch (err) {
|
|
1279
|
+
}
|
|
1280
|
+
const [get, set, subscribeCache] = createCacheHelper(cache$1, infiniteKey);
|
|
1281
|
+
const getSnapshot = reactExports.useCallback(() => {
|
|
1282
|
+
const size = isUndefined$1(get()._l) ? initialSize : get()._l;
|
|
1283
|
+
return size;
|
|
1284
|
+
}, [
|
|
1285
|
+
cache$1,
|
|
1286
|
+
infiniteKey,
|
|
1287
|
+
initialSize
|
|
1288
|
+
]);
|
|
1289
|
+
shimExports.useSyncExternalStore(reactExports.useCallback(
|
|
1290
|
+
(callback) => {
|
|
1291
|
+
if (infiniteKey) return subscribeCache(infiniteKey, () => {
|
|
1292
|
+
callback();
|
|
1293
|
+
});
|
|
1294
|
+
return () => {
|
|
1295
|
+
};
|
|
1296
|
+
},
|
|
1297
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1298
|
+
[
|
|
1299
|
+
cache$1,
|
|
1300
|
+
infiniteKey
|
|
1301
|
+
]
|
|
1302
|
+
), getSnapshot, getSnapshot);
|
|
1303
|
+
const resolvePageSize = reactExports.useCallback(() => {
|
|
1304
|
+
const cachedPageSize = get()._l;
|
|
1305
|
+
return isUndefined$1(cachedPageSize) ? initialSize : cachedPageSize;
|
|
1306
|
+
}, [
|
|
1307
|
+
infiniteKey,
|
|
1308
|
+
initialSize
|
|
1309
|
+
]);
|
|
1310
|
+
const lastPageSizeRef = reactExports.useRef(resolvePageSize());
|
|
1311
|
+
useIsomorphicLayoutEffect(() => {
|
|
1312
|
+
if (!didMountRef.current) {
|
|
1313
|
+
didMountRef.current = true;
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (infiniteKey) {
|
|
1317
|
+
set({
|
|
1318
|
+
_l: persistSize ? lastPageSizeRef.current : resolvePageSize()
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
}, [
|
|
1322
|
+
infiniteKey,
|
|
1323
|
+
cache$1
|
|
1324
|
+
]);
|
|
1325
|
+
const shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current;
|
|
1326
|
+
const swr = useSWRNext(infiniteKey, async (key) => {
|
|
1327
|
+
const forceRevalidateAll = get()._i;
|
|
1328
|
+
const shouldRevalidatePage = get()._r;
|
|
1329
|
+
set({
|
|
1330
|
+
_r: UNDEFINED$1
|
|
1331
|
+
});
|
|
1332
|
+
const data = [];
|
|
1333
|
+
const pageSize = resolvePageSize();
|
|
1334
|
+
const [getCache] = createCacheHelper(cache$1, key);
|
|
1335
|
+
const cacheData = getCache().data;
|
|
1336
|
+
const revalidators = [];
|
|
1337
|
+
let previousPageData = null;
|
|
1338
|
+
for (let i = 0; i < pageSize; ++i) {
|
|
1339
|
+
const [pageKey, pageArg] = serialize$1(getKey(i, parallel ? null : previousPageData));
|
|
1340
|
+
if (!pageKey) {
|
|
1341
|
+
break;
|
|
1342
|
+
}
|
|
1343
|
+
const [getSWRCache, setSWRCache] = createCacheHelper(cache$1, pageKey);
|
|
1344
|
+
let pageData = getSWRCache().data;
|
|
1345
|
+
const shouldFetchPage = revalidateAll || forceRevalidateAll || isUndefined$1(pageData) || revalidateFirstPage && !i && !isUndefined$1(cacheData) || shouldRevalidateOnMount || cacheData && !isUndefined$1(cacheData[i]) && !config.compare(cacheData[i], pageData);
|
|
1346
|
+
if (fn && (typeof shouldRevalidatePage === "function" ? shouldRevalidatePage(pageData, pageArg) : shouldFetchPage)) {
|
|
1347
|
+
const revalidate = async () => {
|
|
1348
|
+
const hasPreloadedRequest = pageKey in PRELOAD;
|
|
1349
|
+
if (!hasPreloadedRequest) {
|
|
1350
|
+
pageData = await fn(pageArg);
|
|
1351
|
+
} else {
|
|
1352
|
+
const req = PRELOAD[pageKey];
|
|
1353
|
+
delete PRELOAD[pageKey];
|
|
1354
|
+
pageData = await req;
|
|
1355
|
+
}
|
|
1356
|
+
setSWRCache({
|
|
1357
|
+
data: pageData,
|
|
1358
|
+
_k: pageArg
|
|
1359
|
+
});
|
|
1360
|
+
data[i] = pageData;
|
|
1361
|
+
};
|
|
1362
|
+
if (parallel) {
|
|
1363
|
+
revalidators.push(revalidate);
|
|
1364
|
+
} else {
|
|
1365
|
+
await revalidate();
|
|
1366
|
+
}
|
|
1367
|
+
} else {
|
|
1368
|
+
data[i] = pageData;
|
|
1369
|
+
}
|
|
1370
|
+
if (!parallel) {
|
|
1371
|
+
previousPageData = pageData;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
if (parallel) {
|
|
1375
|
+
await Promise.all(revalidators.map((r) => r()));
|
|
1376
|
+
}
|
|
1377
|
+
set({
|
|
1378
|
+
_i: UNDEFINED$1
|
|
1379
|
+
});
|
|
1380
|
+
return data;
|
|
1381
|
+
}, config);
|
|
1382
|
+
const mutate2 = reactExports.useCallback(
|
|
1383
|
+
// eslint-disable-next-line func-names
|
|
1384
|
+
function(data, opts) {
|
|
1385
|
+
const options = typeof opts === "boolean" ? {
|
|
1386
|
+
revalidate: opts
|
|
1387
|
+
} : opts || {};
|
|
1388
|
+
const shouldRevalidate = options.revalidate !== false;
|
|
1389
|
+
if (!infiniteKey) return EMPTY_PROMISE;
|
|
1390
|
+
if (shouldRevalidate) {
|
|
1391
|
+
if (!isUndefined$1(data)) {
|
|
1392
|
+
set({
|
|
1393
|
+
_i: false,
|
|
1394
|
+
_r: options.revalidate
|
|
1395
|
+
});
|
|
1396
|
+
} else {
|
|
1397
|
+
set({
|
|
1398
|
+
_i: true,
|
|
1399
|
+
_r: options.revalidate
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
return arguments.length ? swr.mutate(data, {
|
|
1404
|
+
...options,
|
|
1405
|
+
revalidate: shouldRevalidate
|
|
1406
|
+
}) : swr.mutate();
|
|
1407
|
+
},
|
|
1408
|
+
// swr.mutate is always the same reference
|
|
1409
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1410
|
+
[
|
|
1411
|
+
infiniteKey,
|
|
1412
|
+
cache$1
|
|
1413
|
+
]
|
|
1414
|
+
);
|
|
1415
|
+
const setSize = reactExports.useCallback(
|
|
1416
|
+
(arg) => {
|
|
1417
|
+
if (!infiniteKey) return EMPTY_PROMISE;
|
|
1418
|
+
const [, changeSize] = createCacheHelper(cache$1, infiniteKey);
|
|
1419
|
+
let size;
|
|
1420
|
+
if (isFunction$1(arg)) {
|
|
1421
|
+
size = arg(resolvePageSize());
|
|
1422
|
+
} else if (typeof arg == "number") {
|
|
1423
|
+
size = arg;
|
|
1424
|
+
}
|
|
1425
|
+
if (typeof size != "number") return EMPTY_PROMISE;
|
|
1426
|
+
changeSize({
|
|
1427
|
+
_l: size
|
|
1428
|
+
});
|
|
1429
|
+
lastPageSizeRef.current = size;
|
|
1430
|
+
const data = [];
|
|
1431
|
+
const [getInfiniteCache] = createCacheHelper(cache$1, infiniteKey);
|
|
1432
|
+
let previousPageData = null;
|
|
1433
|
+
for (let i = 0; i < size; ++i) {
|
|
1434
|
+
const [pageKey] = serialize$1(getKey(i, previousPageData));
|
|
1435
|
+
const [getCache] = createCacheHelper(cache$1, pageKey);
|
|
1436
|
+
const pageData = pageKey ? getCache().data : UNDEFINED$1;
|
|
1437
|
+
if (isUndefined$1(pageData)) {
|
|
1438
|
+
return mutate2(getInfiniteCache().data);
|
|
1439
|
+
}
|
|
1440
|
+
data.push(pageData);
|
|
1441
|
+
previousPageData = pageData;
|
|
1442
|
+
}
|
|
1443
|
+
return mutate2(data);
|
|
1444
|
+
},
|
|
1445
|
+
// exclude getKey from the dependencies, which isn't allowed to change during the lifecycle
|
|
1446
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1447
|
+
[
|
|
1448
|
+
infiniteKey,
|
|
1449
|
+
cache$1,
|
|
1450
|
+
mutate2,
|
|
1451
|
+
resolvePageSize
|
|
1452
|
+
]
|
|
1453
|
+
);
|
|
1454
|
+
return {
|
|
1455
|
+
size: resolvePageSize(),
|
|
1456
|
+
setSize,
|
|
1457
|
+
mutate: mutate2,
|
|
1458
|
+
get data() {
|
|
1459
|
+
return swr.data;
|
|
1460
|
+
},
|
|
1461
|
+
get error() {
|
|
1462
|
+
return swr.error;
|
|
1463
|
+
},
|
|
1464
|
+
get isValidating() {
|
|
1465
|
+
return swr.isValidating;
|
|
1466
|
+
},
|
|
1467
|
+
get isLoading() {
|
|
1468
|
+
return swr.isLoading;
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
};
|
|
1472
|
+
const useSWRInfinite = withMiddleware(useSWR, infinite);
|
|
1473
|
+
function useInfiniteList(cacheKey, fetchFn, getItemKey) {
|
|
1474
|
+
var _a;
|
|
1475
|
+
const getKey = reactExports.useCallback(
|
|
1476
|
+
(_index, prev) => {
|
|
1477
|
+
if (prev && (!prev.hasMore || !prev.cursor)) return null;
|
|
1478
|
+
return [cacheKey, (prev == null ? void 0 : prev.cursor) ?? null];
|
|
1479
|
+
},
|
|
1480
|
+
[cacheKey]
|
|
1481
|
+
);
|
|
1482
|
+
const {
|
|
1483
|
+
data: pages,
|
|
1484
|
+
error,
|
|
1485
|
+
isLoading,
|
|
1486
|
+
isValidating,
|
|
1487
|
+
size,
|
|
1488
|
+
setSize,
|
|
1489
|
+
mutate: mutate2
|
|
1490
|
+
} = useSWRInfinite(
|
|
1491
|
+
getKey,
|
|
1492
|
+
([, cursor]) => fetchFn(cursor ?? void 0),
|
|
1493
|
+
{
|
|
1494
|
+
revalidateFirstPage: false,
|
|
1495
|
+
revalidateIfStale: false,
|
|
1496
|
+
revalidateOnFocus: false,
|
|
1497
|
+
keepPreviousData: true
|
|
1498
|
+
}
|
|
1499
|
+
);
|
|
1500
|
+
const items = reactExports.useMemo(() => {
|
|
1501
|
+
if (!pages) return [];
|
|
1502
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1503
|
+
const result = [];
|
|
1504
|
+
for (const page of pages) {
|
|
1505
|
+
for (const item of page.data) {
|
|
1506
|
+
const key = getItemKey(item);
|
|
1507
|
+
if (seen.has(key)) continue;
|
|
1508
|
+
seen.add(key);
|
|
1509
|
+
result.push(item);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return result;
|
|
1513
|
+
}, [pages, getItemKey]);
|
|
1514
|
+
const lastPage = pages == null ? void 0 : pages[pages.length - 1];
|
|
1515
|
+
const hasMore = Boolean((lastPage == null ? void 0 : lastPage.hasMore) && (lastPage == null ? void 0 : lastPage.cursor));
|
|
1516
|
+
const isLoadingMore = size > 0 && Boolean(pages) && pages.length < size;
|
|
1517
|
+
const loadMore = reactExports.useCallback(() => {
|
|
1518
|
+
if (isValidating || !hasMore) return;
|
|
1519
|
+
void setSize((s) => s + 1);
|
|
1520
|
+
}, [isValidating, hasMore, setSize]);
|
|
1521
|
+
const reload = reactExports.useCallback(() => {
|
|
1522
|
+
void setSize(1);
|
|
1523
|
+
void mutate2();
|
|
1524
|
+
}, [setSize, mutate2]);
|
|
1525
|
+
const normalizedError = error ? error instanceof Error ? error : new WorkflowWebAPIError(String(error), { layer: "client" }) : null;
|
|
1526
|
+
return {
|
|
1527
|
+
items,
|
|
1528
|
+
error: normalizedError,
|
|
1529
|
+
isLoading,
|
|
1530
|
+
isLoadingMore,
|
|
1531
|
+
hasMore,
|
|
1532
|
+
loadMore,
|
|
1533
|
+
reload,
|
|
1534
|
+
refresh: reload,
|
|
1535
|
+
pageInfo: (_a = pages == null ? void 0 : pages[0]) == null ? void 0 : _a.pageInfo
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
function useWorkflowRunsInfinite(env, params) {
|
|
1539
|
+
const {
|
|
1540
|
+
workflowName,
|
|
1541
|
+
status,
|
|
1542
|
+
limit = 25,
|
|
1543
|
+
sortOrder = "desc",
|
|
1544
|
+
startTime,
|
|
1545
|
+
endTime
|
|
1546
|
+
} = params;
|
|
1547
|
+
const cacheKey = `workflow-runs:${workflowName ?? ""}:${status ?? ""}:${sortOrder}:${limit}:${startTime ?? ""}:${endTime ?? ""}`;
|
|
1548
|
+
const fetchFn = reactExports.useCallback(
|
|
1549
|
+
(cursor) => unwrapOrThrow(
|
|
1550
|
+
fetchRuns(env, {
|
|
1551
|
+
cursor,
|
|
1552
|
+
sortOrder,
|
|
1553
|
+
limit,
|
|
1554
|
+
workflowName,
|
|
1555
|
+
status,
|
|
1556
|
+
startTime,
|
|
1557
|
+
endTime
|
|
1558
|
+
})
|
|
1559
|
+
),
|
|
1560
|
+
[env, workflowName, limit, sortOrder, status, startTime, endTime]
|
|
1561
|
+
);
|
|
1562
|
+
const getItemKey = reactExports.useCallback((run) => run.runId, []);
|
|
1563
|
+
return useInfiniteList(cacheKey, fetchFn, getItemKey);
|
|
1564
|
+
}
|
|
1565
|
+
function useLoadMoreOnScroll(loadMore, {
|
|
1566
|
+
hasMore,
|
|
1567
|
+
isLoadingMore,
|
|
1568
|
+
root = null,
|
|
1569
|
+
rootMargin = "400px"
|
|
1570
|
+
}) {
|
|
1571
|
+
const sentinelRef = reactExports.useRef(null);
|
|
1572
|
+
const loadMoreRef = reactExports.useRef(loadMore);
|
|
1573
|
+
reactExports.useEffect(() => {
|
|
1574
|
+
loadMoreRef.current = loadMore;
|
|
1575
|
+
}, [loadMore]);
|
|
1576
|
+
reactExports.useEffect(() => {
|
|
1577
|
+
const sentinel = sentinelRef.current;
|
|
1578
|
+
if (!sentinel || !hasMore || isLoadingMore) return;
|
|
1579
|
+
const observer = new IntersectionObserver(
|
|
1580
|
+
(entries) => {
|
|
1581
|
+
for (const entry of entries) {
|
|
1582
|
+
if (entry.isIntersecting) {
|
|
1583
|
+
loadMoreRef.current();
|
|
1584
|
+
break;
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
},
|
|
1588
|
+
{ root, rootMargin, threshold: 0 }
|
|
1589
|
+
);
|
|
1590
|
+
observer.observe(sentinel);
|
|
1591
|
+
return () => observer.disconnect();
|
|
1592
|
+
}, [hasMore, isLoadingMore, root, rootMargin]);
|
|
1593
|
+
return sentinelRef;
|
|
401
1594
|
}
|
|
402
1595
|
function usePaginatedList(fetchFn) {
|
|
403
1596
|
var _a;
|
|
@@ -431,7 +1624,8 @@ function usePaginatedList(fetchFn) {
|
|
|
431
1624
|
newMap.set(pageIndex, {
|
|
432
1625
|
data: cached.data,
|
|
433
1626
|
isLoading: false,
|
|
434
|
-
error: null
|
|
1627
|
+
error: null,
|
|
1628
|
+
pageInfo: cached.pageInfo
|
|
435
1629
|
});
|
|
436
1630
|
return newMap;
|
|
437
1631
|
});
|
|
@@ -445,14 +1639,16 @@ function usePaginatedList(fetchFn) {
|
|
|
445
1639
|
pageCache.current.set(cacheKey, {
|
|
446
1640
|
data: result.data,
|
|
447
1641
|
cursor: result.cursor,
|
|
448
|
-
hasMore: result.hasMore
|
|
1642
|
+
hasMore: result.hasMore,
|
|
1643
|
+
pageInfo: result.pageInfo
|
|
449
1644
|
});
|
|
450
1645
|
setAllPageResults((prev) => {
|
|
451
1646
|
const newMap = new Map(prev);
|
|
452
1647
|
newMap.set(pageIndex, {
|
|
453
1648
|
data: result.data,
|
|
454
1649
|
isLoading: false,
|
|
455
|
-
error: null
|
|
1650
|
+
error: null,
|
|
1651
|
+
pageInfo: result.pageInfo
|
|
456
1652
|
});
|
|
457
1653
|
return newMap;
|
|
458
1654
|
});
|
|
@@ -548,19 +1744,10 @@ function usePaginatedList(fetchFn) {
|
|
|
548
1744
|
hasPreviousPage: currentPage > 0,
|
|
549
1745
|
reload,
|
|
550
1746
|
refresh,
|
|
551
|
-
pageInfo
|
|
1747
|
+
pageInfo,
|
|
1748
|
+
analyticsPageInfo: currentPageResult.pageInfo
|
|
552
1749
|
};
|
|
553
1750
|
}
|
|
554
|
-
function useWorkflowRuns(env, params) {
|
|
555
|
-
const { workflowName, status, limit = 10, sortOrder = "desc" } = params;
|
|
556
|
-
const fetchFn = reactExports.useCallback(
|
|
557
|
-
(cursor) => unwrapOrThrow(
|
|
558
|
-
fetchRuns(env, { cursor, sortOrder, limit, workflowName, status })
|
|
559
|
-
),
|
|
560
|
-
[env, workflowName, limit, sortOrder, status]
|
|
561
|
-
);
|
|
562
|
-
return usePaginatedList(fetchFn);
|
|
563
|
-
}
|
|
564
1751
|
function useWorkflowHooks(env, params) {
|
|
565
1752
|
const { runId, limit = 10, sortOrder = "desc" } = params;
|
|
566
1753
|
const fetchFn = reactExports.useCallback(
|
|
@@ -569,6 +1756,137 @@ function useWorkflowHooks(env, params) {
|
|
|
569
1756
|
);
|
|
570
1757
|
return usePaginatedList(fetchFn);
|
|
571
1758
|
}
|
|
1759
|
+
function HookTokenCell({ env, runId, hookId }) {
|
|
1760
|
+
const [status, setStatus] = reactExports.useState("idle");
|
|
1761
|
+
const [error, setError] = reactExports.useState(null);
|
|
1762
|
+
const handleCopy = async (e) => {
|
|
1763
|
+
e.stopPropagation();
|
|
1764
|
+
if (status === "loading") return;
|
|
1765
|
+
setStatus("loading");
|
|
1766
|
+
setError(null);
|
|
1767
|
+
try {
|
|
1768
|
+
const token = await fetchHookToken(env, runId, hookId);
|
|
1769
|
+
await navigator.clipboard.writeText(token);
|
|
1770
|
+
setStatus("copied");
|
|
1771
|
+
setTimeout(() => setStatus("idle"), 2e3);
|
|
1772
|
+
} catch (err) {
|
|
1773
|
+
console.error("Failed to copy hook token:", err);
|
|
1774
|
+
setError("Failed to copy token");
|
|
1775
|
+
setStatus("idle");
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
const tooltip = error ? error : status === "copied" ? "Copied!" : status === "loading" ? "Fetching token…" : "Copy token";
|
|
1779
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "relative group/copy inline-block", children: [
|
|
1780
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "••••••••••••" }),
|
|
1781
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1782
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1783
|
+
"button",
|
|
1784
|
+
{
|
|
1785
|
+
type: "button",
|
|
1786
|
+
onClick: handleCopy,
|
|
1787
|
+
disabled: status === "loading",
|
|
1788
|
+
className: "absolute right-0 top-1/2 -translate-y-1/2 opacity-0 group-hover/copy:opacity-100 transition-opacity bg-background/80 backdrop-blur-sm p-1 rounded",
|
|
1789
|
+
"aria-label": "Copy token",
|
|
1790
|
+
children: status === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-3 w-3 text-muted-foreground animate-spin" }) : status === "copied" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
|
|
1791
|
+
}
|
|
1792
|
+
) }),
|
|
1793
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: tooltip }) })
|
|
1794
|
+
] })
|
|
1795
|
+
] });
|
|
1796
|
+
}
|
|
1797
|
+
function TableSkeleton({
|
|
1798
|
+
rows = DEFAULT_PAGE_SIZE,
|
|
1799
|
+
variant = "runs"
|
|
1800
|
+
}) {
|
|
1801
|
+
const renderRow = (i) => {
|
|
1802
|
+
switch (variant) {
|
|
1803
|
+
case "runs":
|
|
1804
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1805
|
+
"div",
|
|
1806
|
+
{
|
|
1807
|
+
className: "grid grid-cols-[1fr_1.5fr_0.8fr_1fr_1fr_40px] items-center gap-4 py-3 px-4",
|
|
1808
|
+
children: [
|
|
1809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1810
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1812
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-14" }),
|
|
1813
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-2 w-8" })
|
|
1814
|
+
] }),
|
|
1815
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1816
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-6 w-6 rounded" })
|
|
1818
|
+
]
|
|
1819
|
+
},
|
|
1820
|
+
`skeleton-row-${i}`
|
|
1821
|
+
);
|
|
1822
|
+
case "hooks":
|
|
1823
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1824
|
+
"div",
|
|
1825
|
+
{
|
|
1826
|
+
className: "grid grid-cols-[1.2fr_1.2fr_0.8fr_1fr_0.5fr_40px] items-center gap-4 py-3 px-4",
|
|
1827
|
+
children: [
|
|
1828
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1829
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1830
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-8" }),
|
|
1833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-6 w-6 rounded" })
|
|
1834
|
+
]
|
|
1835
|
+
},
|
|
1836
|
+
`skeleton-row-${i}`
|
|
1837
|
+
);
|
|
1838
|
+
case "workflows":
|
|
1839
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1840
|
+
"div",
|
|
1841
|
+
{
|
|
1842
|
+
className: "grid grid-cols-[1fr_1.5fr_0.5fr] items-center gap-4 py-3 px-4",
|
|
1843
|
+
children: [
|
|
1844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1845
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1846
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-5 w-16 rounded-full mx-auto" })
|
|
1847
|
+
]
|
|
1848
|
+
},
|
|
1849
|
+
`skeleton-row-${i}`
|
|
1850
|
+
);
|
|
1851
|
+
default:
|
|
1852
|
+
return null;
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
const renderHeader = () => {
|
|
1856
|
+
switch (variant) {
|
|
1857
|
+
case "runs":
|
|
1858
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1fr_1.5fr_0.8fr_1fr_1fr_40px] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1859
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1860
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1861
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12" }),
|
|
1862
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1863
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1864
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-6" })
|
|
1865
|
+
] });
|
|
1866
|
+
case "hooks":
|
|
1867
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1.2fr_1.2fr_0.8fr_1fr_0.5fr_40px] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1868
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-16" }),
|
|
1869
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12" }),
|
|
1871
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1872
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1873
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-6" })
|
|
1874
|
+
] });
|
|
1875
|
+
case "workflows":
|
|
1876
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1fr_1.5fr_0.5fr] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1877
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1878
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-10" }),
|
|
1879
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12 mx-auto" })
|
|
1880
|
+
] });
|
|
1881
|
+
default:
|
|
1882
|
+
return null;
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-0", children: [
|
|
1886
|
+
renderHeader(),
|
|
1887
|
+
Array.from({ length: rows }, (_, i) => renderRow(i))
|
|
1888
|
+
] }) });
|
|
1889
|
+
}
|
|
572
1890
|
function HooksTable({
|
|
573
1891
|
runId,
|
|
574
1892
|
onHookClick,
|
|
@@ -593,7 +1911,8 @@ function HooksTable({
|
|
|
593
1911
|
});
|
|
594
1912
|
const hookActions = useHookActions({
|
|
595
1913
|
onResolve: async (hook, payload) => {
|
|
596
|
-
await
|
|
1914
|
+
const token = await fetchHookToken(env, hook.runId, hook.hookId);
|
|
1915
|
+
await resumeHook(env, token, payload);
|
|
597
1916
|
},
|
|
598
1917
|
callbacks: {
|
|
599
1918
|
onSuccess: refresh
|
|
@@ -728,7 +2047,7 @@ function HooksTable({
|
|
|
728
2047
|
] }),
|
|
729
2048
|
error ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", children: [
|
|
730
2049
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
731
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Error loading hooks" }),
|
|
2050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: getErrorTitle(error, "Error loading hooks") }),
|
|
732
2051
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
733
2052
|
] }) : !loading && (!hooks || hooks.length === 0) ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
734
2053
|
"No active hooks found. ",
|
|
@@ -753,7 +2072,14 @@ function HooksTable({
|
|
|
753
2072
|
children: [
|
|
754
2073
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: hook.hookId, overlay: true, children: hook.hookId }) }),
|
|
755
2074
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: hook.runId, overlay: true, children: hook.runId }) }),
|
|
756
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2076
|
+
HookTokenCell,
|
|
2077
|
+
{
|
|
2078
|
+
env,
|
|
2079
|
+
runId: hook.runId,
|
|
2080
|
+
hookId: hook.hookId
|
|
2081
|
+
}
|
|
2082
|
+
) }),
|
|
757
2083
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: hook.createdAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: hook.createdAt }) : "-" }),
|
|
758
2084
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: renderInvocationCount(hook) }),
|
|
759
2085
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
|
|
@@ -2301,6 +3627,37 @@ const SelectSeparator = reactExports.forwardRef(({ className, ...props }, ref) =
|
|
|
2301
3627
|
}
|
|
2302
3628
|
));
|
|
2303
3629
|
SelectSeparator.displayName = Separator.displayName;
|
|
3630
|
+
function bulkCancelToastSeverity(summary) {
|
|
3631
|
+
const succeeded = summary.cancelled + summary.alreadyCancelled;
|
|
3632
|
+
const hadProblem = summary.failed + summary.notCancellable + summary.notFound > 0;
|
|
3633
|
+
if (succeeded === 0) return "error";
|
|
3634
|
+
if (hadProblem) return "warning";
|
|
3635
|
+
return "success";
|
|
3636
|
+
}
|
|
3637
|
+
function shouldRetainSelectionAfterBulkCancel(result) {
|
|
3638
|
+
return result.outcome === "failed" && result.retryable;
|
|
3639
|
+
}
|
|
3640
|
+
const windows = /* @__PURE__ */ new Map();
|
|
3641
|
+
function createWindow(periodMs) {
|
|
3642
|
+
const end = Date.now();
|
|
3643
|
+
return {
|
|
3644
|
+
startTime: new Date(end - periodMs).toISOString(),
|
|
3645
|
+
endTime: new Date(end).toISOString()
|
|
3646
|
+
};
|
|
3647
|
+
}
|
|
3648
|
+
function getListingWindow(periodId, periodMs) {
|
|
3649
|
+
let window2 = windows.get(periodId);
|
|
3650
|
+
if (!window2) {
|
|
3651
|
+
window2 = createWindow(periodMs);
|
|
3652
|
+
windows.set(periodId, window2);
|
|
3653
|
+
}
|
|
3654
|
+
return window2;
|
|
3655
|
+
}
|
|
3656
|
+
function advanceListingWindow(periodId, periodMs) {
|
|
3657
|
+
const window2 = createWindow(periodMs);
|
|
3658
|
+
windows.set(periodId, window2);
|
|
3659
|
+
return window2;
|
|
3660
|
+
}
|
|
2304
3661
|
function useTableSelection({
|
|
2305
3662
|
getItemId
|
|
2306
3663
|
}) {
|
|
@@ -2723,6 +4080,20 @@ const statusMap = {
|
|
|
2723
4080
|
failed: { label: "Failed", color: "bg-red-600 dark:bg-red-400" },
|
|
2724
4081
|
cancelled: { label: "Cancelled", color: "bg-gray-600 dark:bg-gray-400" }
|
|
2725
4082
|
};
|
|
4083
|
+
const HOUR_MS = 60 * 60 * 1e3;
|
|
4084
|
+
const DAY_MS = 24 * HOUR_MS;
|
|
4085
|
+
const PERIOD_PRESETS = [
|
|
4086
|
+
{ id: "1h", label: "Last hour", ms: HOUR_MS },
|
|
4087
|
+
{ id: "6h", label: "Last 6 hours", ms: 6 * HOUR_MS },
|
|
4088
|
+
{ id: "24h", label: "Last 24 hours", ms: DAY_MS },
|
|
4089
|
+
{ id: "3d", label: "Last 3 days", ms: 3 * DAY_MS },
|
|
4090
|
+
{ id: "7d", label: "Last 7 days", ms: 7 * DAY_MS },
|
|
4091
|
+
{ id: "30d", label: "Last 30 days", ms: 30 * DAY_MS }
|
|
4092
|
+
];
|
|
4093
|
+
const DEFAULT_PERIOD = "24h";
|
|
4094
|
+
function isPeriodId(value) {
|
|
4095
|
+
return PERIOD_PRESETS.some((preset2) => preset2.id === value);
|
|
4096
|
+
}
|
|
2726
4097
|
function useWorkflowFilter() {
|
|
2727
4098
|
const navigate = useNavigate();
|
|
2728
4099
|
const { pathname } = useLocation();
|
|
@@ -2758,15 +4129,36 @@ function useStatusFilter() {
|
|
|
2758
4129
|
[navigate, pathname, searchParams]
|
|
2759
4130
|
);
|
|
2760
4131
|
}
|
|
4132
|
+
function usePeriodFilter() {
|
|
4133
|
+
const navigate = useNavigate();
|
|
4134
|
+
const { pathname } = useLocation();
|
|
4135
|
+
const [searchParams] = useSearchParams();
|
|
4136
|
+
return reactExports.useCallback(
|
|
4137
|
+
(value) => {
|
|
4138
|
+
const params = new URLSearchParams(searchParams.toString());
|
|
4139
|
+
if (value === DEFAULT_PERIOD) {
|
|
4140
|
+
params.delete("period");
|
|
4141
|
+
} else {
|
|
4142
|
+
params.set("period", value);
|
|
4143
|
+
}
|
|
4144
|
+
navigate(`${pathname}?${params.toString()}`);
|
|
4145
|
+
},
|
|
4146
|
+
[navigate, pathname, searchParams]
|
|
4147
|
+
);
|
|
4148
|
+
}
|
|
2761
4149
|
function FilterControls({
|
|
2762
4150
|
workflowNameFilter,
|
|
2763
4151
|
status,
|
|
2764
4152
|
seenWorkflowNames,
|
|
2765
4153
|
sortOrder,
|
|
2766
4154
|
loading,
|
|
2767
|
-
|
|
4155
|
+
period,
|
|
4156
|
+
showPeriodPicker,
|
|
4157
|
+
planWindowMs,
|
|
4158
|
+
planUpgradeAvailable,
|
|
2768
4159
|
onWorkflowChange,
|
|
2769
4160
|
onStatusChange,
|
|
4161
|
+
onPeriodChange,
|
|
2770
4162
|
onSortToggle,
|
|
2771
4163
|
onRefresh,
|
|
2772
4164
|
lastRefreshTime
|
|
@@ -2784,6 +4176,35 @@ function FilterControls({
|
|
|
2784
4176
|
)
|
|
2785
4177
|
] }),
|
|
2786
4178
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
4179
|
+
showPeriodPicker && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
4180
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4181
|
+
Select,
|
|
4182
|
+
{
|
|
4183
|
+
value: period,
|
|
4184
|
+
onValueChange: onPeriodChange,
|
|
4185
|
+
disabled: loading,
|
|
4186
|
+
children: [
|
|
4187
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-[150px] h-9", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Time window" }) }),
|
|
4188
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: PERIOD_PRESETS.map((preset2) => {
|
|
4189
|
+
const beyondPlan = planWindowMs !== void 0 && preset2.ms > planWindowMs;
|
|
4190
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4191
|
+
SelectItem,
|
|
4192
|
+
{
|
|
4193
|
+
value: preset2.id,
|
|
4194
|
+
disabled: beyondPlan,
|
|
4195
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
4196
|
+
preset2.label,
|
|
4197
|
+
beyondPlan && planUpgradeAvailable && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Observability Plus" })
|
|
4198
|
+
] })
|
|
4199
|
+
},
|
|
4200
|
+
preset2.id
|
|
4201
|
+
);
|
|
4202
|
+
}) })
|
|
4203
|
+
]
|
|
4204
|
+
}
|
|
4205
|
+
) }) }),
|
|
4206
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: planUpgradeAvailable ? "Time window for the runs list. Longer windows require Observability Plus." : "Time window for the runs list" })
|
|
4207
|
+
] }),
|
|
2787
4208
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2788
4209
|
Select,
|
|
2789
4210
|
{
|
|
@@ -2808,7 +4229,7 @@ function FilterControls({
|
|
|
2808
4229
|
{
|
|
2809
4230
|
value: status || "all",
|
|
2810
4231
|
onValueChange: onStatusChange,
|
|
2811
|
-
disabled: loading
|
|
4232
|
+
disabled: loading,
|
|
2812
4233
|
children: [
|
|
2813
4234
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-[140px] h-9", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Filter by status" }) }),
|
|
2814
4235
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
@@ -2828,7 +4249,7 @@ function FilterControls({
|
|
|
2828
4249
|
]
|
|
2829
4250
|
}
|
|
2830
4251
|
) }) }),
|
|
2831
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children:
|
|
4252
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Filter runs by status" })
|
|
2832
4253
|
] }),
|
|
2833
4254
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2834
4255
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2866,7 +4287,7 @@ function FilterControls({
|
|
|
2866
4287
|
] });
|
|
2867
4288
|
}
|
|
2868
4289
|
function RunsTable({ onRunClick }) {
|
|
2869
|
-
var _a, _b, _c
|
|
4290
|
+
var _a, _b, _c;
|
|
2870
4291
|
const [searchParams] = useSearchParams();
|
|
2871
4292
|
const handleWorkflowFilter = useWorkflowFilter();
|
|
2872
4293
|
const handleStatusFilter = useStatusFilter();
|
|
@@ -2875,6 +4296,10 @@ function RunsTable({ onRunClick }) {
|
|
|
2875
4296
|
const validStatuses = Object.keys(statusMap);
|
|
2876
4297
|
const status = rawStatus === "all" || rawStatus && validStatuses.includes(rawStatus) ? rawStatus : void 0;
|
|
2877
4298
|
const workflowNameFilter = searchParams.get("workflow");
|
|
4299
|
+
const rawPeriod = searchParams.get("period");
|
|
4300
|
+
const period = isPeriodId(rawPeriod) ? rawPeriod : DEFAULT_PERIOD;
|
|
4301
|
+
const periodPreset = PERIOD_PRESETS.find((preset2) => preset2.id === period) ?? PERIOD_PRESETS[2];
|
|
4302
|
+
const handlePeriodFilter = usePeriodFilter();
|
|
2878
4303
|
const [sortOrder, setSortOrder] = reactExports.useState("desc");
|
|
2879
4304
|
const [lastRefreshTime, setLastRefreshTime] = reactExports.useState(
|
|
2880
4305
|
() => /* @__PURE__ */ new Date()
|
|
@@ -2884,35 +4309,62 @@ function RunsTable({ onRunClick }) {
|
|
|
2884
4309
|
const isLocal = serverConfig.backendId === "local" || serverConfig.backendId === "@workflow/world-local";
|
|
2885
4310
|
const localDataDirPath = (_a = serverConfig.displayInfo) == null ? void 0 : _a["local.dataDirPath"];
|
|
2886
4311
|
const localShortName = (_b = serverConfig.displayInfo) == null ? void 0 : _b["local.shortName"];
|
|
2887
|
-
const statusFilterRequiresWorkflowNameFilter = ((_c = serverConfig.backendId) == null ? void 0 : _c.includes("vercel")) || false;
|
|
2888
4312
|
const [seenWorkflowNames, setSeenWorkflowNames] = reactExports.useState(
|
|
2889
4313
|
/* @__PURE__ */ new Set()
|
|
2890
4314
|
);
|
|
4315
|
+
const isVercelBackend = ((_c = serverConfig.backendId) == null ? void 0 : _c.includes("vercel")) ?? false;
|
|
4316
|
+
const [listingWindow, setListingWindow] = reactExports.useState(
|
|
4317
|
+
() => isVercelBackend ? getListingWindow(period, periodPreset.ms) : void 0
|
|
4318
|
+
);
|
|
4319
|
+
reactExports.useEffect(() => {
|
|
4320
|
+
setListingWindow(
|
|
4321
|
+
isVercelBackend ? getListingWindow(period, periodPreset.ms) : void 0
|
|
4322
|
+
);
|
|
4323
|
+
}, [isVercelBackend, period, periodPreset.ms]);
|
|
4324
|
+
const refreshListingWindow = reactExports.useCallback(() => {
|
|
4325
|
+
if (isVercelBackend) {
|
|
4326
|
+
setListingWindow(advanceListingWindow(period, periodPreset.ms));
|
|
4327
|
+
}
|
|
4328
|
+
}, [isVercelBackend, period, periodPreset.ms]);
|
|
2891
4329
|
const {
|
|
2892
|
-
|
|
4330
|
+
items: runs,
|
|
2893
4331
|
error,
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
4332
|
+
isLoading,
|
|
4333
|
+
isLoadingMore,
|
|
4334
|
+
hasMore,
|
|
4335
|
+
loadMore,
|
|
2898
4336
|
reload,
|
|
2899
4337
|
refresh,
|
|
2900
|
-
pageInfo
|
|
2901
|
-
} =
|
|
4338
|
+
pageInfo: analyticsPageInfo
|
|
4339
|
+
} = useWorkflowRunsInfinite(env, {
|
|
2902
4340
|
sortOrder,
|
|
2903
4341
|
workflowName: workflowNameFilter === "all" ? void 0 : workflowNameFilter,
|
|
2904
|
-
status: status === "all" ? void 0 : status
|
|
4342
|
+
status: status === "all" ? void 0 : status,
|
|
4343
|
+
startTime: listingWindow == null ? void 0 : listingWindow.startTime,
|
|
4344
|
+
endTime: listingWindow == null ? void 0 : listingWindow.endTime
|
|
4345
|
+
});
|
|
4346
|
+
const [planInfo, setPlanInfo] = reactExports.useState(void 0);
|
|
4347
|
+
reactExports.useEffect(() => {
|
|
4348
|
+
if (analyticsPageInfo) {
|
|
4349
|
+
setPlanInfo(analyticsPageInfo);
|
|
4350
|
+
}
|
|
4351
|
+
}, [analyticsPageInfo]);
|
|
4352
|
+
const planWindowMs = planInfo !== void 0 ? planInfo.currentLookbackDays * DAY_MS : void 0;
|
|
4353
|
+
const [scrollRoot, setScrollRoot] = reactExports.useState(null);
|
|
4354
|
+
const sentinelRef = useLoadMoreOnScroll(loadMore, {
|
|
4355
|
+
hasMore,
|
|
4356
|
+
isLoadingMore,
|
|
4357
|
+
root: scrollRoot
|
|
2905
4358
|
});
|
|
2906
4359
|
const selection = useTableSelection({
|
|
2907
4360
|
getItemId: (run) => run.runId
|
|
2908
4361
|
});
|
|
2909
|
-
const runs = data.data ?? [];
|
|
2910
4362
|
const [isBulkCancelling, setIsBulkCancelling] = reactExports.useState(false);
|
|
2911
4363
|
const [isBulkReenqueuing, setIsBulkReenqueuing] = reactExports.useState(false);
|
|
2912
|
-
const isLocalAndHasMissingData = isLocal && (!localDataDirPath || !
|
|
4364
|
+
const isLocalAndHasMissingData = isLocal && (!localDataDirPath || !runs.length);
|
|
2913
4365
|
reactExports.useEffect(() => {
|
|
2914
|
-
if (
|
|
2915
|
-
const newNames = new Set(
|
|
4366
|
+
if (runs.length > 0) {
|
|
4367
|
+
const newNames = new Set(runs.map((run) => run.workflowName));
|
|
2916
4368
|
setSeenWorkflowNames((prev) => {
|
|
2917
4369
|
const updated = new Set(prev);
|
|
2918
4370
|
for (const name of newNames) {
|
|
@@ -2921,8 +4373,8 @@ function RunsTable({ onRunClick }) {
|
|
|
2921
4373
|
return updated;
|
|
2922
4374
|
});
|
|
2923
4375
|
}
|
|
2924
|
-
}, [
|
|
2925
|
-
const loading =
|
|
4376
|
+
}, [runs]);
|
|
4377
|
+
const loading = isLoading;
|
|
2926
4378
|
reactExports.useEffect(() => {
|
|
2927
4379
|
if (!loading && !hasLoadedOnce) {
|
|
2928
4380
|
setHasLoadedOnce(true);
|
|
@@ -2934,12 +4386,14 @@ function RunsTable({ onRunClick }) {
|
|
|
2934
4386
|
const onReload = reactExports.useCallback(() => {
|
|
2935
4387
|
setLastRefreshTime(() => /* @__PURE__ */ new Date());
|
|
2936
4388
|
setHasLoadedOnce(false);
|
|
4389
|
+
refreshListingWindow();
|
|
2937
4390
|
reload();
|
|
2938
|
-
}, [reload]);
|
|
4391
|
+
}, [reload, refreshListingWindow]);
|
|
2939
4392
|
const onRefresh = reactExports.useCallback(() => {
|
|
2940
4393
|
setLastRefreshTime(() => /* @__PURE__ */ new Date());
|
|
4394
|
+
refreshListingWindow();
|
|
2941
4395
|
refresh();
|
|
2942
|
-
}, [refresh]);
|
|
4396
|
+
}, [refresh, refreshListingWindow]);
|
|
2943
4397
|
const selectedRuns = reactExports.useMemo(() => {
|
|
2944
4398
|
return runs.filter((run) => selection.selectedIds.has(run.runId));
|
|
2945
4399
|
}, [runs, selection.selectedIds]);
|
|
@@ -2949,27 +4403,39 @@ function RunsTable({ onRunClick }) {
|
|
|
2949
4403
|
);
|
|
2950
4404
|
}, [selectedRuns]);
|
|
2951
4405
|
const hasCancellableSelection = cancellableSelectedRuns.length > 0;
|
|
4406
|
+
const exceedsBulkCancelLimit = cancellableSelectedRuns.length > BULK_CANCEL_MAX_RUN_IDS;
|
|
2952
4407
|
const handleBulkCancel = reactExports.useCallback(async () => {
|
|
2953
|
-
if (isBulkCancelling || cancellableSelectedRuns.length === 0)
|
|
4408
|
+
if (isBulkCancelling || cancellableSelectedRuns.length === 0 || cancellableSelectedRuns.length > BULK_CANCEL_MAX_RUN_IDS) {
|
|
4409
|
+
return;
|
|
4410
|
+
}
|
|
2954
4411
|
setIsBulkCancelling(true);
|
|
2955
4412
|
try {
|
|
2956
|
-
const results = await
|
|
2957
|
-
|
|
4413
|
+
const { summary, results } = await bulkCancelRuns(
|
|
4414
|
+
env,
|
|
4415
|
+
cancellableSelectedRuns.map((run) => run.runId)
|
|
2958
4416
|
);
|
|
2959
|
-
const
|
|
2960
|
-
|
|
2961
|
-
if (
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
);
|
|
2965
|
-
|
|
2966
|
-
|
|
4417
|
+
const parts = [];
|
|
4418
|
+
if (summary.cancelled > 0) parts.push(`${summary.cancelled} cancelled`);
|
|
4419
|
+
if (summary.alreadyCancelled > 0)
|
|
4420
|
+
parts.push(`${summary.alreadyCancelled} already cancelled`);
|
|
4421
|
+
if (summary.notCancellable > 0)
|
|
4422
|
+
parts.push(`${summary.notCancellable} not cancellable`);
|
|
4423
|
+
if (summary.notFound > 0) parts.push(`${summary.notFound} not found`);
|
|
4424
|
+
if (summary.failed > 0) parts.push(`${summary.failed} failed`);
|
|
4425
|
+
const message = parts.join(", ") || "No runs cancelled";
|
|
4426
|
+
const severity = bulkCancelToastSeverity(summary);
|
|
4427
|
+
if (severity === "error") {
|
|
4428
|
+
toast.error(message);
|
|
4429
|
+
} else if (severity === "warning") {
|
|
4430
|
+
toast.warning(message);
|
|
2967
4431
|
} else {
|
|
2968
|
-
toast.
|
|
2969
|
-
|
|
2970
|
-
|
|
4432
|
+
toast.success(message);
|
|
4433
|
+
}
|
|
4434
|
+
for (const result of results) {
|
|
4435
|
+
if (!shouldRetainSelectionAfterBulkCancel(result)) {
|
|
4436
|
+
selection.deselectById(result.runId);
|
|
4437
|
+
}
|
|
2971
4438
|
}
|
|
2972
|
-
selection.clearSelection();
|
|
2973
4439
|
onReload();
|
|
2974
4440
|
} catch (err) {
|
|
2975
4441
|
toast.error("Failed to cancel runs", {
|
|
@@ -3046,120 +4512,122 @@ function RunsTable({ onRunClick }) {
|
|
|
3046
4512
|
seenWorkflowNames,
|
|
3047
4513
|
sortOrder,
|
|
3048
4514
|
loading,
|
|
3049
|
-
|
|
4515
|
+
period,
|
|
4516
|
+
showPeriodPicker: isVercelBackend,
|
|
4517
|
+
planWindowMs,
|
|
4518
|
+
planUpgradeAvailable: (planInfo == null ? void 0 : planInfo.upgradeAvailable) ?? false,
|
|
3050
4519
|
onWorkflowChange: handleWorkflowFilter,
|
|
3051
4520
|
onStatusChange: handleStatusFilter,
|
|
4521
|
+
onPeriodChange: handlePeriodFilter,
|
|
3052
4522
|
onSortToggle: toggleSortOrder,
|
|
3053
4523
|
onRefresh: onReload,
|
|
3054
4524
|
lastRefreshTime
|
|
3055
4525
|
}
|
|
3056
4526
|
),
|
|
3057
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
disabled: !runs.length
|
|
3067
|
-
}
|
|
3068
|
-
) }),
|
|
3069
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Workflow" }),
|
|
3070
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Run ID" }),
|
|
3071
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Status" }),
|
|
3072
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Started" }),
|
|
3073
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Completed" }),
|
|
3074
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10" })
|
|
3075
|
-
] }) }),
|
|
3076
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableBody, { children: error ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
3077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
3078
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Error loading runs" }),
|
|
3079
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
3080
|
-
] }) }) }) }) : loading && !hasLoadedOnce ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }) }) : !data.data || data.data.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center text-muted-foreground flex flex-col items-center justify-center gap-3 h-full", children: [
|
|
3081
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm", children: [
|
|
3082
|
-
"No workflow runs found",
|
|
3083
|
-
isLocalAndHasMissingData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3084
|
-
" in ",
|
|
3085
|
-
localDirText
|
|
3086
|
-
] }) : "",
|
|
3087
|
-
"."
|
|
3088
|
-
] }),
|
|
3089
|
-
isLocalAndHasMissingData && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm flex items-center gap-2", children: "This view will update once you run a workflow." })
|
|
3090
|
-
] }) }) }) : runs.map((run) => {
|
|
3091
|
-
var _a2;
|
|
3092
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3093
|
-
TableRow,
|
|
3094
|
-
{
|
|
3095
|
-
className: "cursor-pointer group relative",
|
|
3096
|
-
onClick: () => onRunClick(run.runId),
|
|
3097
|
-
"data-selected": selection.isSelected(run),
|
|
3098
|
-
children: [
|
|
3099
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4527
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4528
|
+
CardContent,
|
|
4529
|
+
{
|
|
4530
|
+
ref: setScrollRoot,
|
|
4531
|
+
className: "p-0 max-h-[calc(100vh-280px)] overflow-auto",
|
|
4532
|
+
children: [
|
|
4533
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Table, { children: [
|
|
4534
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TableRow, { children: [
|
|
4535
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3100
4536
|
Checkbox,
|
|
3101
4537
|
{
|
|
3102
|
-
checked: selection.
|
|
3103
|
-
|
|
3104
|
-
|
|
4538
|
+
checked: selection.isAllSelected(runs),
|
|
4539
|
+
indeterminate: selection.isSomeSelected(runs),
|
|
4540
|
+
onCheckedChange: () => selection.toggleSelectAll(runs),
|
|
4541
|
+
"aria-label": "Select all runs",
|
|
4542
|
+
disabled: !runs.length
|
|
3105
4543
|
}
|
|
3106
4544
|
) }),
|
|
3107
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3108
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3109
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
4545
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Workflow" }),
|
|
4546
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Run ID" }),
|
|
4547
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Status" }),
|
|
4548
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Started" }),
|
|
4549
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Completed" }),
|
|
4550
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10" })
|
|
4551
|
+
] }) }),
|
|
4552
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(TableBody, { children: [
|
|
4553
|
+
error ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
4554
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
4555
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: getErrorTitle(error, "Error loading runs") }),
|
|
4556
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
4557
|
+
] }) }) }) }) : loading && !hasLoadedOnce ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }) }) : runs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center text-muted-foreground flex flex-col items-center justify-center gap-3 h-full", children: [
|
|
4558
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm", children: [
|
|
4559
|
+
"No workflow runs found",
|
|
4560
|
+
isLocalAndHasMissingData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4561
|
+
" in ",
|
|
4562
|
+
localDirText
|
|
4563
|
+
] }) : "",
|
|
4564
|
+
"."
|
|
4565
|
+
] }),
|
|
4566
|
+
isLocalAndHasMissingData && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm flex items-center gap-2", children: "This view will update once you run a workflow." })
|
|
4567
|
+
] }) }) }) : runs.map((run) => {
|
|
4568
|
+
var _a2;
|
|
4569
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4570
|
+
TableRow,
|
|
4571
|
+
{
|
|
4572
|
+
className: "cursor-pointer group relative",
|
|
4573
|
+
onClick: () => onRunClick(run.runId),
|
|
4574
|
+
"data-selected": selection.isSelected(run),
|
|
4575
|
+
children: [
|
|
4576
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4577
|
+
Checkbox,
|
|
4578
|
+
{
|
|
4579
|
+
checked: selection.isSelected(run),
|
|
4580
|
+
onCheckedChange: () => selection.toggleSelection(run),
|
|
4581
|
+
"aria-label": `Select run ${run.runId}`
|
|
4582
|
+
}
|
|
4583
|
+
) }),
|
|
4584
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.workflowName, overlay: true, children: ((_a2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _a2.shortName) || "?" }) }),
|
|
4585
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.runId, overlay: true, children: run.runId }) }),
|
|
4586
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4587
|
+
StatusBadge,
|
|
4588
|
+
{
|
|
4589
|
+
status: run.status,
|
|
4590
|
+
context: run,
|
|
4591
|
+
durationMs: run.startedAt ? (run.completedAt ? new Date(run.completedAt).getTime() : Date.now()) - new Date(run.startedAt).getTime() : void 0
|
|
4592
|
+
}
|
|
4593
|
+
) }),
|
|
4594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: run.startedAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: run.startedAt }) : "-" }),
|
|
4595
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: run.completedAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: run.completedAt }) : "-" }),
|
|
4596
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4597
|
+
LazyDropdownMenu,
|
|
4598
|
+
{
|
|
4599
|
+
env,
|
|
4600
|
+
runId: run.runId,
|
|
4601
|
+
runStatus: run.status,
|
|
4602
|
+
onSuccess: onReload
|
|
4603
|
+
}
|
|
4604
|
+
) })
|
|
4605
|
+
]
|
|
4606
|
+
},
|
|
4607
|
+
run.runId
|
|
4608
|
+
);
|
|
4609
|
+
}),
|
|
4610
|
+
isLoadingMore && /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 text-sm text-muted-foreground", children: [
|
|
4611
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }),
|
|
4612
|
+
"Loading more runs…"
|
|
4613
|
+
] }) }) })
|
|
4614
|
+
] })
|
|
4615
|
+
] }),
|
|
4616
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: sentinelRef, "aria-hidden": true, className: "h-px" })
|
|
4617
|
+
]
|
|
4618
|
+
}
|
|
4619
|
+
) }),
|
|
4620
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mt-4 text-sm text-muted-foreground", children: [
|
|
4621
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: runs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4622
|
+
"Showing ",
|
|
4623
|
+
runs.length,
|
|
4624
|
+
" run",
|
|
4625
|
+
runs.length === 1 ? "" : "s",
|
|
4626
|
+
!hasMore && !loading ? " · end of list" : ""
|
|
4627
|
+
] }) }),
|
|
4628
|
+
isVercelBackend && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
4629
|
+
periodPreset.label,
|
|
4630
|
+
(planInfo == null ? void 0 : planInfo.upgradeAvailable) ? ` · plan window ${planInfo.currentLookbackDays} day${planInfo.currentLookbackDays === 1 ? "" : "s"}` : ""
|
|
3163
4631
|
] })
|
|
3164
4632
|
] }),
|
|
3165
4633
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -3186,23 +4654,26 @@ function RunsTable({ onRunClick }) {
|
|
|
3186
4654
|
) }),
|
|
3187
4655
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Re-enqueue the workflow orchestration layer for selected runs. Useful if workflows appear stuck." })
|
|
3188
4656
|
] }),
|
|
3189
|
-
hasCancellableSelection && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
4657
|
+
hasCancellableSelection && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
4658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-flex", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4659
|
+
Button,
|
|
4660
|
+
{
|
|
4661
|
+
variant: "ghost",
|
|
4662
|
+
size: "sm",
|
|
4663
|
+
className: "h-7 text-primary-foreground hover:bg-primary-foreground/10 hover:text-primary-foreground",
|
|
4664
|
+
onClick: handleBulkCancel,
|
|
4665
|
+
disabled: isBulkCancelling || exceedsBulkCancelLimit,
|
|
4666
|
+
children: [
|
|
4667
|
+
isBulkCancelling ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 mr-1 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CircleX, { className: "h-4 w-4 mr-1" }),
|
|
4668
|
+
"Cancel",
|
|
4669
|
+
" ",
|
|
4670
|
+
cancellableSelectedRuns.length !== selection.selectionCount ? `${cancellableSelectedRuns.length} ` : "",
|
|
4671
|
+
isBulkCancelling ? "cancelling..." : ""
|
|
4672
|
+
]
|
|
4673
|
+
}
|
|
4674
|
+
) }) }),
|
|
4675
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: exceedsBulkCancelLimit ? `Select up to ${BULK_CANCEL_MAX_RUN_IDS} runs at a time.` : "Cancel the selected pending and running runs." })
|
|
4676
|
+
] })
|
|
3206
4677
|
] })
|
|
3207
4678
|
}
|
|
3208
4679
|
)
|