react-terminal-viewer-cicd 3.0.0-beta.39 → 3.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/Addon/WorkerLog/LogWorker.js +1 -1
- package/dist/esm/PipelineLogViewer/PipelineLogViewer.js +142 -103
- package/dist/esm/PipelineLogViewer/components/SearchBar.d.ts +4 -0
- package/dist/esm/PipelineLogViewer/components/SearchBar.js +22 -8
- package/dist/esm/PipelineLogViewer/constants.d.ts +4 -0
- package/dist/esm/PipelineLogViewer/constants.d.ts.map +1 -1
- package/dist/esm/PipelineLogViewer/constants.js +6 -0
- package/dist/esm/PipelineLogViewer/hooks/useLogFetcher.d.ts +8 -2
- package/dist/esm/PipelineLogViewer/hooks/useLogFetcher.js +213 -86
- package/dist/esm/PipelineLogViewer/hooks/useLogSearch.d.ts +3 -1
- package/dist/esm/PipelineLogViewer/hooks/useLogSearch.d.ts.map +1 -1
- package/dist/esm/PipelineLogViewer/hooks/useLogSearch.js +16 -4
- package/dist/esm/PipelineLogViewer/index.less +101 -9
- package/dist/worker/log.worker.js +1 -1
- package/dist/worker/log.worker.js.map +1 -1
- package/dist/worker/src/PipelineLogViewer/components/SearchBar.d.ts +4 -0
- package/dist/worker/src/PipelineLogViewer/constants.d.ts +4 -0
- package/dist/worker/src/PipelineLogViewer/hooks/useLogFetcher.d.ts +8 -2
- package/dist/worker/src/PipelineLogViewer/hooks/useLogSearch.d.ts +3 -1
- package/package.json +1 -1
- package/dist/esm/PipelineLogViewer/PipelineLogViewer.d.ts.map +0 -1
- package/dist/esm/PipelineLogViewer/components/SearchBar.d.ts.map +0 -1
- package/dist/esm/PipelineLogViewer/hooks/useLogFetcher.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
function LogWorker() {
|
|
2
2
|
var workerPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/worker';
|
|
3
3
|
var worker = null;
|
|
4
|
-
var version = "3.0.0-beta.
|
|
4
|
+
var version = "3.0.0-beta.40" || '0.0.0';
|
|
5
5
|
var path = workerPath.includes('http') ? "".concat(workerPath, "/log.worker.js") : "".concat(window.location.origin).concat(workerPath, "/log.worker.js");
|
|
6
6
|
var blob = new Blob(["importScripts(\"".concat(path, "?v=").concat(version, "\")")], {
|
|
7
7
|
type: 'application/javascript'
|
|
@@ -3,10 +3,10 @@ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableTo
|
|
|
3
3
|
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
4
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
5
5
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
6
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
6
7
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
7
8
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
8
9
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
9
|
-
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
10
10
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
11
11
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
12
12
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
@@ -28,7 +28,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
28
28
|
// §六 IoC 接口注入:fetchGroups / fetchLogs / searchLogs 由外部传入
|
|
29
29
|
//
|
|
30
30
|
// 组件生命周期调用时序 (设计文档 §六.2):
|
|
31
|
-
// 第一阶段:Mount → Promise.all(fetchGroups, initLoad)
|
|
31
|
+
// 第一阶段:Mount → Promise.all([fetchGroups, initLoad]) 并行首屏加载(分组与日志同屏)
|
|
32
32
|
// 第二阶段:startReached/endReached/轮询 → 单发 loadPrev/loadNext
|
|
33
33
|
// 第三阶段:搜索 → searchLogs → 若跨页则串行 airdropLoad
|
|
34
34
|
// ============================================================================
|
|
@@ -36,7 +36,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
36
36
|
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
37
37
|
import { Virtuoso } from 'react-virtuoso';
|
|
38
38
|
import { GroupHeader, LogRow, SearchBar, StickyHeader } from "./components";
|
|
39
|
-
import { BOUNDARY_PREFETCH_INDEX_MARGIN, DEFAULT_MAX_MEMORY_LINES, DEFAULT_PAGE_SIZE,
|
|
39
|
+
import { BOUNDARY_PREFETCH_INDEX_MARGIN, DEFAULT_MAX_MEMORY_LINES, DEFAULT_PAGE_SIZE, DEFAULT_VIRTUOSO_ITEM_HEIGHT } from "./constants";
|
|
40
40
|
import useDisplayLogs from "./hooks/useDisplayLogs";
|
|
41
41
|
import useGroupManager from "./hooks/useGroupManager";
|
|
42
42
|
import useLogFetcher from "./hooks/useLogFetcher";
|
|
@@ -130,6 +130,26 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
130
130
|
groups = _useState2[0],
|
|
131
131
|
setGroups = _useState2[1];
|
|
132
132
|
|
|
133
|
+
/** running 轮询时与 fetchLogs(loadNext) 同一节拍拉分组,避免两条请求错拍 */
|
|
134
|
+
var runningPollSync = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
135
|
+
var groupData;
|
|
136
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
137
|
+
while (1) switch (_context.prev = _context.next) {
|
|
138
|
+
case 0:
|
|
139
|
+
_context.next = 2;
|
|
140
|
+
return fetchGroups();
|
|
141
|
+
case 2:
|
|
142
|
+
groupData = _context.sent;
|
|
143
|
+
if (groupData && groupData.length > 0) {
|
|
144
|
+
setGroups(groupData);
|
|
145
|
+
}
|
|
146
|
+
case 4:
|
|
147
|
+
case "end":
|
|
148
|
+
return _context.stop();
|
|
149
|
+
}
|
|
150
|
+
}, _callee);
|
|
151
|
+
})), [fetchGroups]);
|
|
152
|
+
|
|
133
153
|
// ===================================================================
|
|
134
154
|
// 二、日志数据获取与游标管理
|
|
135
155
|
// ===================================================================
|
|
@@ -138,7 +158,8 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
138
158
|
fetchLogs: fetchLogs,
|
|
139
159
|
pageSize: pageSize,
|
|
140
160
|
maxMemoryLines: maxMemoryLines,
|
|
141
|
-
pollInterval: pollInterval
|
|
161
|
+
pollInterval: pollInterval,
|
|
162
|
+
runningPollSync: runningPollSync
|
|
142
163
|
});
|
|
143
164
|
|
|
144
165
|
// ===================================================================
|
|
@@ -169,12 +190,18 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
169
190
|
// ===================================================================
|
|
170
191
|
var cursorRef = useRef(logFetcherResult.cursor);
|
|
171
192
|
cursorRef.current = logFetcherResult.cursor;
|
|
193
|
+
var airdropLoad = logFetcherResult.airdropLoad;
|
|
194
|
+
var searchAirdropLoad = useCallback(function (targetRow) {
|
|
195
|
+
return airdropLoad(targetRow, {
|
|
196
|
+
silent: true
|
|
197
|
+
});
|
|
198
|
+
}, [airdropLoad]);
|
|
172
199
|
var logSearchResult = useLogSearch({
|
|
173
200
|
searchLogs: searchLogs,
|
|
174
201
|
getCursor: function getCursor() {
|
|
175
202
|
return cursorRef.current;
|
|
176
203
|
},
|
|
177
|
-
onAirdropLoad:
|
|
204
|
+
onAirdropLoad: searchAirdropLoad,
|
|
178
205
|
ensureGroupExpanded: groupManager.ensureGroupExpanded,
|
|
179
206
|
expandAllGroups: groupManager.expandAll
|
|
180
207
|
});
|
|
@@ -192,7 +219,11 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
192
219
|
var displayLogsRef = useRef(displayLogs);
|
|
193
220
|
displayLogsRef.current = displayLogs;
|
|
194
221
|
|
|
195
|
-
/**
|
|
222
|
+
/**
|
|
223
|
+
* 有搜索关键字时禁用 followOutput、并阻止 running 下 currentEndRow 触发的兜底置底。
|
|
224
|
+
* 必须在 handleSearch 内 await 之前同步置 true:setSearchState 尚未提交时 ref 若仍为 false,
|
|
225
|
+
* 轮询增大 currentEndRow 会误触 useLayoutEffect 的 scrollToIndex(LAST),导致刚跳转的命中行被「跳走」。
|
|
226
|
+
*/
|
|
196
227
|
var searchKeywordActiveRef = useRef(false);
|
|
197
228
|
searchKeywordActiveRef.current = Boolean((_logSearchResult$sear = logSearchResult.searchState.keyword) === null || _logSearchResult$sear === void 0 ? void 0 : _logSearchResult$sear.trim());
|
|
198
229
|
|
|
@@ -209,6 +240,8 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
209
240
|
// displayLogs 的变化,在 React 完成下一次 re-render 后自动执行滚动。
|
|
210
241
|
// ===================================================================
|
|
211
242
|
var pendingScrollRowRef = useRef(null);
|
|
243
|
+
/** 与 pendingScrollRowRef 配套的对齐方式:搜索跳转用 center,scrollToTop 用 start */
|
|
244
|
+
var pendingScrollAlignRef = useRef('center');
|
|
212
245
|
|
|
213
246
|
// rangeChanged 边界检测的节流锁:防止在顶/底停留时连续触发加载
|
|
214
247
|
var boundaryFetchingRef = useRef(false);
|
|
@@ -280,14 +313,17 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
280
313
|
initLoadRef.current = logFetcherResult.initLoad;
|
|
281
314
|
|
|
282
315
|
/**
|
|
283
|
-
*
|
|
284
|
-
* 加载完成后用 scrollToIndex('LAST') 滚到底部。
|
|
316
|
+
* 首屏:fetchGroups 与 initLoad(fetchLogs) 并行,完成后滚到底部。
|
|
285
317
|
* Virtuoso 无条件挂载,保证 startReached / endReached / followOutput 正常工作。
|
|
286
318
|
*/
|
|
287
319
|
useEffect(function () {
|
|
288
320
|
if (initializedRef.current) return;
|
|
289
321
|
initializedRef.current = true;
|
|
290
|
-
|
|
322
|
+
Promise.all([fetchGroups().then(function (groupData) {
|
|
323
|
+
if (groupData && groupData.length > 0) {
|
|
324
|
+
setGroups(groupData);
|
|
325
|
+
}
|
|
326
|
+
}), initLoadRef.current()]).then(function () {
|
|
291
327
|
ignoreBoundaryFetchRef.current = Date.now() + 500;
|
|
292
328
|
requestAnimationFrame(function () {
|
|
293
329
|
var _virtuosoRef$current;
|
|
@@ -299,16 +335,6 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
299
335
|
});
|
|
300
336
|
});
|
|
301
337
|
}, [fetchLogs, fetchGroups]);
|
|
302
|
-
/**
|
|
303
|
-
* 首屏初始化分组信息
|
|
304
|
-
*/
|
|
305
|
-
useEffect(function () {
|
|
306
|
-
fetchGroups().then(function (groupData) {
|
|
307
|
-
if (groupData && groupData.length > 0) {
|
|
308
|
-
setGroups(groupData);
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}, [fetchGroups]);
|
|
312
338
|
|
|
313
339
|
// fetchLogs 引用变化 = 新日志源(如外部 logUrl 切换):清空状态并允许首屏 init 重新跑
|
|
314
340
|
/* eslint-disable react-hooks/exhaustive-deps -- 仅响应 fetchLogs 引用变化;reset/clearSearch/expandAll 为稳定回调 */
|
|
@@ -325,6 +351,7 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
325
351
|
collapseAirdropActiveRef.current = false;
|
|
326
352
|
isAtBottomRef.current = true;
|
|
327
353
|
pendingScrollRowRef.current = null;
|
|
354
|
+
pendingScrollAlignRef.current = 'center';
|
|
328
355
|
boundaryFetchingRef.current = false;
|
|
329
356
|
pendingScrollAfterPrevRef.current = null;
|
|
330
357
|
pendingScrollAfterNextRef.current = null;
|
|
@@ -332,23 +359,6 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
332
359
|
}, [fetchLogs, logFetcherResult.reset, groupManager.expandAll, logSearchResult.clearSearch]);
|
|
333
360
|
/* eslint-enable react-hooks/exhaustive-deps */
|
|
334
361
|
|
|
335
|
-
// running 态定时轮询分组(与 useLogFetcher 中 fetchLogs 轮询策略一致)
|
|
336
|
-
useEffect(function () {
|
|
337
|
-
if (status !== 'running') return undefined;
|
|
338
|
-
var intervalMs = pollInterval !== null && pollInterval !== void 0 ? pollInterval : DEFAULT_POLL_INTERVAL;
|
|
339
|
-
var timer = window.setInterval(function () {
|
|
340
|
-
if (logFetcherResult.isUserBrowsingHistory) return;
|
|
341
|
-
fetchGroups().then(function (groupData) {
|
|
342
|
-
if (groupData && groupData.length > 0) {
|
|
343
|
-
setGroups(groupData);
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}, intervalMs);
|
|
347
|
-
return function () {
|
|
348
|
-
return window.clearInterval(timer);
|
|
349
|
-
};
|
|
350
|
-
}, [status, pollInterval, fetchGroups, logFetcherResult.isUserBrowsingHistory]);
|
|
351
|
-
|
|
352
362
|
// ===================================================================
|
|
353
363
|
// 折叠导致可见内容过少时自动跳转到折叠区之前
|
|
354
364
|
//
|
|
@@ -430,8 +440,8 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
430
440
|
var anchorRow = (_displayLogsRef$curre = displayLogsRef.current[anchorIndex]) === null || _displayLogsRef$curre === void 0 ? void 0 : _displayLogsRef$curre.absoluteRow;
|
|
431
441
|
pendingScrollAfterPrevRef.current = anchorRow !== undefined && anchorRow !== null ? anchorRow : null;
|
|
432
442
|
displayLogsLenBeforeLoadPrevRef.current = displayLogsRef.current.length;
|
|
433
|
-
(_virtuosoRef$current2 = virtuosoRef.current) === null || _virtuosoRef$current2 === void 0 || _virtuosoRef$current2.getState(function (
|
|
434
|
-
var scrollTop =
|
|
443
|
+
(_virtuosoRef$current2 = virtuosoRef.current) === null || _virtuosoRef$current2 === void 0 || _virtuosoRef$current2.getState(function (_ref4) {
|
|
444
|
+
var scrollTop = _ref4.scrollTop;
|
|
435
445
|
scrollTopBeforeLoadPrevRef.current = scrollTop;
|
|
436
446
|
});
|
|
437
447
|
boundaryFetchingRef.current = true;
|
|
@@ -460,8 +470,8 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
460
470
|
var anchorRow = (_displayLogsRef$curre2 = displayLogsRef.current[anchorIndex]) === null || _displayLogsRef$curre2 === void 0 ? void 0 : _displayLogsRef$curre2.absoluteRow;
|
|
461
471
|
pendingScrollAfterNextRef.current = anchorRow !== undefined && anchorRow !== null ? anchorRow : null;
|
|
462
472
|
displayLogsLenBeforeLoadNextRef.current = displayLogsRef.current.length;
|
|
463
|
-
(_virtuosoRef$current3 = virtuosoRef.current) === null || _virtuosoRef$current3 === void 0 || _virtuosoRef$current3.getState(function (
|
|
464
|
-
var scrollTop =
|
|
473
|
+
(_virtuosoRef$current3 = virtuosoRef.current) === null || _virtuosoRef$current3 === void 0 || _virtuosoRef$current3.getState(function (_ref5) {
|
|
474
|
+
var scrollTop = _ref5.scrollTop;
|
|
465
475
|
scrollTopBeforeLoadNextRef.current = scrollTop;
|
|
466
476
|
});
|
|
467
477
|
boundaryFetchingRef.current = true;
|
|
@@ -614,6 +624,12 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
614
624
|
if (!isAtBottomRef.current) return;
|
|
615
625
|
requestAnimationFrame(function () {
|
|
616
626
|
var _virtuosoRef$current4;
|
|
627
|
+
// 在 rAF 回调执行时再次检查,防止在排队期间用户执行了置顶/搜索/折叠等操作(产生竞态被强行拉回底部)
|
|
628
|
+
if (statusRef.current !== 'running') return;
|
|
629
|
+
if (searchKeywordActiveRef.current) return;
|
|
630
|
+
if (groupActionRef.current) return;
|
|
631
|
+
if (collapseAirdropActiveRef.current) return;
|
|
632
|
+
if (userStoppedFollowingRef.current) return;
|
|
617
633
|
ignoreBoundaryFetchRef.current = Date.now() + 500;
|
|
618
634
|
(_virtuosoRef$current4 = virtuosoRef.current) === null || _virtuosoRef$current4 === void 0 || _virtuosoRef$current4.scrollToIndex({
|
|
619
635
|
index: 'LAST',
|
|
@@ -627,17 +643,18 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
627
643
|
// 搜索跳转滚动
|
|
628
644
|
// ===================================================================
|
|
629
645
|
// ===================================================================
|
|
630
|
-
// 在 Virtuoso 完成布局后再 scrollToIndex
|
|
646
|
+
// 在 Virtuoso 完成布局后再 scrollToIndex(scrollToTop 需空降时与此相同,走 pendingScrollRowRef)。
|
|
631
647
|
// 同步调用会因 totalCount / 内部 range 尚未更新而无效;长 setTimeout 只是“等布局”的权宜之计。
|
|
632
648
|
// ===================================================================
|
|
633
649
|
var scheduleScrollToDisplayIndex = useCallback(function (displayIndex) {
|
|
650
|
+
var align = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'center';
|
|
634
651
|
ignoreBoundaryFetchRef.current = Date.now() + 500;
|
|
635
652
|
requestAnimationFrame(function () {
|
|
636
653
|
var v = virtuosoRef.current;
|
|
637
654
|
if (!v || displayLogsRef.current.length === 0) return;
|
|
638
655
|
v.scrollToIndex({
|
|
639
656
|
index: displayIndex,
|
|
640
|
-
align:
|
|
657
|
+
align: align,
|
|
641
658
|
behavior: 'auto'
|
|
642
659
|
});
|
|
643
660
|
});
|
|
@@ -650,24 +667,26 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
650
667
|
});
|
|
651
668
|
if (displayIndex >= 0) {
|
|
652
669
|
pendingScrollRowRef.current = null;
|
|
653
|
-
|
|
670
|
+
var align = pendingScrollAlignRef.current;
|
|
671
|
+
pendingScrollAlignRef.current = 'center';
|
|
672
|
+
scheduleScrollToDisplayIndex(displayIndex, align);
|
|
654
673
|
}
|
|
655
674
|
}, [displayLogs, scheduleScrollToDisplayIndex]);
|
|
656
675
|
var scrollToAbsoluteRow = useCallback( /*#__PURE__*/function () {
|
|
657
|
-
var
|
|
676
|
+
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(absoluteRow) {
|
|
658
677
|
var targetRow, currentDisplayLogs, displayIndex;
|
|
659
|
-
return _regeneratorRuntime().wrap(function
|
|
660
|
-
while (1) switch (
|
|
678
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
679
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
661
680
|
case 0:
|
|
662
|
-
|
|
681
|
+
_context2.next = 2;
|
|
663
682
|
return logSearchResult.resolveTargetRow(absoluteRow);
|
|
664
683
|
case 2:
|
|
665
|
-
targetRow =
|
|
684
|
+
targetRow = _context2.sent;
|
|
666
685
|
if (!(targetRow === null)) {
|
|
667
|
-
|
|
686
|
+
_context2.next = 5;
|
|
668
687
|
break;
|
|
669
688
|
}
|
|
670
|
-
return
|
|
689
|
+
return _context2.abrupt("return");
|
|
671
690
|
case 5:
|
|
672
691
|
currentDisplayLogs = displayLogsRef.current;
|
|
673
692
|
displayIndex = currentDisplayLogs.findIndex(function (line) {
|
|
@@ -675,18 +694,20 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
675
694
|
});
|
|
676
695
|
if (displayIndex >= 0) {
|
|
677
696
|
pendingScrollRowRef.current = null;
|
|
697
|
+
pendingScrollAlignRef.current = 'center';
|
|
678
698
|
scheduleScrollToDisplayIndex(displayIndex);
|
|
679
699
|
} else {
|
|
700
|
+
pendingScrollAlignRef.current = 'center';
|
|
680
701
|
pendingScrollRowRef.current = targetRow;
|
|
681
702
|
}
|
|
682
703
|
case 8:
|
|
683
704
|
case "end":
|
|
684
|
-
return
|
|
705
|
+
return _context2.stop();
|
|
685
706
|
}
|
|
686
|
-
},
|
|
707
|
+
}, _callee2);
|
|
687
708
|
}));
|
|
688
709
|
return function (_x) {
|
|
689
|
-
return
|
|
710
|
+
return _ref6.apply(this, arguments);
|
|
690
711
|
};
|
|
691
712
|
}(), [logSearchResult, scheduleScrollToDisplayIndex]);
|
|
692
713
|
|
|
@@ -694,6 +715,7 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
694
715
|
var handleSearchPrev = useCallback(function () {
|
|
695
716
|
var targetRow = logSearchResult.searchPrev();
|
|
696
717
|
if (targetRow !== null) {
|
|
718
|
+
searchKeywordActiveRef.current = true;
|
|
697
719
|
scrollToAbsoluteRow(targetRow);
|
|
698
720
|
}
|
|
699
721
|
}, [logSearchResult, scrollToAbsoluteRow]);
|
|
@@ -702,32 +724,36 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
702
724
|
var handleSearchNext = useCallback(function () {
|
|
703
725
|
var targetRow = logSearchResult.searchNext();
|
|
704
726
|
if (targetRow !== null) {
|
|
727
|
+
searchKeywordActiveRef.current = true;
|
|
705
728
|
scrollToAbsoluteRow(targetRow);
|
|
706
729
|
}
|
|
707
730
|
}, [logSearchResult, scrollToAbsoluteRow]);
|
|
708
731
|
|
|
709
732
|
// 触发搜索
|
|
710
733
|
var handleSearch = useCallback( /*#__PURE__*/function () {
|
|
711
|
-
var
|
|
734
|
+
var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(keyword) {
|
|
712
735
|
var targetRow;
|
|
713
|
-
return _regeneratorRuntime().wrap(function
|
|
714
|
-
while (1) switch (
|
|
736
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
737
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
715
738
|
case 0:
|
|
716
|
-
|
|
739
|
+
if (keyword.trim()) {
|
|
740
|
+
searchKeywordActiveRef.current = true;
|
|
741
|
+
}
|
|
742
|
+
_context3.next = 3;
|
|
717
743
|
return logSearchResult.search(keyword);
|
|
718
|
-
case
|
|
719
|
-
targetRow =
|
|
744
|
+
case 3:
|
|
745
|
+
targetRow = _context3.sent;
|
|
720
746
|
if (targetRow !== null) {
|
|
721
747
|
scrollToAbsoluteRow(targetRow);
|
|
722
748
|
}
|
|
723
|
-
case
|
|
749
|
+
case 5:
|
|
724
750
|
case "end":
|
|
725
|
-
return
|
|
751
|
+
return _context3.stop();
|
|
726
752
|
}
|
|
727
|
-
},
|
|
753
|
+
}, _callee3);
|
|
728
754
|
}));
|
|
729
755
|
return function (_x2) {
|
|
730
|
-
return
|
|
756
|
+
return _ref7.apply(this, arguments);
|
|
731
757
|
};
|
|
732
758
|
}(), [logSearchResult, scrollToAbsoluteRow]);
|
|
733
759
|
|
|
@@ -809,24 +835,24 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
809
835
|
airdropExpandInFlightRef.current = true;
|
|
810
836
|
setLoadingGroupName(name);
|
|
811
837
|
var runAirdropThenExpand = /*#__PURE__*/function () {
|
|
812
|
-
var
|
|
838
|
+
var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
813
839
|
var ok;
|
|
814
|
-
return _regeneratorRuntime().wrap(function
|
|
815
|
-
while (1) switch (
|
|
840
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
841
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
816
842
|
case 0:
|
|
817
|
-
|
|
818
|
-
|
|
843
|
+
_context4.prev = 0;
|
|
844
|
+
_context4.next = 3;
|
|
819
845
|
return logFetcherResult.airdropLoad(group.start, {
|
|
820
846
|
window: 'fromStart',
|
|
821
847
|
silent: true
|
|
822
848
|
});
|
|
823
849
|
case 3:
|
|
824
|
-
ok =
|
|
850
|
+
ok = _context4.sent;
|
|
825
851
|
if (!ok) {
|
|
826
|
-
|
|
852
|
+
_context4.next = 7;
|
|
827
853
|
break;
|
|
828
854
|
}
|
|
829
|
-
|
|
855
|
+
_context4.next = 7;
|
|
830
856
|
return new Promise(function (resolve) {
|
|
831
857
|
requestAnimationFrame(function () {
|
|
832
858
|
requestAnimationFrame(function () {
|
|
@@ -838,18 +864,18 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
838
864
|
});
|
|
839
865
|
});
|
|
840
866
|
case 7:
|
|
841
|
-
|
|
867
|
+
_context4.prev = 7;
|
|
842
868
|
setLoadingGroupName(null);
|
|
843
869
|
airdropExpandInFlightRef.current = false;
|
|
844
|
-
return
|
|
870
|
+
return _context4.finish(7);
|
|
845
871
|
case 11:
|
|
846
872
|
case "end":
|
|
847
|
-
return
|
|
873
|
+
return _context4.stop();
|
|
848
874
|
}
|
|
849
|
-
},
|
|
875
|
+
}, _callee4, null, [[0,, 7, 11]]);
|
|
850
876
|
}));
|
|
851
877
|
return function runAirdropThenExpand() {
|
|
852
|
-
return
|
|
878
|
+
return _ref8.apply(this, arguments);
|
|
853
879
|
};
|
|
854
880
|
}();
|
|
855
881
|
runAirdropThenExpand();
|
|
@@ -1037,10 +1063,10 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1037
1063
|
useImperativeHandle(ref, function () {
|
|
1038
1064
|
return {
|
|
1039
1065
|
scrollToTop: function () {
|
|
1040
|
-
var _scrollToTop = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function
|
|
1041
|
-
var globalFirstRow, bufStart, needsTopWindow;
|
|
1042
|
-
return _regeneratorRuntime().wrap(function
|
|
1043
|
-
while (1) switch (
|
|
1066
|
+
var _scrollToTop = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
|
|
1067
|
+
var globalFirstRow, bufStart, needsTopWindow, ok;
|
|
1068
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
1069
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
1044
1070
|
case 0:
|
|
1045
1071
|
groupManager.expandAll();
|
|
1046
1072
|
userStoppedFollowingRef.current = true;
|
|
@@ -1053,23 +1079,34 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1053
1079
|
}))) : 0;
|
|
1054
1080
|
bufStart = logFetcherResult.cursor.currentStartRow;
|
|
1055
1081
|
needsTopWindow = bufStart > globalFirstRow;
|
|
1082
|
+
ignoreBoundaryFetchRef.current = Date.now() + 500;
|
|
1056
1083
|
if (!needsTopWindow) {
|
|
1057
|
-
|
|
1084
|
+
_context5.next = 19;
|
|
1058
1085
|
break;
|
|
1059
1086
|
}
|
|
1060
|
-
|
|
1087
|
+
// airdropLoad 完成时 React 尚未提交新 displayLogs,单帧 rAF 里 scrollToIndex(0)
|
|
1088
|
+
// 仍作用在旧列表上(index 0 = 旧缓冲首行),无法置顶;与搜索跨页一致走 pending。
|
|
1089
|
+
pendingScrollAlignRef.current = 'start';
|
|
1090
|
+
pendingScrollRowRef.current = globalFirstRow;
|
|
1091
|
+
_context5.next = 12;
|
|
1061
1092
|
return logFetcherResult.airdropLoad(globalFirstRow, {
|
|
1062
1093
|
window: 'fromStart'
|
|
1063
1094
|
});
|
|
1064
|
-
case
|
|
1095
|
+
case 12:
|
|
1096
|
+
ok = _context5.sent;
|
|
1097
|
+
if (ok) {
|
|
1098
|
+
_context5.next = 17;
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
pendingScrollRowRef.current = null;
|
|
1102
|
+
pendingScrollAlignRef.current = 'center';
|
|
1103
|
+
return _context5.abrupt("return");
|
|
1104
|
+
case 17:
|
|
1065
1105
|
logFetcherResult.updateBoundaryLock({
|
|
1066
1106
|
isLastPage: false
|
|
1067
1107
|
});
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
// 用 pending 机制在 useLayoutEffect 里执行滚动,确保坐标系已稳定。
|
|
1071
|
-
// index: 0 在去掉 firstItemIndex 后永远有效。
|
|
1072
|
-
ignoreBoundaryFetchRef.current = Date.now() + 500;
|
|
1108
|
+
return _context5.abrupt("return");
|
|
1109
|
+
case 19:
|
|
1073
1110
|
requestAnimationFrame(function () {
|
|
1074
1111
|
var _virtuosoRef$current6;
|
|
1075
1112
|
(_virtuosoRef$current6 = virtuosoRef.current) === null || _virtuosoRef$current6 === void 0 || _virtuosoRef$current6.scrollToIndex({
|
|
@@ -1078,11 +1115,11 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1078
1115
|
behavior: 'auto'
|
|
1079
1116
|
});
|
|
1080
1117
|
});
|
|
1081
|
-
case
|
|
1118
|
+
case 20:
|
|
1082
1119
|
case "end":
|
|
1083
|
-
return
|
|
1120
|
+
return _context5.stop();
|
|
1084
1121
|
}
|
|
1085
|
-
},
|
|
1122
|
+
}, _callee5);
|
|
1086
1123
|
}));
|
|
1087
1124
|
function scrollToTop() {
|
|
1088
1125
|
return _scrollToTop.apply(this, arguments);
|
|
@@ -1090,20 +1127,20 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1090
1127
|
return scrollToTop;
|
|
1091
1128
|
}(),
|
|
1092
1129
|
scrollToBottom: function () {
|
|
1093
|
-
var _scrollToBottom = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function
|
|
1130
|
+
var _scrollToBottom = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
|
|
1094
1131
|
var needsFetch;
|
|
1095
|
-
return _regeneratorRuntime().wrap(function
|
|
1096
|
-
while (1) switch (
|
|
1132
|
+
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
1133
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
1097
1134
|
case 0:
|
|
1098
1135
|
groupManager.expandAll();
|
|
1099
1136
|
userStoppedFollowingRef.current = false;
|
|
1100
1137
|
collapseAirdropActiveRef.current = false;
|
|
1101
1138
|
needsFetch = status !== 'running' && !logFetcherResult.boundaryLock.isLastPage || status === 'running' && logFetcherResult.isUserBrowsingHistory;
|
|
1102
1139
|
if (!needsFetch) {
|
|
1103
|
-
|
|
1140
|
+
_context6.next = 8;
|
|
1104
1141
|
break;
|
|
1105
1142
|
}
|
|
1106
|
-
|
|
1143
|
+
_context6.next = 7;
|
|
1107
1144
|
return logFetcherResult.initLoad();
|
|
1108
1145
|
case 7:
|
|
1109
1146
|
logFetcherResult.updateBoundaryLock({
|
|
@@ -1120,9 +1157,9 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1120
1157
|
}, 50);
|
|
1121
1158
|
case 10:
|
|
1122
1159
|
case "end":
|
|
1123
|
-
return
|
|
1160
|
+
return _context6.stop();
|
|
1124
1161
|
}
|
|
1125
|
-
},
|
|
1162
|
+
}, _callee6);
|
|
1126
1163
|
}));
|
|
1127
1164
|
function scrollToBottom() {
|
|
1128
1165
|
return _scrollToBottom.apply(this, arguments);
|
|
@@ -1138,12 +1175,13 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1138
1175
|
};
|
|
1139
1176
|
}, [handleCollapseAll, handleExpandAll, handleSearch, handleSearchPrev, handleSearchNext, logSearchResult, logFetcherResult, groupManager, groups, status]);
|
|
1140
1177
|
var lastGroupStatus = useMemo(function () {
|
|
1141
|
-
return groups.length > 0 ? groups[groups.length - 1].status :
|
|
1142
|
-
}, [groups]);
|
|
1178
|
+
return groups.length > 0 ? groups[groups.length - 1].status : status;
|
|
1179
|
+
}, [groups, status]);
|
|
1143
1180
|
var virtuosoComponents = useMemo(function () {
|
|
1181
|
+
var isRunning = lastGroupStatus === 'running';
|
|
1144
1182
|
return {
|
|
1145
|
-
EmptyPlaceholder: logFetcherResult.loading ? undefined : EmptyPlaceholder,
|
|
1146
|
-
Footer: !logFetcherResult.loading &&
|
|
1183
|
+
EmptyPlaceholder: logFetcherResult.loading || isRunning ? undefined : EmptyPlaceholder,
|
|
1184
|
+
Footer: !logFetcherResult.loading && isRunning ? VirtuosoFooterWithLoading : VirtuosoFooterEmpty
|
|
1147
1185
|
};
|
|
1148
1186
|
}, [lastGroupStatus, logFetcherResult.loading]);
|
|
1149
1187
|
|
|
@@ -1166,7 +1204,8 @@ var PipelineLogViewer = /*#__PURE__*/forwardRef(function (_ref2, ref) {
|
|
|
1166
1204
|
placeholder: searchPlaceholder,
|
|
1167
1205
|
inputAddonBefore: headerAddonBefore,
|
|
1168
1206
|
inputAddonAfter: headerAddonAfter,
|
|
1169
|
-
icons: icons
|
|
1207
|
+
icons: icons,
|
|
1208
|
+
searchLoading: logSearchResult.searching || logSearchResult.searchJumpLoading
|
|
1170
1209
|
}), /*#__PURE__*/React.createElement("div", {
|
|
1171
1210
|
className: "pipeline-log-viewer__list-container"
|
|
1172
1211
|
}, /*#__PURE__*/React.createElement(StickyHeader, {
|
|
@@ -25,6 +25,10 @@ export interface SearchBarProps {
|
|
|
25
25
|
down?: React.ReactNode;
|
|
26
26
|
clear?: React.ReactNode;
|
|
27
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* 搜索请求或跨页拉取匹配行所在日志时,在搜索图标位展示 loading(不阻塞输入)
|
|
30
|
+
*/
|
|
31
|
+
searchLoading?: boolean;
|
|
28
32
|
}
|
|
29
33
|
declare const _default: React.NamedExoticComponent<SearchBarProps>;
|
|
30
34
|
export default _default;
|
|
@@ -17,7 +17,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
17
17
|
// 4. 输入框内容被完全清空或按下 Escape 键时,触发 onClear 清除状态与高亮。
|
|
18
18
|
// ============================================================================
|
|
19
19
|
|
|
20
|
-
import { CloseCircleFilled, DownOutlined, SearchOutlined, UpOutlined } from '@ant-design/icons';
|
|
20
|
+
import { CloseCircleFilled, DownOutlined, LoadingOutlined, SearchOutlined, UpOutlined } from '@ant-design/icons';
|
|
21
21
|
import React, { useCallback, useRef, useState } from 'react';
|
|
22
22
|
var SearchBar = function SearchBar(_ref) {
|
|
23
23
|
var total = _ref.total,
|
|
@@ -30,7 +30,9 @@ var SearchBar = function SearchBar(_ref) {
|
|
|
30
30
|
placeholder = _ref$placeholder === void 0 ? '搜索日志...' : _ref$placeholder,
|
|
31
31
|
inputAddonBefore = _ref.inputAddonBefore,
|
|
32
32
|
inputAddonAfter = _ref.inputAddonAfter,
|
|
33
|
-
icons = _ref.icons
|
|
33
|
+
icons = _ref.icons,
|
|
34
|
+
_ref$searchLoading = _ref.searchLoading,
|
|
35
|
+
searchLoading = _ref$searchLoading === void 0 ? false : _ref$searchLoading;
|
|
34
36
|
var _useState = useState(''),
|
|
35
37
|
_useState2 = _slicedToArray(_useState, 2),
|
|
36
38
|
inputValue = _useState2[0],
|
|
@@ -85,17 +87,29 @@ var SearchBar = function SearchBar(_ref) {
|
|
|
85
87
|
onClear();
|
|
86
88
|
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus();
|
|
87
89
|
}, [onClear]);
|
|
90
|
+
var searchPrefixIcon;
|
|
91
|
+
if (searchLoading) {
|
|
92
|
+
searchPrefixIcon = /*#__PURE__*/React.createElement(LoadingOutlined, {
|
|
93
|
+
className: "pipeline-log-search-bar__search-icon",
|
|
94
|
+
spin: true
|
|
95
|
+
});
|
|
96
|
+
} else if ( /*#__PURE__*/React.isValidElement(icons === null || icons === void 0 ? void 0 : icons.search)) {
|
|
97
|
+
searchPrefixIcon = /*#__PURE__*/React.cloneElement(icons === null || icons === void 0 ? void 0 : icons.search, {
|
|
98
|
+
className: 'pipeline-log-search-bar__search-icon'
|
|
99
|
+
});
|
|
100
|
+
} else {
|
|
101
|
+
searchPrefixIcon = /*#__PURE__*/React.createElement(SearchOutlined, {
|
|
102
|
+
className: "pipeline-log-search-bar__search-icon"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
88
105
|
return /*#__PURE__*/React.createElement("div", {
|
|
89
106
|
className: "pipeline-log-search-bar"
|
|
90
107
|
}, /*#__PURE__*/React.createElement("div", {
|
|
91
108
|
className: "pipeline-log-search-bar__input-prefix"
|
|
92
109
|
}, inputAddonBefore), /*#__PURE__*/React.createElement("div", {
|
|
93
|
-
className: "pipeline-log-search-bar__input-wrapper"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
})) : /*#__PURE__*/React.createElement(SearchOutlined, {
|
|
97
|
-
className: "pipeline-log-search-bar__search-icon"
|
|
98
|
-
}), /*#__PURE__*/React.createElement("input", {
|
|
110
|
+
className: "pipeline-log-search-bar__input-wrapper",
|
|
111
|
+
"aria-busy": searchLoading || undefined
|
|
112
|
+
}, searchPrefixIcon, /*#__PURE__*/React.createElement("input", {
|
|
99
113
|
ref: inputRef,
|
|
100
114
|
className: "pipeline-log-search-bar__input",
|
|
101
115
|
type: "text",
|
|
@@ -12,6 +12,10 @@ export declare const DEFAULT_VIRTUOSO_ITEM_HEIGHT = 20;
|
|
|
12
12
|
export declare const BOUNDARY_PREFETCH_INDEX_MARGIN = 400;
|
|
13
13
|
/** running 态轮询间隔 (默认值,单位 ms) */
|
|
14
14
|
export declare const DEFAULT_POLL_INTERVAL = 1000;
|
|
15
|
+
/** running→结束态:收尾 initLoad 之后追加 loadNext 的次数 */
|
|
16
|
+
export declare const TERMINAL_TAIL_LOAD_NEXT_COUNT = 5;
|
|
17
|
+
/** 收尾追加 loadNext 每次之间的间隔 (ms) */
|
|
18
|
+
export declare const TERMINAL_TAIL_LOAD_NEXT_INTERVAL_MS = 1000;
|
|
15
19
|
/** 空降加载时,取目标行前后各加载多少行 */
|
|
16
20
|
export declare const AIRDROP_HALF_RANGE = 250;
|
|
17
21
|
/** 折叠占位行标记文本 */
|