@lesliechan721/aw 0.1.0-beta.32 → 0.1.0-beta.34
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/src/tui/clipboard.d.ts +13 -0
- package/dist/src/tui/clipboard.js +95 -0
- package/dist/src/tui/clipboard.js.map +1 -0
- package/dist/src/tui/components.d.ts +20 -0
- package/dist/src/tui/components.js +62 -17
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.js +431 -367
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +5 -0
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +4 -1
- package/dist/src/tui/controller.js +86 -28
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/model.d.ts +2 -1
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +1 -0
- package/dist/src/tui/operation-diagnostic-screens.js +5 -0
- package/dist/src/tui/operation-diagnostic-screens.js.map +1 -1
- package/dist/src/tui/router.d.ts +1 -1
- package/dist/src/tui/screen-registry.d.ts +3 -3
- package/package.json +3 -3
|
@@ -12,12 +12,13 @@ import { normalizePortableAgents, SKILLS_CLI_SUPPORTED_VERSION_LABEL, } from '..
|
|
|
12
12
|
import { selectLifecycleRetryAction, } from '../commands/operation-planner.js';
|
|
13
13
|
import { parseScriptTimeoutMs, SCRIPT_TIMEOUT_DEFAULT_MS, SCRIPT_TIMEOUT_MAX_MS, SCRIPT_TIMEOUT_MIN_MS, } from '../commands/options.js';
|
|
14
14
|
import { projectCatalogSourceLocation } from '../utils/catalog-source-presentation.js';
|
|
15
|
-
import { ActionRow, ObjectCardRow, objectCardRowLayout, StatusBadge, diagnosticDetailLines, Callout, ChoiceRow, ContentViewport, DiagnosticSummary, InputCard, PluginListRow, ProgressRow, ResultCard, ResultRow, ReviewCard, ReviewChangeRow, ScreenFrame, SectionCard, SectionRow, StaticRow, StatusCard, TaskRow, TechnicalDetails, ToggleRow, } from './components.js';
|
|
15
|
+
import { ActionRow, ObjectCardRow, objectCardRowLayout, pluginListRowLayout, StatusBadge, diagnosticDetailLines, diagnosticDetailText, Callout, ChoiceRow, ContentViewport, DiagnosticSummary, InputCard, PluginListRow, ProgressRow, ResultCard, ResultRow, ReviewCard, ReviewChangeRow, ScreenFrame, SectionCard, SectionRow, StaticRow, StatusCard, TaskRow, TechnicalDetails, ToggleRow, } from './components.js';
|
|
16
16
|
import { safeDiagnosticCode, sanitizeDiagnosticText, } from './diagnostics.js';
|
|
17
17
|
import { extractPortableError, TuiConfigInvalidStoreError, userIssueKey, } from './controller.js';
|
|
18
18
|
import { pluginWriteTaskVersionEvidence } from './plugin-write-task.js';
|
|
19
19
|
import { catalogSourceFreshnessLabel, catalogSourceListPresentation, } from './catalog-sources/screens.js';
|
|
20
|
-
import { operationDiagnosticLineCount, operationHistoryMeta, operationHistoryState, operationReportLineCount, OperationDiagnosticScreen, OperationReportPreviewScreen, } from './operation-diagnostic-screens.js';
|
|
20
|
+
import { operationDiagnosticLineCount, operationDiagnosticText, operationHistoryMeta, operationHistoryState, operationReportLineCount, OperationDiagnosticScreen, OperationReportPreviewScreen, } from './operation-diagnostic-screens.js';
|
|
21
|
+
import { copyToClipboard } from './clipboard.js';
|
|
21
22
|
import { resolveTuiSizePolicy } from './layout.js';
|
|
22
23
|
import { buildDependencyGraphProjection, buildUnifiedDependencyGraphProjection, } from './dependency-graph.js';
|
|
23
24
|
import { platformLabel, scopeLabel } from './glossary.js';
|
|
@@ -41,22 +42,6 @@ function pluginFilterLabel(filter) {
|
|
|
41
42
|
attention: '需处理',
|
|
42
43
|
}[filter];
|
|
43
44
|
}
|
|
44
|
-
function paginationActions(options) {
|
|
45
|
-
return [
|
|
46
|
-
{
|
|
47
|
-
actionId: 'pagination-previous',
|
|
48
|
-
label: 'p 上一页',
|
|
49
|
-
disabled: options.offset <= 0 ? '已在第一页' : undefined,
|
|
50
|
-
run: () => options.move(-1),
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
actionId: 'pagination-next',
|
|
54
|
-
label: 'n 下一页',
|
|
55
|
-
disabled: options.offset + options.pageRows >= options.total ? '已在最后一页' : undefined,
|
|
56
|
-
run: () => options.move(1),
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
45
|
function sourceOperationBlockLabel(reason) {
|
|
61
46
|
switch (reason) {
|
|
62
47
|
case 'configDraft': return '未保存的插件设置';
|
|
@@ -306,12 +291,16 @@ function pluginUpdateDescription(plugin) {
|
|
|
306
291
|
}
|
|
307
292
|
return '当前启用目录已验证;可直接进入更新确认。';
|
|
308
293
|
}
|
|
294
|
+
function pluginPlatformUnknown(plugin, platform) {
|
|
295
|
+
const placements = plugin.installedPlacements.filter((entry) => entry.platform === platform);
|
|
296
|
+
return plugin.sourceUnavailable || placements.length === 0
|
|
297
|
+
|| placements.some((entry) => entry.state === 'installed' && entry.sharedNative?.state === 'unobserved');
|
|
298
|
+
}
|
|
309
299
|
function pluginPlatformBadges(plugin) {
|
|
310
300
|
const items = plugin.supportedPlatforms.map((platform) => {
|
|
311
301
|
const placements = plugin.installedPlacements.filter((entry) => entry.platform === platform);
|
|
312
302
|
const installed = placements.some((entry) => entry.state === 'installed' || entry.state === 'scopeConflict');
|
|
313
|
-
const unknown = plugin
|
|
314
|
-
|| placements.some((entry) => entry.state === 'installed' && entry.sharedNative?.state === 'unobserved');
|
|
303
|
+
const unknown = pluginPlatformUnknown(plugin, platform);
|
|
315
304
|
const attention = placements.some((entry) => entry.state === 'blocked' || entry.state === 'scopeConflict'
|
|
316
305
|
|| entry.state === 'installed' && (entry.health !== 'ready' || entry.blockingReason !== undefined));
|
|
317
306
|
const update = plugin.update.targets.some((target) => target.platform === platform
|
|
@@ -469,6 +458,16 @@ function changeDetailLines(changes, columns) {
|
|
|
469
458
|
...(change.children ?? []).flatMap((child) => [child.property, ...valueLines('修改前', child.before), ...valueLines('修改后', child.after)]),
|
|
470
459
|
]);
|
|
471
460
|
}
|
|
461
|
+
function changeDetailText(changes) {
|
|
462
|
+
return changes.flatMap((change) => [
|
|
463
|
+
`修改项 · ${change.title}`,
|
|
464
|
+
`修改前\n ${change.before ?? '未设置'}`,
|
|
465
|
+
`修改后\n ${change.after ?? '未设置'}`,
|
|
466
|
+
...(change.children ?? []).flatMap((child) => [
|
|
467
|
+
child.property, `修改前\n ${child.before}`, `修改后\n ${child.after}`,
|
|
468
|
+
]),
|
|
469
|
+
]).join('\n');
|
|
470
|
+
}
|
|
472
471
|
function operationRiskWarnings(review) {
|
|
473
472
|
return [...new Set([
|
|
474
473
|
...(review.sharedImpact.warning ? [review.sharedImpact.warning] : []),
|
|
@@ -869,7 +868,7 @@ function SemanticRows(props) {
|
|
|
869
868
|
compact: props.compact,
|
|
870
869
|
};
|
|
871
870
|
if (props.cards)
|
|
872
|
-
return _jsx(ObjectCardRow, { width: props.columns ?? 58, title: action.label, description: action.disabled ?? action.description ?? '', meta: action.meta, tags: action.tags, focused: index === props.focus, compact: props.compact }, `${action.label}:${index}`);
|
|
871
|
+
return _jsx(ObjectCardRow, { width: props.columns ?? 58, title: action.label, description: action.disabled ?? action.description ?? '', meta: action.meta, sourceLabel: action.sourceLabel, maxDescriptionRows: action.maxDescriptionRows, tags: action.tags, focused: index === props.focus, compact: props.compact }, `${action.label}:${index}`);
|
|
873
872
|
if (props.kind === 'section')
|
|
874
873
|
return _jsx(SectionRow, { ...rowProps }, `${action.label}:${index}`);
|
|
875
874
|
if (props.kind === 'choice') {
|
|
@@ -892,7 +891,8 @@ function SequenceRows(props) {
|
|
|
892
891
|
rowHeights: props.actions.map((action, index) => action.role === 'navigation' ? 0 : index < props.itemCount
|
|
893
892
|
? props.wrapValues ? configLines(action).length : props.cards ? objectCardRowLayout({
|
|
894
893
|
width: props.columns, description: action.disabled ?? action.description ?? '',
|
|
895
|
-
meta: action.meta,
|
|
894
|
+
meta: action.meta, sourceLabel: action.sourceLabel, maxDescriptionRows: action.maxDescriptionRows,
|
|
895
|
+
hasTags: action.tags !== undefined, compact: props.compact,
|
|
896
896
|
}).height : action.description ? 2 : 1
|
|
897
897
|
: 1),
|
|
898
898
|
focus: props.focus, requestedOffset: props.scrollOffset, rowBudget: props.rowBudget,
|
|
@@ -905,13 +905,13 @@ function SequenceRows(props) {
|
|
|
905
905
|
if (index < props.itemCount && props.wrapValues)
|
|
906
906
|
return _jsx(Box, { flexDirection: "column", children: configLines(action).map((line, lineIndex) => _jsxs(Text, { bold: focused && lineIndex === 0, color: action.status === 'error' ? 'red' : undefined, children: [lineIndex === 0 ? focused ? '› ' : ' ' : ' ', line] }, lineIndex)) }, action.configKey ?? action.label);
|
|
907
907
|
return index < props.itemCount && props.cards
|
|
908
|
-
? _jsx(ObjectCardRow, { width: props.columns, title: `${action.selected === undefined ? '' : action.selected ? '[x] ' : '[ ] '}${action.label}`, description: action.disabled ?? action.description ?? '', meta: action.meta, tags: action.tags, focused: focused, compact: props.compact }, action.actionId ?? action.pluginId ?? action.label)
|
|
908
|
+
? _jsx(ObjectCardRow, { width: props.columns, title: `${action.selected === undefined ? '' : action.selected ? '[x] ' : '[ ] '}${action.label}`, description: action.disabled ?? action.description ?? '', meta: action.meta, sourceLabel: action.sourceLabel, maxDescriptionRows: action.maxDescriptionRows, tags: action.tags, focused: focused, compact: props.compact }, action.actionId ?? action.pluginId ?? action.label)
|
|
909
909
|
: _jsx(SemanticRows, { actions: [action], focus: focused ? 0 : -1, kind: index < props.itemCount ? 'section' : 'action', compact: index >= props.itemCount }, action.actionId ?? action.label);
|
|
910
910
|
}) });
|
|
911
911
|
}
|
|
912
912
|
function PluginRows(props) {
|
|
913
913
|
return (_jsx(Box, { flexDirection: "column", children: props.rows.slice(props.viewport.offset, props.viewport.offset + props.viewport.limit)
|
|
914
|
-
.map((row, visibleIndex) => row.menuAction ? (_jsx(TaskRow, { title: row.name, description: row.description, meta: row.statusLabel, status: row.status, focused: props.active && props.viewport.offset + visibleIndex === props.focus, compact: true }, row.pluginId)) : (_jsx(PluginListRow, { name: row.name, sourceLabel: row.sourceLabel, description: row.description, attention: row.attention, placementSummary: row.placementSummary, tags: row.tags, statusLabel: row.statusLabel, status: row.status, focused: props.active && props.viewport.offset + visibleIndex === props.focus, anchored: !props.active && props.viewport.offset + visibleIndex === props.focus }, row.pluginId))) }));
|
|
914
|
+
.map((row, visibleIndex) => row.menuAction ? (_jsx(TaskRow, { title: row.name, description: row.description, meta: row.statusLabel, status: row.status, focused: props.active && props.viewport.offset + visibleIndex === props.focus, compact: true }, row.pluginId)) : (_jsx(PluginListRow, { width: props.columns, name: row.name, sourceLabel: row.sourceLabel, description: row.description, attention: row.attention, placementSummary: row.placementSummary, tags: row.tags, statusLabel: row.statusLabel, status: row.status, focused: props.active && props.viewport.offset + visibleIndex === props.focus, anchored: !props.active && props.viewport.offset + visibleIndex === props.focus }, row.pluginId))) }));
|
|
915
915
|
}
|
|
916
916
|
function IssueTechnicalDetails(props) {
|
|
917
917
|
const visible = props.details.slice(0, props.compact ? 1 : 2);
|
|
@@ -939,7 +939,7 @@ function SourceTabs(props) {
|
|
|
939
939
|
const state = 'state' in tab ? tab.state : 'ready';
|
|
940
940
|
return `${tab.id === props.current ? '[' : ''}${tab.label}${badge(state, tab.count)}${tab.id === props.current ? ']' : ''} `;
|
|
941
941
|
}).join('')}`;
|
|
942
|
-
if (props.compact || terminalTextWidth(fullText) > props.columns) {
|
|
942
|
+
if (props.compact || terminalTextWidth(`${fullText}←→ 切换`) > props.columns) {
|
|
943
943
|
const tab = tabs[index];
|
|
944
944
|
const neighbour = tabs[(index + 1) % tabs.length];
|
|
945
945
|
return _jsxs(Text, { wrap: "truncate-end", children: ["\u6765\u6E90 ", _jsxs(Text, { color: tuiTheme.colors.accent, children: ["[", tab.label, "]"] }), " \u2190\u2192 \u5207\u6362 ", tabs.length > 1 ? neighbour?.label : ''] });
|
|
@@ -951,7 +951,7 @@ function SourceTabs(props) {
|
|
|
951
951
|
: state === 'error' ? tuiTheme.statusColors.error
|
|
952
952
|
: state === 'update' || state === 'recovery' ? tuiTheme.statusColors.warning
|
|
953
953
|
: tuiTheme.colors.muted, children: [active ? '[' : '', tab.label, badge(state, tab.count), active ? ']' : '', ' '] }, tab.id));
|
|
954
|
-
})] }));
|
|
954
|
+
}), "\u2190\u2192 \u5207\u6362"] }));
|
|
955
955
|
}
|
|
956
956
|
function configTabs(page) {
|
|
957
957
|
return [
|
|
@@ -1149,6 +1149,7 @@ export function ConsoleAppV4(props) {
|
|
|
1149
1149
|
const [scope, setScope] = useState('user');
|
|
1150
1150
|
const [selectedTargets, setSelectedTargets] = useState([]);
|
|
1151
1151
|
const [installPlatformScopes, setInstallPlatformScopes] = useState({});
|
|
1152
|
+
const [installPlatformIndex, setInstallPlatformIndex] = useState(0);
|
|
1152
1153
|
const [uninstallTargetKeys, setUninstallTargetKeys] = useState([]);
|
|
1153
1154
|
const [technicalRouteKey, setTechnicalRouteKey] = useState();
|
|
1154
1155
|
const [exitAfterBusy, setExitAfterBusy] = useState(false);
|
|
@@ -1167,9 +1168,11 @@ export function ConsoleAppV4(props) {
|
|
|
1167
1168
|
const [inputError, setInputError] = useState();
|
|
1168
1169
|
const [configActionError, setConfigActionError] = useState();
|
|
1169
1170
|
const [actionError, setActionError] = useState();
|
|
1171
|
+
const [copyFeedback, setCopyFeedback] = useState();
|
|
1170
1172
|
const [configResetAvailability, setConfigResetAvailability] = useState({});
|
|
1171
1173
|
const [sourceDraft, setSourceDraft] = useState();
|
|
1172
1174
|
const [batchDraft, setBatchDraft] = useState();
|
|
1175
|
+
const batchSelectionAnchor = useRef(undefined);
|
|
1173
1176
|
const [batchTargetOffset, setBatchTargetOffset] = useState(0);
|
|
1174
1177
|
const [portableResultDetailOpen, setPortableResultDetailOpen] = useState(false);
|
|
1175
1178
|
const [portableResultDetailOffset, setPortableResultDetailOffset] = useState(0);
|
|
@@ -1966,9 +1969,13 @@ export function ConsoleAppV4(props) {
|
|
|
1966
1969
|
let description = '为 Codex 和 Claude Code 添加、设置或移除开发能力。';
|
|
1967
1970
|
let breadcrumb = '首页';
|
|
1968
1971
|
let context;
|
|
1969
|
-
let help =
|
|
1972
|
+
let help = route.name === 'home'
|
|
1973
|
+
? '↑↓ 移动 · Enter 选择 · ? 帮助 · q 退出'
|
|
1974
|
+
: '↑↓ 移动 · Enter 选择 · Esc 返回 · ? 帮助';
|
|
1970
1975
|
let content;
|
|
1971
1976
|
let actions = [];
|
|
1977
|
+
let readingText;
|
|
1978
|
+
let confirmationText;
|
|
1972
1979
|
let referenceDetailPagination;
|
|
1973
1980
|
let confirmationPagination;
|
|
1974
1981
|
let pluginRows = [];
|
|
@@ -1979,6 +1986,7 @@ export function ConsoleAppV4(props) {
|
|
|
1979
1986
|
let movePluginListSource;
|
|
1980
1987
|
let choosePluginListFilter;
|
|
1981
1988
|
let choosePluginListSource;
|
|
1989
|
+
let returnToPreviousInstallPlatform;
|
|
1982
1990
|
let visibleConfigTabs = [];
|
|
1983
1991
|
let activeConfigTabId;
|
|
1984
1992
|
const dynamicMenu = plugin && route.name === 'platform'
|
|
@@ -2006,7 +2014,8 @@ export function ConsoleAppV4(props) {
|
|
|
2006
2014
|
+ Math.max(0, wrapConsoleText(actionError ?? description ?? '', size.columns - 2).length - 1)
|
|
2007
2015
|
+ Math.max(0, wrapConsoleText(title, size.columns - 2).length - 1),
|
|
2008
2016
|
});
|
|
2009
|
-
const dependencyPlacementStaticRows = policy.mode === 'compact' ? 3 : 10
|
|
2017
|
+
const dependencyPlacementStaticRows = (policy.mode === 'compact' ? 3 : 10)
|
|
2018
|
+
+ (snapshot.installPlacementDraft?.exactRootTargets?.length ?? 0);
|
|
2010
2019
|
const actionViewportStaticRows = route.name === 'dependencyPlacement'
|
|
2011
2020
|
? dependencyPlacementStaticRows
|
|
2012
2021
|
: route.name === 'pluginDetail' ? policy.mode === 'compact' ? 6 : 8
|
|
@@ -2019,7 +2028,8 @@ export function ConsoleAppV4(props) {
|
|
|
2019
2028
|
const base = policy.mode === 'compact' ? compactRows : standardRows;
|
|
2020
2029
|
return base + Math.max(0, size.rows - baseline);
|
|
2021
2030
|
};
|
|
2022
|
-
const operationDetailPageRows =
|
|
2031
|
+
const operationDetailPageRows = responsiveBudget(3, 6);
|
|
2032
|
+
const operationReportPageRows = responsiveBudget(3, 4);
|
|
2023
2033
|
const sourceTechnicalPageRows = Math.max(1, contentRowBudget({
|
|
2024
2034
|
terminalRows: size.rows, description: false, compact: policy.mode === 'compact', staticRows: 6,
|
|
2025
2035
|
}));
|
|
@@ -2100,6 +2110,19 @@ export function ConsoleAppV4(props) {
|
|
|
2100
2110
|
setShowTechnical(false);
|
|
2101
2111
|
setActionError(undefined);
|
|
2102
2112
|
};
|
|
2113
|
+
const closeBatchSelectionTools = () => {
|
|
2114
|
+
if (!batchDraft)
|
|
2115
|
+
return;
|
|
2116
|
+
const candidates = batchCandidates(batchDraft);
|
|
2117
|
+
const anchor = batchSelectionAnchor.current;
|
|
2118
|
+
const retained = anchor?.frameId === snapshot.router.currentFrameId
|
|
2119
|
+
? candidates.findIndex((candidate) => candidate.pluginId === anchor.pluginId) : -1;
|
|
2120
|
+
const nextFocus = retained >= 0 ? retained
|
|
2121
|
+
: Math.min(anchor?.index ?? 0, Math.max(0, candidates.length - 1));
|
|
2122
|
+
setBatchDraft((current) => current ? { ...current, showSelectionTools: false } : current);
|
|
2123
|
+
setFocus(nextFocus);
|
|
2124
|
+
setScrollOffset(Math.min(anchor?.scrollOffset ?? 0, nextFocus));
|
|
2125
|
+
};
|
|
2103
2126
|
const toggleTechnical = () => {
|
|
2104
2127
|
if (portableResultDetailOpen)
|
|
2105
2128
|
setFocus(portableResultDetailReturnFocus.current);
|
|
@@ -3365,23 +3388,26 @@ export function ConsoleAppV4(props) {
|
|
|
3365
3388
|
}] : []),
|
|
3366
3389
|
];
|
|
3367
3390
|
help = showTechnical
|
|
3368
|
-
? '
|
|
3391
|
+
? '←→ 或 PgUp/PgDn 阅读 · d 返回项目位置 · Esc 返回'
|
|
3369
3392
|
: '↑↓ 移动 · Enter 查看 · Esc 返回';
|
|
3370
3393
|
const projectItemCount = showTechnical ? 0 : actions.length;
|
|
3371
3394
|
actions = [...(showTechnical ? [] : actions), ...bottomActions];
|
|
3372
|
-
const
|
|
3395
|
+
const technicalFields = [
|
|
3373
3396
|
...(projectIntentIssue ? [
|
|
3374
3397
|
`项目声明 · ${safeDiagnosticCode(projectIntentIssue.code, 'projectIntentUnavailable')}`,
|
|
3375
|
-
|
|
3398
|
+
`说明 · ${sanitizeDiagnosticText(projectIntentIssue.message)}`,
|
|
3376
3399
|
] : []),
|
|
3377
3400
|
...allTargets.flatMap(({ target, state }) => [
|
|
3378
|
-
|
|
3401
|
+
`${target.pluginId} · ${platformLabel(target.platform)} · ${scopeLabel(target.scope)}`,
|
|
3379
3402
|
...(target.reasonCodes.length > 0
|
|
3380
|
-
? target.reasonCodes.
|
|
3403
|
+
? target.reasonCodes.map((code) => `原因 · ${safeDiagnosticCode(code, 'projectTargetUnknown')}`)
|
|
3381
3404
|
: [state === 'actionable' ? '原因 · confirmedDifference'
|
|
3382
3405
|
: state === 'blocked' ? '原因 · blocked' : '原因 · unconfirmed']),
|
|
3383
3406
|
]),
|
|
3384
3407
|
];
|
|
3408
|
+
const technicalLines = technicalFields.flatMap((field) => wrapConsoleText(field, Math.max(20, size.columns - 8)));
|
|
3409
|
+
if (showTechnical)
|
|
3410
|
+
readingText = technicalFields.join('\n');
|
|
3385
3411
|
if (showTechnical)
|
|
3386
3412
|
description = undefined;
|
|
3387
3413
|
const technicalPageRows = responsiveBudget(4, 8);
|
|
@@ -3598,7 +3624,10 @@ export function ConsoleAppV4(props) {
|
|
|
3598
3624
|
})), ...bottomActions];
|
|
3599
3625
|
const viewport = rowViewport({
|
|
3600
3626
|
rowHeights: actions.map((_, index) => index < pluginRows.length
|
|
3601
|
-
?
|
|
3627
|
+
? pluginListRowLayout({
|
|
3628
|
+
...pluginRows[index], width: size.columns - 2,
|
|
3629
|
+
hasTags: Boolean(pluginRows[index].tags),
|
|
3630
|
+
}).height : 1),
|
|
3602
3631
|
focus, requestedOffset: scrollOffset, rowBudget: pageActionBudget(3),
|
|
3603
3632
|
});
|
|
3604
3633
|
content = (_jsxs(Box, { flexDirection: "column", children: [_jsx(SourceTabs, { controller: props.controller, current: sourceId, compact: policy.mode === 'compact', columns: size.columns - 2, mode: route.mode, query: query || undefined, installFilter: installFilter }), _jsxs(Text, { color: searchFocus ? tuiTheme.colors.accent : tuiTheme.colors.muted, children: ["\u641C\u7D22 [/] ", searchFocus
|
|
@@ -3609,7 +3638,7 @@ export function ConsoleAppV4(props) {
|
|
|
3609
3638
|
? installFilter === 'updateAvailable'
|
|
3610
3639
|
? _jsx(Callout, { title: "\u6CA1\u6709\u53EF\u66F4\u65B0\u63D2\u4EF6", description: "\u5F53\u524D\u7B5B\u9009\u8303\u56F4\u5185\u6CA1\u6709\u7ECF\u8FC7\u7248\u672C\u8BC1\u636E\u786E\u8BA4\u7684\u66F4\u65B0\u3002" })
|
|
3611
3640
|
: _jsx(Callout, { title: "\u5F00\u59CB\u6DFB\u52A0\u7B2C\u4E00\u4E2A\u63D2\u4EF6", description: "\u63D2\u4EF6\u53EF\u4EE5\u5B89\u88C5\u5230 Codex\u3001Claude Code \u6216\u4E24\u8005\u3002" })
|
|
3612
|
-
: null, _jsxs(ContentViewport, { children: [_jsx(PluginRows, { rows: pluginRows, focus: focus, viewport: viewport, active: !searchFocus }), _jsx(SemanticRows, { actions: actions, focus: searchFocus ? -1 : focus, kind: "action", compact: true, offset: Math.max(pluginRows.length, viewport.offset), limit: Math.max(0, viewport.offset + viewport.limit - Math.max(pluginRows.length, viewport.offset)) })] })] }));
|
|
3641
|
+
: null, _jsxs(ContentViewport, { children: [_jsx(PluginRows, { columns: size.columns - 2, rows: pluginRows, focus: focus, viewport: viewport, active: !searchFocus }), _jsx(SemanticRows, { actions: actions, focus: searchFocus ? -1 : focus, kind: "action", compact: true, offset: Math.max(pluginRows.length, viewport.offset), limit: Math.max(0, viewport.offset + viewport.limit - Math.max(pluginRows.length, viewport.offset)) })] })] }));
|
|
3613
3642
|
}
|
|
3614
3643
|
else if (route.name === 'batchSelection') {
|
|
3615
3644
|
breadcrumb = '插件 / 选择多个';
|
|
@@ -3636,8 +3665,10 @@ export function ConsoleAppV4(props) {
|
|
|
3636
3665
|
const plugin = candidate.plugin;
|
|
3637
3666
|
return {
|
|
3638
3667
|
label: plugin
|
|
3639
|
-
?
|
|
3668
|
+
? plugin.displayName
|
|
3640
3669
|
: `${candidate.pluginId}(已不可用,可取消选择)`,
|
|
3670
|
+
sourceLabel: plugin?.sourceLabel,
|
|
3671
|
+
maxDescriptionRows: 2,
|
|
3641
3672
|
description: plugin
|
|
3642
3673
|
? `${plugin.description} · ${blockReason
|
|
3643
3674
|
? `${isSelected ? '可取消选择' : '不可选择'}:${blockReason}`
|
|
@@ -3673,9 +3704,11 @@ export function ConsoleAppV4(props) {
|
|
|
3673
3704
|
}
|
|
3674
3705
|
moveBatchStage('task');
|
|
3675
3706
|
};
|
|
3707
|
+
const continueLabel = batchDraft.recommendedGoal === 'update' ? '查看升级汇总'
|
|
3708
|
+
: batchDraft.recommendedGoal ? '查看恢复汇总' : '继续选择任务';
|
|
3676
3709
|
const continueAction = {
|
|
3677
3710
|
actionId: 'batch-selection-continue',
|
|
3678
|
-
label:
|
|
3711
|
+
label: `${continueLabel}(${batchDraft.selectedPluginIds.length}) [c]`,
|
|
3679
3712
|
description: batchDraft.selectedPluginIds.length > 0
|
|
3680
3713
|
? batchDraft.recommendedGoal ? '重新读取更新信息并显示操作汇总' : '继续选择任务和确认范围'
|
|
3681
3714
|
: '先选择至少一个插件',
|
|
@@ -3699,11 +3732,7 @@ export function ConsoleAppV4(props) {
|
|
|
3699
3732
|
{
|
|
3700
3733
|
role: 'navigation', label: '返回插件选择',
|
|
3701
3734
|
description: '保留当前已选插件',
|
|
3702
|
-
run:
|
|
3703
|
-
setBatchDraft((current) => current ? { ...current, showSelectionTools: false } : current);
|
|
3704
|
-
setFocus(0);
|
|
3705
|
-
setScrollOffset(0);
|
|
3706
|
-
},
|
|
3735
|
+
run: closeBatchSelectionTools,
|
|
3707
3736
|
},
|
|
3708
3737
|
{
|
|
3709
3738
|
label: '全选当前结果',
|
|
@@ -3731,10 +3760,11 @@ export function ConsoleAppV4(props) {
|
|
|
3731
3760
|
label: batchDraft.showSelectionTools ? '返回插件选择' : '选择工具',
|
|
3732
3761
|
description: '全选、取消当前结果或清空全部选择',
|
|
3733
3762
|
run: () => {
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
}
|
|
3763
|
+
if (batchDraft.showSelectionTools) {
|
|
3764
|
+
closeBatchSelectionTools();
|
|
3765
|
+
return;
|
|
3766
|
+
}
|
|
3767
|
+
setBatchDraft((current) => current ? { ...current, showSelectionTools: true } : current);
|
|
3738
3768
|
setFocus(0);
|
|
3739
3769
|
setScrollOffset(0);
|
|
3740
3770
|
},
|
|
@@ -3748,7 +3778,7 @@ export function ConsoleAppV4(props) {
|
|
|
3748
3778
|
: '↑↓ 移动 · Space 选择 · Enter 查看 · Esc 返回';
|
|
3749
3779
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SourceTabs, { controller: props.controller, current: batchDraft.showSelected ? 'all' : batchDraft.sourceId ?? 'all', compact: policy.mode === 'compact', columns: size.columns - 2, mode: batchDraft.mode, query: batchDraft.showSelected ? undefined : batchDraft.query || undefined, installFilter: batchDraft.showSelected ? 'all' : batchDraft.installFilter }), _jsxs(Text, { color: searchFocus ? tuiTheme.colors.accent : tuiTheme.colors.muted, children: ["\u641C\u7D22 [/] ", searchFocus
|
|
3750
3780
|
? _jsx(InputDisplay, { value: batchDraft.query, cursor: searchCursor, placeholder: "\u8F93\u5165\u641C\u7D22\u5185\u5BB9", columns: Math.max(8, size.columns - 14) })
|
|
3751
|
-
: _jsxs(_Fragment, { children: [batchDraft.query || '输入名称或用途', batchDraft.query ? ' / 编辑' : ''] })] }), _jsxs(Text, { color: tuiTheme.colors.muted, children: ["\u72B6\u6001 ", _jsxs(Text, { color: tuiTheme.colors.accent, children: ["[", pluginFilterLabel(batchDraft.installFilter), "]"] }), " [f] \u5207\u6362"] }), _jsxs(Text, { color: tuiTheme.colors.muted, children: ["\u5DF2\u9009 ", selected.size, " \u00B7 \u9690\u85CF\u5DF2\u9009 ", hiddenSelected, " [c]
|
|
3781
|
+
: _jsxs(_Fragment, { children: [batchDraft.query || '输入名称或用途', batchDraft.query ? ' / 编辑' : ''] })] }), _jsxs(Text, { color: tuiTheme.colors.muted, children: ["\u72B6\u6001 ", _jsxs(Text, { color: tuiTheme.colors.accent, children: ["[", pluginFilterLabel(batchDraft.installFilter), "]"] }), " [f] \u5207\u6362"] }), _jsxs(Text, { color: tuiTheme.colors.muted, children: ["\u5DF2\u9009 ", selected.size, " \u00B7 \u9690\u85CF\u5DF2\u9009 ", hiddenSelected, " [c] ", continueLabel] }), _jsx(SequenceRows, { actions: actions, itemCount: batchDraft.showSelectionTools ? 0 : candidateActions.length, focus: batchFocus, scrollOffset: scrollOffset, columns: size.columns - 2, rowBudget: pageActionBudget(4), compact: policy.mode === 'compact', cards: true, inactive: searchFocus })] });
|
|
3752
3782
|
}
|
|
3753
3783
|
else {
|
|
3754
3784
|
const selectedIds = batchDraft.selectedPluginIds;
|
|
@@ -4224,13 +4254,14 @@ export function ConsoleAppV4(props) {
|
|
|
4224
4254
|
{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() },
|
|
4225
4255
|
];
|
|
4226
4256
|
const dependencies = overview?.dependencies ?? [];
|
|
4257
|
+
readingText = [plugin.displayName, ...dependencies.map((entry) => `${entry.displayName} · ${entry.pluginId} · ${entry.relation === 'direct' ? '直接依赖' : '间接依赖'} · ${entry.requiredBy.map((parent) => parent.displayName).join('、')} 需要它`)].join('\n');
|
|
4227
4258
|
const dependencyLimit = showTechnical ? 1 : responsiveBudget(2, 3);
|
|
4228
4259
|
const dependencyOffset = Math.min(batchTargetOffset, Math.max(0, dependencies.length - dependencyLimit));
|
|
4229
4260
|
const visibleDependencies = dependencies.slice(dependencyOffset, dependencyOffset + dependencyLimit);
|
|
4230
4261
|
const technicalDependencies = dependencies.slice(dependencyOffset, dependencyOffset + 1);
|
|
4231
4262
|
const compactTechnicalSummary = policy.mode === 'compact' && showTechnical;
|
|
4232
4263
|
help = dependencies.length > dependencyLimit
|
|
4233
|
-
? '↑↓ 移动 · PageUp/PageDown 或
|
|
4264
|
+
? '↑↓ 移动 · PageUp/PageDown 或 ←→ 阅读依赖 · Enter 选择 · Esc 返回'
|
|
4234
4265
|
: '↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4235
4266
|
content = _jsxs(Box, { flexDirection: "column", children: [compactTechnicalSummary ? _jsxs(SectionCard, { title: "provider \u6458\u8981", meta: `${dependencies.length + 1} 个`, compact: true, children: [_jsx(StaticRow, { title: plugin.displayName, meta: "\u6839 provider", compact: true }), _jsx(StaticRow, { title: `${dependencies.length} 个依赖 providers`, meta: "\u7528\u4E8E\u751F\u6210", compact: true })] }) : _jsx(SectionCard, { title: "\u5F53\u524D\u63D2\u4EF6", children: _jsx(StaticRow, { title: plugin.displayName, description: "\u63D0\u4F9B\u672C\u6B21\u5B89\u88C5\u5165\u53E3", meta: `提供 ${snapshot.portableDraft.candidates.filter((candidate) => candidate.relation === 'requested').length} 个 Skills`, compact: policy.mode === 'compact' }) }), compactTechnicalSummary ? null : _jsxs(SectionCard, { title: "\u4F9D\u8D56\u63D2\u4EF6", meta: `${dependencies.length} 个`, children: [dependencyOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${dependencyOffset} 个依赖插件`, status: "muted", compact: true }) : null, visibleDependencies.map((dependency) => _jsx(StaticRow, { title: dependency.displayName, description: `${dependency.relation === 'direct' ? '当前插件直接需要' : '由依赖插件继续需要'} · ${dependency.requiredBy.map((entry) => entry.displayName).join('、')} 需要它`, meta: `提供 ${snapshot.portableDraft.candidates.filter((candidate) => candidate.providerPluginId === dependency.pluginId).length} 个 Skills`, compact: policy.mode === 'compact' }, dependency.pluginId)), dependencies.length > dependencyOffset + visibleDependencies.length ? _jsx(StaticRow, { title: `↓ 后面还有 ${dependencies.length - dependencyOffset - visibleDependencies.length} 个依赖插件`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true }), showTechnical ? _jsx(TechnicalDetails, { children: technicalDependencies.map((entry) => _jsx(StaticRow, { title: entry.displayName, meta: entry.pluginId, compact: true }, entry.pluginId)) }) : null] });
|
|
4236
4267
|
}
|
|
@@ -4308,11 +4339,12 @@ export function ConsoleAppV4(props) {
|
|
|
4308
4339
|
];
|
|
4309
4340
|
const technicalPageRows = responsiveBudget(2, 4);
|
|
4310
4341
|
if (showTechnical && !showPortableRequirements) {
|
|
4342
|
+
readingText = diagnosticDetailText(diagnostic);
|
|
4311
4343
|
referenceDetailPagination = {
|
|
4312
4344
|
total: diagnosticDetailLines(diagnostic, size.columns - 6).length,
|
|
4313
4345
|
pageRows: technicalPageRows,
|
|
4314
4346
|
};
|
|
4315
|
-
help = '
|
|
4347
|
+
help = '←→ 或 PgUp/PgDn 阅读技术字段 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4316
4348
|
}
|
|
4317
4349
|
const blockerActionViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(2, 4));
|
|
4318
4350
|
content = _jsxs(Box, { flexDirection: "column", children: [showPortableRequirements ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u5728 PATH \u4E2D\u63D0\u4F9B\u517C\u5BB9\u7684 skills \u53EF\u6267\u884C\u6587\u4EF6\u3002", compact: true }), _jsx(StaticRow, { title: `当前 AW adapter 支持:${SKILLS_CLI_SUPPORTED_VERSION_LABEL}`, compact: true }), _jsx(StaticRow, { title: "\u51C6\u5907\u5B8C\u6210\u540E\u8FD4\u56DE\u95EE\u9898\u6458\u8981\u5E76\u91CD\u65B0\u68C0\u67E5\u3002", compact: true }), _jsx(StaticRow, { title: "\u4E0D\u4F1A\u81EA\u52A8\u8FD0\u884C npx latest\u3001sudo \u6216\u5728\u7EBF\u5B89\u88C5\u811A\u672C\u3002", status: "warning", compact: true }), _jsx(StaticRow, { title: "\u9009\u5B9A\u63D2\u4EF6\u3001\u5B89\u88C5\u76EE\u6807\u548C Portable \u8349\u7A3F\u4FDD\u6301\u4E0D\u53D8\u3002", status: "success", compact: true }), _jsx(StaticRow, { title: "AW \u4E0D\u4F1A\u5728\u6B64\u9875\u5B89\u88C5\u5916\u90E8\u4F9D\u8D56\u3002", status: "warning", compact: true })] }) : _jsx(DiagnosticSummary, { diagnostic: diagnostic, technical: showTechnical, columns: size.columns, offset: showTechnical ? batchTargetOffset : undefined, limit: showTechnical ? technicalPageRows : undefined, compact: policy.mode === 'compact' }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: blockerActionViewport.offset, limit: blockerActionViewport.limit })] });
|
|
@@ -4334,6 +4366,8 @@ export function ConsoleAppV4(props) {
|
|
|
4334
4366
|
}), entries.length > safeOffset + visible.length ? _jsx(StaticRow, { title: `↓ 后面还有 ${entries.length - safeOffset - visible.length} 项`, status: "muted", compact: true }) : null] });
|
|
4335
4367
|
};
|
|
4336
4368
|
if (route.view === 'removeBlocked') {
|
|
4369
|
+
if (!showTechnical)
|
|
4370
|
+
readingText = visibleDependents.map((entry) => `${entry.displayName} · ${dependencyRelationDescription(entry)} · ${dependentTargetLabel(entry)}`).join('\n');
|
|
4337
4371
|
breadcrumb = `${plugin.displayName} / 移除`;
|
|
4338
4372
|
context = '已阻止';
|
|
4339
4373
|
title = `无法移除 ${plugin.displayName}`;
|
|
@@ -4347,21 +4381,13 @@ export function ConsoleAppV4(props) {
|
|
|
4347
4381
|
{ role: 'navigation', label: '返回插件详情', run: back },
|
|
4348
4382
|
{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() },
|
|
4349
4383
|
];
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
offset: batchTargetOffset,
|
|
4353
|
-
total: visibleDependents.length,
|
|
4354
|
-
pageRows: dependentLimit,
|
|
4355
|
-
move: (direction) => moveBatchTargetPage(visibleDependents.length, dependentLimit, direction),
|
|
4356
|
-
})
|
|
4357
|
-
: [];
|
|
4358
|
-
actions = [...blockedRemovalPagination, ...blockedRemovalActions];
|
|
4359
|
-
if (blockedRemovalPagination.length > 0) {
|
|
4384
|
+
actions = blockedRemovalActions;
|
|
4385
|
+
if (!showTechnical && visibleDependents.length > dependentLimit) {
|
|
4360
4386
|
referenceDetailPagination = { total: visibleDependents.length, pageRows: dependentLimit };
|
|
4361
4387
|
}
|
|
4362
4388
|
const blockedRemovalViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(5));
|
|
4363
4389
|
if (!showTechnical && visibleDependents.length > dependentLimit) {
|
|
4364
|
-
help = '
|
|
4390
|
+
help = '←→ 查看全部被依赖关系 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4365
4391
|
}
|
|
4366
4392
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StaticRow, { title: `${dependentCount} 个已安装插件仍在使用`, status: "error", compact: true }), _jsx(StaticRow, { title: "\u6CA1\u6709\u4FEE\u6539\u4EFB\u4F55\u5B89\u88C5\u3002", status: "muted", compact: true }), showTechnical ? null : _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u4F7F\u7528\u8FD9\u4E2A\u4F9D\u8D56\u7684\u63D2\u4EF6", meta: "\u53CD\u5411\u5F15\u7528", compact: true }), dependencyRows(visibleDependents, dependentLimit, true, batchTargetOffset)] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: blockedRemovalViewport.offset, limit: blockedRemovalViewport.limit }), showTechnical ? _jsx(IssueTechnicalDetails, { details: [{
|
|
4367
4393
|
code: 'dependencyStillRequired',
|
|
@@ -4508,38 +4534,7 @@ export function ConsoleAppV4(props) {
|
|
|
4508
4534
|
meta: '依赖当前可用',
|
|
4509
4535
|
};
|
|
4510
4536
|
});
|
|
4511
|
-
if (route.view === '
|
|
4512
|
-
const detailSections = [
|
|
4513
|
-
['用途', node?.description ?? '当前目录没有用途说明'],
|
|
4514
|
-
['为何需要', description],
|
|
4515
|
-
['影响', state?.value ?? (node ? statusText(node) : '尚未检查当前状态')],
|
|
4516
|
-
];
|
|
4517
|
-
const detailLines = detailSections.flatMap(([label, value]) => [
|
|
4518
|
-
label,
|
|
4519
|
-
...wrapConsoleText(value, Math.max(1, size.columns - 6)).map((line) => ` ${line}`),
|
|
4520
|
-
]);
|
|
4521
|
-
const pageRows = Math.max(1, Math.min(responsiveBudget(5, 10), pageActionBudget(5)));
|
|
4522
|
-
const detailOffset = Math.min(batchTargetOffset, Math.max(0, detailLines.length - 1));
|
|
4523
|
-
const visibleDetailLines = detailLines.slice(detailOffset, detailOffset + pageRows);
|
|
4524
|
-
referenceDetailPagination = { total: detailLines.length, pageRows };
|
|
4525
|
-
breadcrumb = `${plugin.displayName} / 依赖关系 / ${node?.displayName ?? route.nodePluginId} / 完整说明`;
|
|
4526
|
-
context = `${Math.min(detailOffset + 1, detailLines.length)}–${Math.min(detailOffset + visibleDetailLines.length, detailLines.length)} / ${detailLines.length}`;
|
|
4527
|
-
title = `${node?.displayName ?? route.nodePluginId} 的完整说明`;
|
|
4528
|
-
description = '用途、关系原因和当前影响。';
|
|
4529
|
-
help = 'p/n 或 PgUp/PgDn 阅读 · ↑↓ 移动 · Enter 选择 · Esc 返回节点详情';
|
|
4530
|
-
actions = [
|
|
4531
|
-
...paginationActions({
|
|
4532
|
-
offset: detailOffset,
|
|
4533
|
-
total: detailLines.length,
|
|
4534
|
-
pageRows,
|
|
4535
|
-
move: (direction) => moveBatchTargetPage(detailLines.length, pageRows, direction),
|
|
4536
|
-
}),
|
|
4537
|
-
{ role: 'navigation', label: '返回节点详情', run: back },
|
|
4538
|
-
];
|
|
4539
|
-
content = _jsxs(Box, { flexDirection: "column", children: [detailOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${detailOffset} 行`, status: "muted", compact: true }) : null, visibleDetailLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${detailOffset + index}:${line}`)), detailOffset + visibleDetailLines.length < detailLines.length
|
|
4540
|
-
? _jsx(StaticRow, { title: `↓ 后面还有 ${detailLines.length - detailOffset - visibleDetailLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
4541
|
-
}
|
|
4542
|
-
else if (route.view === 'references') {
|
|
4537
|
+
if (route.view === 'references') {
|
|
4543
4538
|
breadcrumb = `${plugin.displayName} / 依赖关系 / ${node?.displayName ?? route.nodePluginId} / 使用位置`;
|
|
4544
4539
|
context = showTechnical ? '技术详情' : '使用位置';
|
|
4545
4540
|
title = `当前可用依赖位置 ${references.length} 个`;
|
|
@@ -4563,6 +4558,15 @@ export function ConsoleAppV4(props) {
|
|
|
4563
4558
|
`dependency · platform=${platformLabel(selectedReference.dependency.platform)} · scope=${selectedReference.dependency.scope}`,
|
|
4564
4559
|
`dependency · project=${selectedReference.dependency.project ?? 'none'}`,
|
|
4565
4560
|
] : [];
|
|
4561
|
+
if (showTechnical && selectedReference)
|
|
4562
|
+
readingText = [
|
|
4563
|
+
`consumer · ${selectedReference.consumer.pluginId}`,
|
|
4564
|
+
`consumer · platform=${platformLabel(selectedReference.consumer.platform)} · scope=${selectedReference.consumer.scope}`,
|
|
4565
|
+
`consumer · project=${selectedReference.consumer.project ?? 'none'}`,
|
|
4566
|
+
`dependency · ${selectedReference.dependency.pluginId}`,
|
|
4567
|
+
`dependency · platform=${platformLabel(selectedReference.dependency.platform)} · scope=${selectedReference.dependency.scope}`,
|
|
4568
|
+
`dependency · project=${selectedReference.dependency.project ?? 'none'}`,
|
|
4569
|
+
].join('\n');
|
|
4566
4570
|
const referenceDetailPageRows = referenceDetailLines.length <= 6
|
|
4567
4571
|
? 6
|
|
4568
4572
|
: responsiveBudget(4, 8);
|
|
@@ -4572,24 +4576,14 @@ export function ConsoleAppV4(props) {
|
|
|
4572
4576
|
total: referenceDetailLines.length,
|
|
4573
4577
|
pageRows: referenceDetailPageRows,
|
|
4574
4578
|
} : undefined;
|
|
4575
|
-
const referencePaginationActions = showTechnical
|
|
4576
|
-
&& referenceDetailLines.length > referenceDetailPageRows
|
|
4577
|
-
? paginationActions({
|
|
4578
|
-
offset: referenceDetailOffset,
|
|
4579
|
-
total: referenceDetailLines.length,
|
|
4580
|
-
pageRows: referenceDetailPageRows,
|
|
4581
|
-
move: (direction) => moveBatchTargetPage(referenceDetailLines.length, referenceDetailPageRows, direction),
|
|
4582
|
-
})
|
|
4583
|
-
: [];
|
|
4584
4579
|
actions = [
|
|
4585
4580
|
...(showTechnical && referenceActions[selectedReferenceIndex]
|
|
4586
4581
|
? [referenceActions[selectedReferenceIndex]] : referenceActions),
|
|
4587
|
-
...referencePaginationActions,
|
|
4588
4582
|
{ role: 'navigation', label: '返回节点详情', run: back },
|
|
4589
4583
|
];
|
|
4590
4584
|
const referenceViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(3, 6));
|
|
4591
4585
|
help = showTechnical
|
|
4592
|
-
? '
|
|
4586
|
+
? '←→ 查看当前位置详情 · ↑↓ 移动 · Enter 选择 · d 隐藏技术详情 · Esc 返回节点详情'
|
|
4593
4587
|
: '↑↓ 查看全部位置 · d 技术详情 · Enter 返回节点详情 · Esc 返回节点详情';
|
|
4594
4588
|
content = _jsxs(Box, { flexDirection: "column", children: [showTechnical ? null
|
|
4595
4589
|
: _jsx(StaticRow, { title: "\u672C\u6B21\u68C0\u67E5", value: "\u53EA\u68C0\u67E5\u5F53\u524D\u9879\u76EE\u548C\u4E2A\u4EBA\u4F4D\u7F6E\uFF1B\u5176\u4ED6\u9879\u76EE\u672A\u68C0\u67E5", status: "muted", compact: true }), showTechnical && referenceDetailOffset > 0
|
|
@@ -4612,20 +4606,33 @@ export function ConsoleAppV4(props) {
|
|
|
4612
4606
|
direction: route.direction,
|
|
4613
4607
|
}),
|
|
4614
4608
|
}] : []),
|
|
4615
|
-
{
|
|
4616
|
-
label: '阅读完整说明',
|
|
4617
|
-
description: '分页查看用途、为何需要和影响',
|
|
4618
|
-
run: () => {
|
|
4619
|
-
setBatchTargetOffset(0);
|
|
4620
|
-
go({ ...route, view: 'details' });
|
|
4621
|
-
},
|
|
4622
|
-
},
|
|
4623
4609
|
{ role: 'navigation', label: '返回关系图', run: back },
|
|
4624
4610
|
];
|
|
4625
|
-
const
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
|
|
4611
|
+
const reason = description;
|
|
4612
|
+
description = undefined;
|
|
4613
|
+
const summary = [
|
|
4614
|
+
`用途:${node?.description ?? '当前目录没有用途说明'}`,
|
|
4615
|
+
`为何需要:${reason}`,
|
|
4616
|
+
`影响:${state?.value ?? (node ? statusText(node) : '尚未检查当前状态')}`,
|
|
4617
|
+
...(showTechnical ? [`pluginId · ${route.nodePluginId}`, `relationship · ${relationship ?? 'unknown'}`] : []),
|
|
4618
|
+
];
|
|
4619
|
+
readingText = [title, ...summary].join('\n');
|
|
4620
|
+
const summaryLines = summary.flatMap((line) => wrapConsoleText(line, size.columns - 2));
|
|
4621
|
+
const actionCount = actions.filter((action) => action.role !== 'navigation').length;
|
|
4622
|
+
const availableSummaryRows = pageActionBudget(Math.min(2, actionCount));
|
|
4623
|
+
const pageRows = Math.max(1, availableSummaryRows - Number(summaryLines.length > availableSummaryRows));
|
|
4624
|
+
const offset = Math.min(batchTargetOffset, Math.max(0, summaryLines.length - pageRows));
|
|
4625
|
+
const visible = summaryLines.slice(offset, offset + pageRows);
|
|
4626
|
+
const paginated = summaryLines.length > pageRows;
|
|
4627
|
+
if (paginated) {
|
|
4628
|
+
referenceDetailPagination = { total: summaryLines.length, pageRows };
|
|
4629
|
+
context = `${offset + 1}–${offset + visible.length} / ${summaryLines.length}`;
|
|
4630
|
+
help = '←→ 翻页 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4631
|
+
}
|
|
4632
|
+
currentActionViewportLineBudget = pageActionBudget(visible.length + Number(paginated));
|
|
4633
|
+
const nodeActionViewport = actionViewport(actions, true, focus, scrollOffset, currentActionViewportLineBudget);
|
|
4634
|
+
content = _jsxs(Box, { flexDirection: "column", children: [visible.map((line, index) => _jsx(Text, { wrap: "truncate-end", children: line }, `${offset + index}`)), paginated ? _jsx(Text, { color: tuiTheme.colors.muted, children: offset + visible.length < summaryLines.length
|
|
4635
|
+
? `↓ 后面还有 ${summaryLines.length - offset - visible.length} 行` : '已到正文末尾' }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: nodeActionViewport.offset, limit: nodeActionViewport.limit })] });
|
|
4629
4636
|
}
|
|
4630
4637
|
}
|
|
4631
4638
|
else if (route.name === 'installTargets' && plugin) {
|
|
@@ -4669,6 +4676,7 @@ export function ConsoleAppV4(props) {
|
|
|
4669
4676
|
}
|
|
4670
4677
|
setDirty(false);
|
|
4671
4678
|
props.controller.setInstallPlatforms(validSelectedTargets);
|
|
4679
|
+
setInstallPlatformIndex(0);
|
|
4672
4680
|
go({ name: 'installPlacement', pluginId: plugin.pluginId });
|
|
4673
4681
|
};
|
|
4674
4682
|
const nativeActions = choices.map((choice) => {
|
|
@@ -4780,35 +4788,53 @@ export function ConsoleAppV4(props) {
|
|
|
4780
4788
|
}
|
|
4781
4789
|
else {
|
|
4782
4790
|
description = '所选平台没有共同范围。请分别确定每个平台的合法位置。';
|
|
4783
|
-
const
|
|
4784
|
-
|
|
4791
|
+
const platformIndex = Math.min(installPlatformIndex, Math.max(0, selectedPlatforms.length - 1));
|
|
4792
|
+
const platform = selectedPlatforms[platformIndex];
|
|
4793
|
+
title = platform ? `${platformLabel(platform)} 的使用范围` : '请返回选择目标平台';
|
|
4794
|
+
context = `平台 ${platformIndex + 1} / ${selectedPlatforms.length}`;
|
|
4795
|
+
if (platformIndex > 0)
|
|
4796
|
+
returnToPreviousInstallPlatform = () => {
|
|
4797
|
+
setInstallPlatformIndex(platformIndex - 1);
|
|
4798
|
+
setFocus(0);
|
|
4799
|
+
setScrollOffset(0);
|
|
4800
|
+
};
|
|
4801
|
+
actions = platform ? legalScopes(platform).map((candidateScope) => ({
|
|
4802
|
+
label: scopeLabel(candidateScope),
|
|
4785
4803
|
selected: installPlatformScopes[platform] === candidateScope,
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
?
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
+
description: platformIndex + 1 < selectedPlatforms.length
|
|
4805
|
+
? `下一步:${platformLabel(selectedPlatforms[platformIndex + 1])} 的使用范围`
|
|
4806
|
+
: '下一步:查看这些精确目标的操作汇总',
|
|
4807
|
+
run: async () => {
|
|
4808
|
+
const nextScopes = { ...installPlatformScopes, [platform]: candidateScope };
|
|
4809
|
+
setInstallPlatformScopes(nextScopes);
|
|
4810
|
+
if (platformIndex + 1 < selectedPlatforms.length) {
|
|
4811
|
+
setInstallPlatformIndex(platformIndex + 1);
|
|
4812
|
+
setFocus(0);
|
|
4813
|
+
setScrollOffset(0);
|
|
4814
|
+
return;
|
|
4815
|
+
}
|
|
4816
|
+
const exactTargets = selectedPlatforms.flatMap((selectedPlatform) => {
|
|
4817
|
+
const selectedScope = nextScopes[selectedPlatform];
|
|
4818
|
+
return selectedScope && legalScopes(selectedPlatform).includes(selectedScope)
|
|
4819
|
+
? [{ pluginId: plugin.pluginId, platform: selectedPlatform, scope: selectedScope }] : [];
|
|
4820
|
+
});
|
|
4821
|
+
if (exactTargets.length !== selectedPlatforms.length) {
|
|
4822
|
+
setInstallPlatformIndex(0);
|
|
4823
|
+
setFocus(0);
|
|
4824
|
+
setScrollOffset(0);
|
|
4825
|
+
setActionError('合法位置已变化。请重新确定每个平台的范围。');
|
|
4826
|
+
return;
|
|
4827
|
+
}
|
|
4828
|
+
props.controller.setInstallRootTargets(exactTargets);
|
|
4829
|
+
if (hasDependencies && await props.controller.prepareInstallDependencyPlacement()) {
|
|
4830
|
+
go({ name: 'dependencyPlacement', pluginId: plugin.pluginId });
|
|
4831
|
+
return;
|
|
4832
|
+
}
|
|
4833
|
+
beginReview(props.controller.installPlacementIntent());
|
|
4804
4834
|
},
|
|
4805
|
-
|
|
4806
|
-
];
|
|
4835
|
+
})) : [];
|
|
4807
4836
|
}
|
|
4808
|
-
|
|
4809
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SemanticRows, { actions: actions, focus: focus, kind: commonScopes.length > 0 ? 'choice' : 'toggle', compact: policy.mode === 'compact', limit: scopeChoiceCount }), commonScopes.length === 0
|
|
4810
|
-
? _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: scopeChoiceCount })
|
|
4811
|
-
: null, hasDependencies ? _jsx(Callout, { title: "\u4F9D\u8D56\u8BA1\u5212", description: "\u6240\u9700\u63D2\u4EF6\u4F1A\u81EA\u52A8\u5B89\u6392\uFF1B\u786E\u8BA4\u524D\u53EF\u67E5\u770B\u5F71\u54CD\u3002" }) : null] });
|
|
4837
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SemanticRows, { actions: actions, focus: focus, kind: "choice", compact: policy.mode === 'compact' }), hasDependencies ? _jsx(Callout, { title: "\u4F9D\u8D56\u8BA1\u5212", description: "\u6240\u9700\u63D2\u4EF6\u4F1A\u81EA\u52A8\u5B89\u6392\uFF1B\u786E\u8BA4\u524D\u53EF\u67E5\u770B\u5F71\u54CD\u3002" }) : null] });
|
|
4812
4838
|
help = '↑↓ 移动 · Enter 选择/继续 · Esc 返回';
|
|
4813
4839
|
}
|
|
4814
4840
|
else if (route.name === 'uninstallTargets' && plugin) {
|
|
@@ -4870,6 +4896,9 @@ export function ConsoleAppV4(props) {
|
|
|
4870
4896
|
else if (route.name === 'dependencyPlacement' && plugin) {
|
|
4871
4897
|
const draft = snapshot.installPlacementDraft?.pluginId === plugin.pluginId
|
|
4872
4898
|
? snapshot.installPlacementDraft : undefined;
|
|
4899
|
+
const rootScopeSummary = draft?.exactRootTargets ? '按平台设置'
|
|
4900
|
+
: draft ? scopeLabel(draft.rootScope) : '未就绪';
|
|
4901
|
+
const exactRootRows = draft?.exactRootTargets?.map((target) => _jsx(StaticRow, { title: `${platformLabel(target.platform)} · ${scopeLabel(target.scope)}`, compact: true }, target.platform));
|
|
4873
4902
|
breadcrumb = `${plugin.displayName} / 添加 / 依赖位置`;
|
|
4874
4903
|
context = '依赖位置';
|
|
4875
4904
|
title = '选择每个平台的依赖位置';
|
|
@@ -4913,8 +4942,8 @@ export function ConsoleAppV4(props) {
|
|
|
4913
4942
|
...(promotedCount > 0 ? [`因依赖自动调整 ${promotedCount} 项`] : []),
|
|
4914
4943
|
].join(';');
|
|
4915
4944
|
content = _jsxs(Box, { flexDirection: "column", children: [policy.mode === 'compact'
|
|
4916
|
-
? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `根插件 · ${plugin.displayName}`, meta:
|
|
4917
|
-
: _jsxs(_Fragment, { children: [
|
|
4945
|
+
? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `根插件 · ${plugin.displayName}`, meta: rootScopeSummary, compact: true }), exactRootRows, _jsx(StaticRow, { title: `位置原因 · ${reasonSummary || '由平台或上游约束固定'}`, status: userCount > 0 ? 'warning' : 'info', compact: true }), _jsx(StaticRow, { title: "\u8303\u56F4\u63D0\u793A \u00B7 \u6240\u6709\u9879\u76EE\u4F4D\u7F6E\u4F1A\u5F71\u54CD\u5176\u4ED6\u9879\u76EE\u548C\u7528\u6237\u73AF\u5883", status: userCount > 0 ? 'warning' : 'muted', compact: true })] })
|
|
4946
|
+
: _jsxs(_Fragment, { children: [_jsxs(SectionCard, { title: "\u6839\u63D2\u4EF6\u4F4D\u7F6E", children: [_jsx(StaticRow, { title: plugin.displayName, meta: rootScopeSummary, compact: true }), exactRootRows] }), _jsx(Callout, { status: userCount > 0 ? 'warning' : 'info', title: userCount > 0 ? `${userCount} 个依赖平台目标使用所有项目位置` : '位置计算原因', description: `${reasonSummary || '依赖位置由平台或上游约束固定'}${userCount > 0 ? ';所有项目位置对其他项目也可见,并会改变你的用户环境' : ''}。` })] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: placementViewport.offset, limit: placementViewport.limit })] });
|
|
4918
4947
|
help = '↑↓ 移动 · Enter 打开/继续 · Esc 返回';
|
|
4919
4948
|
}
|
|
4920
4949
|
else if (route.name === 'dependencyPlacementEditor' && plugin) {
|
|
@@ -5152,6 +5181,18 @@ export function ConsoleAppV4(props) {
|
|
|
5152
5181
|
{ role: 'navigation', label: route.recommendedPluginIds ? '返回调整选择' : '返回插件详情', run: back },
|
|
5153
5182
|
];
|
|
5154
5183
|
const taskTargetLimit = policy.mode === 'compact' ? 3 : 6;
|
|
5184
|
+
readingText = candidates.map((candidate) => {
|
|
5185
|
+
const target = candidate.target;
|
|
5186
|
+
const version = target.expectedUpdate
|
|
5187
|
+
? `${target.expectedUpdate.installedVersion} → ${target.expectedUpdate.activeVersion}`
|
|
5188
|
+
: '保持当前版本';
|
|
5189
|
+
return `${candidate.displayName} · ${candidate.sourceId} · ${platformLabel(target.platform)} · ${scopeLabel(target.scope)} · ${candidate.eligible
|
|
5190
|
+
? pluginWriteTaskMethodLabel(candidate.recommendedMethod)
|
|
5191
|
+
: pluginWriteTaskBlockLabel(candidate.blockReason)} · ${version}`;
|
|
5192
|
+
}).join('\n');
|
|
5193
|
+
if (candidates.length > taskTargetLimit) {
|
|
5194
|
+
referenceDetailPagination = { total: candidates.length, pageRows: taskTargetLimit };
|
|
5195
|
+
}
|
|
5155
5196
|
const taskTargetOffset = Math.min(batchTargetOffset, Math.max(0, candidates.length - 1));
|
|
5156
5197
|
const visibleTaskCandidates = candidates.slice(taskTargetOffset, taskTargetOffset + taskTargetLimit);
|
|
5157
5198
|
const targetRows = visibleTaskCandidates.map((candidate) => {
|
|
@@ -5340,17 +5381,6 @@ export function ConsoleAppV4(props) {
|
|
|
5340
5381
|
...(installAction ? [installAction] : []),
|
|
5341
5382
|
...(settingsAction ? [{ ...settingsAction, actionId: 'settings' }] : []),
|
|
5342
5383
|
...(contentAction ? [contentAction] : []),
|
|
5343
|
-
{
|
|
5344
|
-
actionId: 'full-description',
|
|
5345
|
-
label: '完整基本信息',
|
|
5346
|
-
description: '阅读未截断的用途和平台状态',
|
|
5347
|
-
run: () => {
|
|
5348
|
-
setShowTechnical(true);
|
|
5349
|
-
setBatchTargetOffset(0);
|
|
5350
|
-
setFocus(0);
|
|
5351
|
-
setScrollOffset(0);
|
|
5352
|
-
},
|
|
5353
|
-
},
|
|
5354
5384
|
...(dependencyAction ? [dependencyAction] : []),
|
|
5355
5385
|
...(uninstallAction ? [uninstallAction] : []),
|
|
5356
5386
|
{
|
|
@@ -5364,63 +5394,49 @@ export function ConsoleAppV4(props) {
|
|
|
5364
5394
|
&& dependencyOverviewForDetail.summary.totalCount > 0
|
|
5365
5395
|
? `需要 ${dependencyOverviewForDetail.summary.totalCount} 个插件;当前可用关系按当前范围检查,未显示的关系尚未检查通过。`
|
|
5366
5396
|
: undefined;
|
|
5367
|
-
const
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
const
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
? `${
|
|
5374
|
-
: '
|
|
5397
|
+
const detailPlatforms = [...new Set([
|
|
5398
|
+
...plugin.installedPlacements.map((placement) => placement.platform), ...plugin.supportedPlatforms,
|
|
5399
|
+
])];
|
|
5400
|
+
const detailPositions = detailPlatforms.flatMap((platform) => {
|
|
5401
|
+
const placements = plugin.installedPlacements.filter((placement) => placement.platform === platform && placement.state !== 'notInstalled');
|
|
5402
|
+
return placements.length > 0
|
|
5403
|
+
? placements.map((placement) => `${platformLabel(platform)}:${pluginPlacementConclusions(placement).map((entry) => entry.text).join(' · ')}`)
|
|
5404
|
+
: [`${platformLabel(platform)} · ${pluginPlatformUnknown(plugin, platform) ? '未知 · 尚未确认' : '尚未安装'}`];
|
|
5405
|
+
});
|
|
5406
|
+
const platformSummary = detailPositions.length > 0 ? detailPositions.join(';') : '当前没有可用平台';
|
|
5375
5407
|
context = '插件详情';
|
|
5376
|
-
const
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
...
|
|
5381
|
-
'
|
|
5382
|
-
...(
|
|
5383
|
-
|
|
5384
|
-
|
|
5408
|
+
const summary = [
|
|
5409
|
+
plugin.description,
|
|
5410
|
+
`版本 · ${versionSummary}`,
|
|
5411
|
+
`来源 · ${plugin.sourceLabel}`,
|
|
5412
|
+
...(detailPositions.length > 0 ? detailPositions : [platformSummary]),
|
|
5413
|
+
...(plugin.portableSkills ? ['[Skills 可选]'] : []),
|
|
5414
|
+
...(plugin.configOnly ? ['[已保存设置]'] : []),
|
|
5415
|
+
...(updateDescription ? [`有可用更新 · ${updateDescription}`] : []),
|
|
5416
|
+
...(dependencyDetailText ? [dependencyDetailText] : []),
|
|
5385
5417
|
];
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
help = 'p/n 或 PgUp/PgDn 阅读 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
5409
|
-
content = _jsxs(Box, { flexDirection: "column", children: [descriptionOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${descriptionOffset} 行`, status: "muted", compact: true }) : null, visibleDescriptionLines.map((line, index) => _jsx(StaticRow, { title: line || ' ', compact: true }, `${descriptionOffset + index}:${line}`)), descriptionOffset + visibleDescriptionLines.length < completeDescriptionLines.length
|
|
5410
|
-
? _jsx(StaticRow, { title: `↓ 后面还有 ${completeDescriptionLines.length - descriptionOffset - visibleDescriptionLines.length} 行`, status: "muted", compact: true })
|
|
5411
|
-
: null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: descriptionActionViewport.offset, limit: descriptionActionViewport.limit })] });
|
|
5412
|
-
}
|
|
5413
|
-
else {
|
|
5414
|
-
const detailExtraRows = (updateDescription ? 1 : 0) + (dependencyDetailText ? 1 : 0)
|
|
5415
|
-
+ (snapshot.completionNotice?.pluginId === plugin.pluginId ? 4 : 0);
|
|
5416
|
-
currentActionViewportLineBudget = pageActionBudget(detailExtraRows + 4 + Number(Boolean(plugin.portableSkills)) + Number(Boolean(plugin.configOnly)));
|
|
5417
|
-
const detailViewport = actionViewport(actions, true, focus, scrollOffset, currentActionViewportLineBudget);
|
|
5418
|
-
content = _jsxs(Box, { flexDirection: "column", children: [snapshot.completionNotice?.pluginId === plugin.pluginId
|
|
5419
|
-
? _jsx(Callout, { status: "success", title: snapshot.completionNotice.title, description: snapshot.completionNotice.description })
|
|
5420
|
-
: null, _jsx(StaticRow, { title: plugin.description, compact: true }), _jsx(StaticRow, { title: `版本 · ${versionSummary}`, compact: true }), _jsx(StaticRow, { title: `来源 · ${plugin.sourceLabel}`, compact: true }), _jsx(StaticRow, { title: platformSummary, compact: true }), plugin.portableSkills ? _jsx(Text, { color: tuiTheme.colors.accent, children: "[Skills \u53EF\u9009]" }) : null, plugin.configOnly ? _jsx(Text, { color: tuiTheme.colors.muted, children: "[\u5DF2\u4FDD\u5B58\u8BBE\u7F6E]" }) : null, updateDescription
|
|
5421
|
-
? _jsx(StaticRow, { title: "\u6709\u53EF\u7528\u66F4\u65B0", meta: updateDescription, status: "warning", compact: true })
|
|
5422
|
-
: null, dependencyDetailText ? _jsx(StaticRow, { title: dependencyDetailText, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: detailViewport.offset, limit: detailViewport.limit })] });
|
|
5423
|
-
}
|
|
5418
|
+
readingText = [plugin.displayName, ...summary].join('\n');
|
|
5419
|
+
const summaryLines = summary.flatMap((line) => wrapConsoleText(line, size.columns - 2));
|
|
5420
|
+
const completion = snapshot.completionNotice?.pluginId === plugin.pluginId
|
|
5421
|
+
? snapshot.completionNotice : undefined;
|
|
5422
|
+
const completionLines = completion
|
|
5423
|
+
? wrapConsoleText(`${completion.title} · ${completion.description}`, size.columns - 2) : [];
|
|
5424
|
+
const availableSummaryRows = pageActionBudget(Math.min(3, actions.length) + completionLines.length);
|
|
5425
|
+
const summaryPageRows = Math.max(1, availableSummaryRows - Number(summaryLines.length > availableSummaryRows));
|
|
5426
|
+
const summaryOffset = Math.min(batchTargetOffset, Math.max(0, summaryLines.length - summaryPageRows));
|
|
5427
|
+
const visibleSummary = summaryLines.slice(summaryOffset, summaryOffset + summaryPageRows);
|
|
5428
|
+
const summaryPaginated = summaryLines.length > summaryPageRows;
|
|
5429
|
+
if (summaryPaginated) {
|
|
5430
|
+
referenceDetailPagination = { total: summaryLines.length, pageRows: summaryPageRows };
|
|
5431
|
+
context = `${summaryOffset + 1}–${summaryOffset + visibleSummary.length} / ${summaryLines.length}`;
|
|
5432
|
+
help = '←→ 翻页 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
5433
|
+
}
|
|
5434
|
+
currentActionViewportLineBudget = pageActionBudget(visibleSummary.length
|
|
5435
|
+
+ Number(summaryPaginated) + completionLines.length);
|
|
5436
|
+
const detailViewport = actionViewport(actions, true, focus, scrollOffset, currentActionViewportLineBudget);
|
|
5437
|
+
content = _jsxs(Box, { flexDirection: "column", children: [completionLines.map((line, index) => _jsx(Text, { color: tuiTheme.statusColors.success, children: line }, `completion:${index}`)), visibleSummary.map((line, index) => _jsx(Text, { wrap: "truncate-end", children: line }, `${summaryOffset + index}`)), summaryPaginated ? _jsx(Text, { color: tuiTheme.colors.muted, children: summaryOffset + visibleSummary.length < summaryLines.length
|
|
5438
|
+
? `↓ 后面还有 ${summaryLines.length - summaryOffset - visibleSummary.length} 行`
|
|
5439
|
+
: '已到正文末尾' }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: detailViewport.offset, limit: detailViewport.limit })] });
|
|
5424
5440
|
}
|
|
5425
5441
|
else if (route.name === 'pluginMore' && plugin) {
|
|
5426
5442
|
breadcrumb = `插件 / ${plugin.displayName} / 更多操作`;
|
|
@@ -5880,12 +5896,14 @@ export function ConsoleAppV4(props) {
|
|
|
5880
5896
|
const lines = ['effective', 'project', 'user'].flatMap((scope) => ((scope === 'effective' ? currentConfigPage : configLayerPages[scope])?.groups.flatMap((group) => group.fields) ?? []).flatMap((field) => wrapConsoleText(`${field.title} · ${configLayerLabel({ scope })}:${scope === 'effective'
|
|
5881
5897
|
? field.invalidOverrideIssue ? '需修正' : fieldValueText(field, field.draftValue ?? field.effectiveValue, true, field.effectiveSourceLabel !== '未设置')
|
|
5882
5898
|
: fieldValueText(field, field.draftValue ?? field.value, true, field.configured)}`, size.columns - 4)));
|
|
5899
|
+
readingText = ['effective', 'project', 'user'].flatMap((scope) => ((scope === 'effective' ? currentConfigPage : configLayerPages[scope])?.groups.flatMap((group) => group.fields) ?? []).map((field) => `${field.title} · ${configLayerLabel({ scope })}:${scope === 'effective'
|
|
5900
|
+
? field.invalidOverrideIssue ? '需修正' : fieldValueText(field, field.draftValue ?? field.effectiveValue, true, field.effectiveSourceLabel !== '未设置')
|
|
5901
|
+
: fieldValueText(field, field.draftValue ?? field.value, true, field.configured)}`)).join('\n');
|
|
5883
5902
|
const pageRows = Math.max(1, pageActionBudget(4));
|
|
5884
5903
|
const offset = Math.min(batchTargetOffset, Math.max(0, lines.length - 1));
|
|
5885
5904
|
referenceDetailPagination = { total: lines.length, pageRows };
|
|
5886
|
-
actions =
|
|
5887
|
-
|
|
5888
|
-
help = 'p/n 或 PgUp/PgDn 阅读 · Esc 返回';
|
|
5905
|
+
actions = [{ label: '返回设置', run: back }];
|
|
5906
|
+
help = '←→ 或 PgUp/PgDn 阅读 · Esc 返回';
|
|
5889
5907
|
return _jsxs(Box, { flexDirection: "column", children: [lines.slice(offset, offset + pageRows).map((line, index) => _jsx(Text, { children: line }, index)), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
5890
5908
|
})() : _jsxs(Box, { flexDirection: "column", children: [!readonly && configDraftIssues.length > 0 ? _jsx(Callout, { status: "warning", title: "\u6709\u672A\u4FDD\u5B58\u4FEE\u6539\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528", description: "\u63D2\u4EF6\u6765\u6E90\u6062\u590D\u540E\uFF0C\u8BBE\u7F6E\u5185\u5BB9\u6216\u53EF\u7528\u4F4D\u7F6E\u5DF2\u53D8\u5316\u3002\u8BF7\u653E\u5F03\u8FD9\u4E9B\u4FEE\u6539\uFF0C\u6216\u8FD4\u56DE\u68C0\u67E5\u63D2\u4EF6\u6765\u6E90\uFF1B\u7CFB\u7EDF\u4E0D\u4F1A\u81EA\u52A8\u4FDD\u5B58\u3002" }) : null, activeTab ? _jsx(ConfigGroupTabs, { tabs: visibleConfigTabs, current: activeTab.id, compact: policy.mode === 'compact', columns: size.columns - 2 }) : null, _jsx(SequenceRows, { actions: actions, itemCount: tabActions.length, wrapValues: true, focus: effectiveConfigFocus, scrollOffset: scrollOffset, columns: size.columns - 2, rowBudget: pageActionBudget(2 + (configDraftIssues.length > 0 ? 3 : 0)), compact: policy.mode === 'compact' })] });
|
|
5891
5909
|
}
|
|
@@ -5902,6 +5920,7 @@ export function ConsoleAppV4(props) {
|
|
|
5902
5920
|
})));
|
|
5903
5921
|
if (route.view === 'changes') {
|
|
5904
5922
|
const lines = changeDetailLines(changes, size.columns - 4);
|
|
5923
|
+
readingText = changeDetailText(changes);
|
|
5905
5924
|
const pageRows = Math.max(1, Math.min(responsiveBudget(5, 10), pageActionBudget(5)));
|
|
5906
5925
|
const detailOffset = Math.min(batchTargetOffset, Math.max(0, lines.length - 1));
|
|
5907
5926
|
const visibleLines = lines.slice(detailOffset, detailOffset + pageRows);
|
|
@@ -5910,15 +5929,9 @@ export function ConsoleAppV4(props) {
|
|
|
5910
5929
|
context = `${Math.min(detailOffset + 1, lines.length)}–${Math.min(detailOffset + visibleLines.length, lines.length)} / ${lines.length}`;
|
|
5911
5930
|
title = '完整设置变化';
|
|
5912
5931
|
description = '逐项显示修改前和修改后的完整值。';
|
|
5913
|
-
help = '
|
|
5932
|
+
help = '←→ 或 PgUp/PgDn 阅读 · ↑↓ 移动 · Enter 选择 · Esc 返回保存汇总';
|
|
5914
5933
|
actions = [
|
|
5915
|
-
|
|
5916
|
-
offset: detailOffset,
|
|
5917
|
-
total: lines.length,
|
|
5918
|
-
pageRows,
|
|
5919
|
-
move: (direction) => moveBatchTargetPage(lines.length, pageRows, direction),
|
|
5920
|
-
}),
|
|
5921
|
-
{ role: 'navigation', label: '返回保存汇总', run: back },
|
|
5934
|
+
{ label: '返回保存汇总', run: back },
|
|
5922
5935
|
];
|
|
5923
5936
|
content = _jsxs(Box, { flexDirection: "column", children: [detailOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${detailOffset} 行`, status: "muted", compact: true }) : null, visibleLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${detailOffset + index}:${line}`)), detailOffset + visibleLines.length < lines.length
|
|
5924
5937
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${lines.length - detailOffset - visibleLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
@@ -6206,6 +6219,8 @@ export function ConsoleAppV4(props) {
|
|
|
6206
6219
|
breadcrumb = `${unavailablePluginName} / 设置`;
|
|
6207
6220
|
context = '暂时不可编辑';
|
|
6208
6221
|
const diagnostic = configUnavailableDiagnostic(route);
|
|
6222
|
+
if (showTechnical)
|
|
6223
|
+
readingText = diagnosticDetailText(diagnostic);
|
|
6209
6224
|
const invalidLayer = (route.invalidStores?.length ?? 0) > 0;
|
|
6210
6225
|
const canRecoverSource = configUnavailableCanRecoverSource(route);
|
|
6211
6226
|
title = diagnostic.title;
|
|
@@ -6248,7 +6263,7 @@ export function ConsoleAppV4(props) {
|
|
|
6248
6263
|
total: diagnosticDetailLines(diagnostic, size.columns - 6).length,
|
|
6249
6264
|
pageRows: technicalPageRows,
|
|
6250
6265
|
};
|
|
6251
|
-
help = '
|
|
6266
|
+
help = '←→ 或 PgUp/PgDn 阅读技术字段 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6252
6267
|
}
|
|
6253
6268
|
const unavailableActionViewport = actionViewport(actions, true, focus, scrollOffset, pageActionBudget(technicalPageRows + 6 + unsupportedRows.length));
|
|
6254
6269
|
content = invalidLayer
|
|
@@ -6292,7 +6307,8 @@ export function ConsoleAppV4(props) {
|
|
|
6292
6307
|
const unavailable = health === 'unavailable' || health === 'error' || health === 'recovery';
|
|
6293
6308
|
return {
|
|
6294
6309
|
label: source.id,
|
|
6295
|
-
description:
|
|
6310
|
+
description: sourceLocationSummary(overview.detail?.type ?? 'git', overview.detail?.locationSummary),
|
|
6311
|
+
sourceLabel: policy,
|
|
6296
6312
|
meta: `当前 ${version} · ${source.count === undefined ? '插件数未知' : `${source.count} 个插件`} · ${relativeCheckTime(freshness?.checkedAt)}`,
|
|
6297
6313
|
tags: _jsxs(Box, { children: [_jsxs(Text, { color: tuiTheme.colors.muted, children: ["[", source.primary ? '主来源' : transport, "] "] }), _jsx(StatusBadge, { items: [{ key: 'health', label: available ? '可用' : unavailable ? '不可用' : '未确认',
|
|
6298
6314
|
symbol: available ? '✓' : unavailable ? '!' : '?', status: available ? 'success' : unavailable ? 'warning' : 'muted' }] }), freshness && freshness.state !== 'current' && freshness.state !== 'fixed'
|
|
@@ -6469,7 +6485,7 @@ export function ConsoleAppV4(props) {
|
|
|
6469
6485
|
}]
|
|
6470
6486
|
: [{
|
|
6471
6487
|
actionId: 'source-check',
|
|
6472
|
-
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6488
|
+
label: freshness?.state === 'checking' ? '正在检查' : '检查来源 [r]',
|
|
6473
6489
|
description: '检查这个来源;检测到变化或异常时完整验证',
|
|
6474
6490
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6475
6491
|
run: () => props.controller.recheckCatalogSource(route.sourceId),
|
|
@@ -6509,7 +6525,7 @@ export function ConsoleAppV4(props) {
|
|
|
6509
6525
|
|| freshness?.state === 'rollbackDetected'
|
|
6510
6526
|
|| freshness?.state === 'incompatible' ? [{
|
|
6511
6527
|
actionId: 'source-check',
|
|
6512
|
-
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6528
|
+
label: freshness?.state === 'checking' ? '正在检查' : '检查来源 [r]',
|
|
6513
6529
|
description: '检查这个来源;检测到变化或异常时完整验证',
|
|
6514
6530
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6515
6531
|
run: () => props.controller.recheckCatalogSource(route.sourceId),
|
|
@@ -6539,7 +6555,7 @@ export function ConsoleAppV4(props) {
|
|
|
6539
6555
|
const sourceCount = snapshot.viewModel?.sourceTabs.find((source) => source.id === route.sourceId)?.count;
|
|
6540
6556
|
const checkAction = {
|
|
6541
6557
|
actionId: 'source-check',
|
|
6542
|
-
label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6558
|
+
label: freshness?.state === 'checking' ? '正在检查' : '检查来源 [r]',
|
|
6543
6559
|
description: '检查这个来源;检测到变化或异常时完整验证;不会自动启用更新',
|
|
6544
6560
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6545
6561
|
run: () => props.controller.recheckCatalogSource(route.sourceId),
|
|
@@ -6666,7 +6682,7 @@ export function ConsoleAppV4(props) {
|
|
|
6666
6682
|
: detail?.primary ? '主来源不能直接移除' : undefined,
|
|
6667
6683
|
run: () => beginReview({ kind: 'sourceMutation', action: 'remove', sourceId: route.sourceId,
|
|
6668
6684
|
changes: [{ title: `移除来源 ${route.sourceId}` }] }) },
|
|
6669
|
-
{ label: freshness?.state === 'checking' ? '正在检查' : '检查来源',
|
|
6685
|
+
{ label: freshness?.state === 'checking' ? '正在检查' : '检查来源 [r]',
|
|
6670
6686
|
description: '检查这个来源;检测到变化或异常时完整验证;不会自动启用更新',
|
|
6671
6687
|
disabled: freshness?.state === 'checking' ? '检查正在进行' : undefined,
|
|
6672
6688
|
run: () => props.controller.recheckCatalogSource(route.sourceId) },
|
|
@@ -6683,18 +6699,16 @@ export function ConsoleAppV4(props) {
|
|
|
6683
6699
|
}
|
|
6684
6700
|
else if (route.name === 'sourceTechnical') {
|
|
6685
6701
|
const diagnostic = resolveSourceTechnicalDiagnostic(route.sourceId);
|
|
6702
|
+
readingText = diagnosticDetailText(diagnostic);
|
|
6686
6703
|
breadcrumb = `插件来源 / ${route.sourceId} / 技术详情`;
|
|
6687
6704
|
const lines = diagnosticDetailLines(diagnostic, size.columns - 6);
|
|
6688
6705
|
const offset = Math.min(batchTargetOffset, Math.max(0, lines.length - sourceTechnicalPageRows));
|
|
6689
6706
|
context = `${offset + 1}–${Math.min(lines.length, offset + sourceTechnicalPageRows)} / ${lines.length} 行`;
|
|
6690
6707
|
title = '来源技术诊断';
|
|
6691
6708
|
description = '';
|
|
6692
|
-
help = '
|
|
6693
|
-
const sourceTechnicalLastOffset = Math.max(0, lines.length - sourceTechnicalPageRows);
|
|
6709
|
+
help = '←→ 或 PgUp/PgDn 翻页 · Esc 返回';
|
|
6694
6710
|
actions = [
|
|
6695
|
-
{ label: '
|
|
6696
|
-
{ label: 'n 下一页', run: () => setBatchTargetOffset((value) => Math.min(sourceTechnicalLastOffset, value + sourceTechnicalPageRows)) },
|
|
6697
|
-
{ role: 'navigation', label: '返回来源详情', run: back },
|
|
6711
|
+
{ label: '返回来源详情', run: back },
|
|
6698
6712
|
];
|
|
6699
6713
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SectionCard, { title: "\u5B8C\u6574\u5B89\u5168\u5B57\u6BB5", compact: true, children: lines.slice(offset, offset + sourceTechnicalPageRows).map((line, index) => _jsx(Text, { children: line }, offset + index)) }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
6700
6714
|
}
|
|
@@ -6834,6 +6848,7 @@ export function ConsoleAppV4(props) {
|
|
|
6834
6848
|
const changes = sourceDraftChanges(sourceDraft);
|
|
6835
6849
|
if (route.view === 'changes') {
|
|
6836
6850
|
const lines = changeDetailLines(changes, size.columns - 4);
|
|
6851
|
+
readingText = changeDetailText(changes);
|
|
6837
6852
|
const pageRows = Math.max(1, Math.min(responsiveBudget(5, 10), pageActionBudget(5)));
|
|
6838
6853
|
const detailOffset = Math.min(batchTargetOffset, Math.max(0, lines.length - 1));
|
|
6839
6854
|
const visibleLines = lines.slice(detailOffset, detailOffset + pageRows);
|
|
@@ -6842,15 +6857,9 @@ export function ConsoleAppV4(props) {
|
|
|
6842
6857
|
context = `${Math.min(detailOffset + 1, lines.length)}–${Math.min(detailOffset + visibleLines.length, lines.length)} / ${lines.length}`;
|
|
6843
6858
|
title = '完整来源变化';
|
|
6844
6859
|
description = '逐项显示修改前和修改后的完整值。';
|
|
6845
|
-
help = '
|
|
6860
|
+
help = '←→ 或 PgUp/PgDn 阅读 · ↑↓ 移动 · Enter 选择 · Esc 返回修改汇总';
|
|
6846
6861
|
actions = [
|
|
6847
|
-
|
|
6848
|
-
offset: detailOffset,
|
|
6849
|
-
total: lines.length,
|
|
6850
|
-
pageRows,
|
|
6851
|
-
move: (direction) => moveBatchTargetPage(lines.length, pageRows, direction),
|
|
6852
|
-
}),
|
|
6853
|
-
{ role: 'navigation', label: '返回修改汇总', run: back },
|
|
6862
|
+
{ label: '返回修改汇总', run: back },
|
|
6854
6863
|
];
|
|
6855
6864
|
content = _jsxs(Box, { flexDirection: "column", children: [detailOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${detailOffset} 行`, status: "muted", compact: true }) : null, visibleLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${detailOffset + index}:${line}`)), detailOffset + visibleLines.length < lines.length
|
|
6856
6865
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${lines.length - detailOffset - visibleLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
@@ -6906,18 +6915,14 @@ export function ConsoleAppV4(props) {
|
|
|
6906
6915
|
const countLabel = (value, unit) => value === undefined ? '未知' : `${value} ${unit}`;
|
|
6907
6916
|
const referenceLimit = Math.max(1, pageActionBudget(12));
|
|
6908
6917
|
const references = sourceReferenceSummary?.dependencies ?? [];
|
|
6918
|
+
if (sourceDependenciesExpanded)
|
|
6919
|
+
readingText = references.map((dependency) => `${dependency.category} · ${dependency.pluginId ?? dependency.sourceId ?? '身份未知'} · ${dependency.platform ? platformLabel(dependency.platform) : ''}${dependency.scope ? ` · ${scopeLabel(dependency.scope)}` : ''}`).join('\n');
|
|
6909
6920
|
const referenceOffset = Math.min(batchTargetOffset, Math.max(0, references.length - 1));
|
|
6910
6921
|
const visibleReferences = references.slice(referenceOffset, referenceOffset + referenceLimit);
|
|
6911
6922
|
const hiddenReferences = Math.max(0, references.length - referenceOffset - visibleReferences.length);
|
|
6912
6923
|
if (sourceDependenciesExpanded && references.length > referenceLimit) {
|
|
6913
|
-
actions.unshift(...paginationActions({
|
|
6914
|
-
offset: referenceOffset,
|
|
6915
|
-
total: references.length,
|
|
6916
|
-
pageRows: referenceLimit,
|
|
6917
|
-
move: (direction) => moveBatchTargetPage(references.length, referenceLimit, direction),
|
|
6918
|
-
}));
|
|
6919
6924
|
referenceDetailPagination = { total: references.length, pageRows: referenceLimit };
|
|
6920
|
-
help = '
|
|
6925
|
+
help = '←→ 查看全部引用 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6921
6926
|
}
|
|
6922
6927
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(Callout, { status: "error", title: sourceReferenceSummary?.inventoryComplete === false ? '引用清单不完整' : '发现活动引用' }), _jsxs(SectionCard, { title: sourceDependenciesExpanded
|
|
6923
6928
|
? referenceOffset > 0 ? `引用内容 · ↑ 前面还有 ${referenceOffset} 项` : '引用内容'
|
|
@@ -7035,21 +7040,14 @@ export function ConsoleAppV4(props) {
|
|
|
7035
7040
|
run: () => runIssueAction(entry),
|
|
7036
7041
|
}));
|
|
7037
7042
|
const issueDetailRows = diagnosticDetailLines(issue.diagnostic, size.columns - 6).length;
|
|
7043
|
+
if (showTechnical)
|
|
7044
|
+
readingText = diagnosticDetailText(issue.diagnostic);
|
|
7038
7045
|
const issueDetailPageRows = policy.mode === 'compact'
|
|
7039
7046
|
? 1
|
|
7040
7047
|
: Math.max(1, responsiveBudget(1, 4));
|
|
7041
|
-
|
|
7042
|
-
? paginationActions({
|
|
7043
|
-
offset: batchTargetOffset,
|
|
7044
|
-
total: issueDetailRows,
|
|
7045
|
-
pageRows: issueDetailPageRows,
|
|
7046
|
-
move: (direction) => moveBatchTargetPage(issueDetailRows, issueDetailPageRows, direction),
|
|
7047
|
-
})
|
|
7048
|
-
: [];
|
|
7049
|
-
actions.push(...issuePaginationActions);
|
|
7050
|
-
if (issuePaginationActions.length > 0) {
|
|
7048
|
+
if (showTechnical && issueDetailRows > issueDetailPageRows) {
|
|
7051
7049
|
referenceDetailPagination = { total: issueDetailRows, pageRows: issueDetailPageRows };
|
|
7052
|
-
help = '
|
|
7050
|
+
help = '←→ 或 PgUp/PgDn 阅读全部技术字段 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
7053
7051
|
}
|
|
7054
7052
|
const issuePlugin = issue.pluginId ? props.controller.getPluginOverview(issue.pluginId) : undefined;
|
|
7055
7053
|
const issueOverview = issue.pluginId ? props.controller.getPluginDependencyOverview(issue.pluginId) : undefined;
|
|
@@ -7070,7 +7068,6 @@ export function ConsoleAppV4(props) {
|
|
|
7070
7068
|
{ label: '查看完整依赖关系', run: () => go({ name: 'pluginDependencies', pluginId: issuePlugin.pluginId }) },
|
|
7071
7069
|
{ label: '返回插件详情', run: () => go({ name: 'pluginDetail', pluginId: issuePlugin.pluginId }) },
|
|
7072
7070
|
...(issueHasTechnicalDetails ? [{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() }] : []),
|
|
7073
|
-
...issuePaginationActions,
|
|
7074
7071
|
];
|
|
7075
7072
|
const dependencyBlockedViewport = policy.mode === 'compact' && showTechnical
|
|
7076
7073
|
? { offset: Math.min(Math.max(0, focus - 1), Math.max(0, actions.length - 2)), limit: 2 }
|
|
@@ -7111,7 +7108,6 @@ export function ConsoleAppV4(props) {
|
|
|
7111
7108
|
} },
|
|
7112
7109
|
{ label: '查看依赖关系', run: () => go({ name: 'pluginDependencies', pluginId: issuePlugin.pluginId }) },
|
|
7113
7110
|
...(issueHasTechnicalDetails ? [{ label: showTechnical ? '隐藏技术详情' : '技术详情', run: () => toggleTechnical() }] : []),
|
|
7114
|
-
...issuePaginationActions,
|
|
7115
7111
|
];
|
|
7116
7112
|
const unsupportedTargetViewport = policy.mode === 'compact' && showTechnical
|
|
7117
7113
|
? { offset: Math.min(Math.max(0, focus - 1), Math.max(0, actions.length - 2)), limit: 2 }
|
|
@@ -7165,21 +7161,22 @@ export function ConsoleAppV4(props) {
|
|
|
7165
7161
|
else if (route.name === 'operationDiagnostic') {
|
|
7166
7162
|
const detail = props.controller.getOperationDiagnostic(route.recordId);
|
|
7167
7163
|
breadcrumb = '操作记录 / 技术详情';
|
|
7168
|
-
context = '
|
|
7164
|
+
context = '安全详情';
|
|
7169
7165
|
title = detail ? '安全技术详情' : '操作记录已不可用';
|
|
7170
7166
|
description = detail
|
|
7171
7167
|
? '可滚动查看所有目标、阶段、代码和已保留的安全原因。'
|
|
7172
7168
|
: '这项会话记录已经不再可用。';
|
|
7173
7169
|
const preview = detail ? props.controller.previewOperationReport(route.recordId) : undefined;
|
|
7174
7170
|
const detailLineLimit = operationDetailPageRows;
|
|
7175
|
-
|
|
7176
|
-
|
|
7171
|
+
if (detail) {
|
|
7172
|
+
readingText = operationDiagnosticText(detail);
|
|
7173
|
+
const total = operationDiagnosticLineCount(detail, size.columns);
|
|
7174
|
+
context = `${Math.min(total, scrollOffset + 1)}–${Math.min(total, scrollOffset + detailLineLimit)} / ${total} 行`;
|
|
7175
|
+
}
|
|
7177
7176
|
actions = detail ? [
|
|
7178
7177
|
preview
|
|
7179
7178
|
? { label: '预览安全报告', description: '确认内容后选择本地保存位置', run: () => go({ name: 'operationReportPreview', recordId: route.recordId }) }
|
|
7180
7179
|
: { label: '报告当前不可用', disabled: '无法生成这项记录的报告' },
|
|
7181
|
-
{ label: 'p 上一页', run: () => setScrollOffset((value) => Math.max(0, value - detailLineLimit)) },
|
|
7182
|
-
{ label: 'n 下一页', run: () => setScrollOffset((value) => Math.min(lastDetailOffset, value + detailLineLimit)) },
|
|
7183
7180
|
{ role: 'navigation', label: '返回操作记录', run: back },
|
|
7184
7181
|
] : [{ role: 'navigation', label: '返回操作记录', run: back }];
|
|
7185
7182
|
const diagnosticActionViewport = actionViewport(actions, policy.mode === 'compact', focus, 0, policy.mode === 'compact' ? 2 : 3);
|
|
@@ -7188,7 +7185,7 @@ export function ConsoleAppV4(props) {
|
|
|
7188
7185
|
else if (route.name === 'operationReportPreview') {
|
|
7189
7186
|
const preview = props.controller.previewOperationReport(route.recordId);
|
|
7190
7187
|
breadcrumb = '操作记录 / 报告预览';
|
|
7191
|
-
context = '
|
|
7188
|
+
context = '安全报告';
|
|
7192
7189
|
title = reportSaveMode ? '选择报告保存位置' : preview ? '安全报告预览' : '报告已不可用';
|
|
7193
7190
|
description = reportSaveMode
|
|
7194
7191
|
? '输入一个新的本地文件路径,然后按 Enter 保存。'
|
|
@@ -7200,9 +7197,10 @@ export function ConsoleAppV4(props) {
|
|
|
7200
7197
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(InputCard, { title: "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84", focused: true, compact: policy.mode === 'compact', children: _jsx(InputDisplay, { value: reportSavePath, placeholder: "/tmp/aw-operation-report.md", columns: Math.max(12, size.columns - 10) }) }), reportSaveError ? _jsx(Callout, { status: "error", title: "\u62A5\u544A\u672A\u4FDD\u5B58", description: reportSaveError, compact: policy.mode === 'compact' }) : null, _jsx(StaticRow, { title: "\u4EC5\u4FDD\u5B58\u5F53\u524D\u9884\u89C8\u4E2D\u7684\u5B89\u5168\u5185\u5BB9\u3002", status: "muted", compact: true })] });
|
|
7201
7198
|
}
|
|
7202
7199
|
else if (preview) {
|
|
7203
|
-
|
|
7204
|
-
const
|
|
7205
|
-
const
|
|
7200
|
+
readingText = preview.content;
|
|
7201
|
+
const reportLineLimit = operationReportPageRows;
|
|
7202
|
+
const total = operationReportLineCount(preview, size.columns);
|
|
7203
|
+
context = `${Math.min(total, scrollOffset + 1)}–${Math.min(total, scrollOffset + reportLineLimit)} / ${total} 行`;
|
|
7206
7204
|
actions = [
|
|
7207
7205
|
{ label: '选择本地保存位置', description: '保存前输入明确的文件路径', run: () => {
|
|
7208
7206
|
setReportSaveMode(true);
|
|
@@ -7217,8 +7215,6 @@ export function ConsoleAppV4(props) {
|
|
|
7217
7215
|
setReportSaveError('报告未保存。请检查保存位置后重试。');
|
|
7218
7216
|
});
|
|
7219
7217
|
} },
|
|
7220
|
-
{ label: 'p 上一页', run: () => setScrollOffset((value) => Math.max(0, value - reportLineLimit)) },
|
|
7221
|
-
{ label: 'n 下一页', run: () => setScrollOffset((value) => Math.min(lastReportOffset, value + reportLineLimit)) },
|
|
7222
7218
|
{ role: 'navigation', label: '返回技术详情', run: back },
|
|
7223
7219
|
];
|
|
7224
7220
|
const reportFeedbackVisible = Boolean(reportSaveResult || reportSaveError);
|
|
@@ -7283,6 +7279,17 @@ export function ConsoleAppV4(props) {
|
|
|
7283
7279
|
}
|
|
7284
7280
|
else if (route.name === 'review' && snapshot.activeReview) {
|
|
7285
7281
|
const review = snapshot.activeReview;
|
|
7282
|
+
readingText = [
|
|
7283
|
+
`${review.title} · ${review.subject.name}`,
|
|
7284
|
+
review.description,
|
|
7285
|
+
...(review.equivalentCommand && !review.requiresConfirmation
|
|
7286
|
+
? [`等价命令:${review.equivalentCommand}`] : []),
|
|
7287
|
+
...(review.rootSummary ?? []).map((root) => `${root.pluginId}${root.version ? ` · ${root.version}` : ''} · ${root.targets.map((target) => `${target.platform}/${target.scope}`).join('、')}`),
|
|
7288
|
+
...review.changes.map((change) => `${change.sourceId ? `${change.sourceId} · ` : ''}${reviewSymbol(change)} ${change.title}${change.description ? ` · ${change.description}` : ''}`),
|
|
7289
|
+
...(review.technicalDetails ?? []),
|
|
7290
|
+
...(review.confirmationDetails ?? []),
|
|
7291
|
+
...(review.sharedImpact.warning ? [review.sharedImpact.warning] : []),
|
|
7292
|
+
].join('\n');
|
|
7286
7293
|
const technicalDetails = (review.technicalDetails ?? []).flatMap((detail) => review.operationKind === 'catalogGeneration' && detail.startsWith('引用影响:')
|
|
7287
7294
|
? wrapConsoleText(detail, Math.max(20, size.columns - 10))
|
|
7288
7295
|
: [detail]);
|
|
@@ -7492,12 +7499,6 @@ export function ConsoleAppV4(props) {
|
|
|
7492
7499
|
: userReviewChanges.length;
|
|
7493
7500
|
const reviewPageRows = Math.max(1, responsiveBudget(6, 10) - actions.length - 2);
|
|
7494
7501
|
if (reviewPaginationTotal > reviewPageRows) {
|
|
7495
|
-
actions.push(...paginationActions({
|
|
7496
|
-
offset: batchTargetOffset,
|
|
7497
|
-
total: reviewPaginationTotal,
|
|
7498
|
-
pageRows: 1,
|
|
7499
|
-
move: (direction) => moveBatchTargetPage(reviewPaginationTotal, 1, direction),
|
|
7500
|
-
}));
|
|
7501
7502
|
referenceDetailPagination = { total: reviewPaginationTotal, pageRows: 1 };
|
|
7502
7503
|
}
|
|
7503
7504
|
const reviewActionViewport = actionViewport(actions, true, focus, scrollOffset, responsiveBudget(2, 6));
|
|
@@ -7696,6 +7697,11 @@ export function ConsoleAppV4(props) {
|
|
|
7696
7697
|
: entry.state === 'skipped' ? 3 : 4;
|
|
7697
7698
|
return priority(left) - priority(right);
|
|
7698
7699
|
});
|
|
7700
|
+
readingText = [
|
|
7701
|
+
title,
|
|
7702
|
+
...prioritizedProgressTargets.map((entry) => `${entry.pluginId} · ${platformLabel(entry.platform)} · ${scopeLabel(entry.scope)} · ${progressLabel(entry).label}`),
|
|
7703
|
+
...snapshot.progress.messages.map(productResultMessage),
|
|
7704
|
+
].join('\n');
|
|
7699
7705
|
const progressStepRows = policy.mode === 'compact' ? 4 : 5;
|
|
7700
7706
|
const progressTargetAndMessageBudget = pageActionBudget()
|
|
7701
7707
|
- 2
|
|
@@ -7709,7 +7715,10 @@ export function ConsoleAppV4(props) {
|
|
|
7709
7715
|
const progressTargetBudget = progressTargetAndMessageBudget - dependencyMessageLimit;
|
|
7710
7716
|
const progressTargetLimit = prefixRowLimit(prioritizedProgressTargets.map(() => policy.mode === 'compact' ? 1 : 2), progressTargetBudget);
|
|
7711
7717
|
help = prioritizedProgressTargets.length > progressTargetLimit
|
|
7712
|
-
? '
|
|
7718
|
+
? '←→ 翻页 · [y] 复制全文 · Ctrl-C 完成后退出'
|
|
7719
|
+
: '[y] 复制全文 · Ctrl-C 完成后退出';
|
|
7720
|
+
if (copyFeedback?.routeKey === routeKey)
|
|
7721
|
+
description = copyFeedback.message;
|
|
7713
7722
|
const progressTargetOffset = Math.min(batchTargetOffset, Math.max(0, prioritizedProgressTargets.length - 1));
|
|
7714
7723
|
const visibleProgressTargets = prioritizedProgressTargets.slice(progressTargetOffset, progressTargetOffset + progressTargetLimit);
|
|
7715
7724
|
const hiddenProgressTargets = Math.max(0, snapshot.progressTargets.length - progressTargetOffset - visibleProgressTargets.length);
|
|
@@ -8240,6 +8249,16 @@ export function ConsoleAppV4(props) {
|
|
|
8240
8249
|
},
|
|
8241
8250
|
}] : []), { role: !partial && !blocked ? 'navigation' : undefined,
|
|
8242
8251
|
label: '返回首页', run: () => requestSessionNavigation('home') }];
|
|
8252
|
+
if (snapshot.canResumeInstallDraft) {
|
|
8253
|
+
actions.unshift({ label: '返回修改', run: async () => {
|
|
8254
|
+
props.controller.resumeResultDraft();
|
|
8255
|
+
if (props.controller.snapshot.router.current.route.name === 'dependencyPlacement') {
|
|
8256
|
+
await props.controller.prepareInstallDependencyPlacement();
|
|
8257
|
+
}
|
|
8258
|
+
setFocus(0);
|
|
8259
|
+
setScrollOffset(0);
|
|
8260
|
+
} });
|
|
8261
|
+
}
|
|
8243
8262
|
if (failedCleanupTargets.length > 0) {
|
|
8244
8263
|
actions.unshift({
|
|
8245
8264
|
label: '查看清理建议',
|
|
@@ -8350,23 +8369,36 @@ export function ConsoleAppV4(props) {
|
|
|
8350
8369
|
? wrapPortableField('materialization digest', portableReceipt.materializationDigest) : []),
|
|
8351
8370
|
...(resultSummary?.elapsedMs !== undefined ? [`elapsed · ${resultSummary.elapsedMs} ms`] : []),
|
|
8352
8371
|
] : ['当前结果已变化。请返回结果摘要。'];
|
|
8372
|
+
readingText = portableResultDetailOpen ? selectedPortablePair ? [
|
|
8373
|
+
`Skill · ${selectedPortablePair.skill}`,
|
|
8374
|
+
`Agent · ${selectedPortablePair.agent ?? '无法确认'}`,
|
|
8375
|
+
`状态 · ${portablePairStateLabel(selectedPortablePair)}`,
|
|
8376
|
+
...(portableResultScope ? [`范围 · ${scopeLabel(portableResultScope)}`] : []),
|
|
8377
|
+
...(portableReceipt?.recovery ? [`安全恢复 · ${portableReceipt.recovery}`] : []),
|
|
8378
|
+
...(portableReceipt?.failureCode ? [`failure code · ${portableReceipt.failureCode}`] : []),
|
|
8379
|
+
...(portableReceipt ? [`verification missing · ${portableReceipt.missing.length}`,
|
|
8380
|
+
`Skills CLI version · ${portableReceipt.skillsCliVersion}`,
|
|
8381
|
+
`materialization digest · ${portableReceipt.materializationDigest}`] : []),
|
|
8382
|
+
...(resultSummary?.elapsedMs !== undefined ? [`elapsed · ${resultSummary.elapsedMs} ms`] : []),
|
|
8383
|
+
].join('\n') : '当前结果已变化。请返回结果摘要。' : [
|
|
8384
|
+
resultSummary?.message ?? (blocked ? result.message : '操作结果'),
|
|
8385
|
+
...(resultSummary?.messages ?? []).map(productResultMessage),
|
|
8386
|
+
...(resultSummary?.changes ?? []),
|
|
8387
|
+
...(resultSummary?.warnings ?? []),
|
|
8388
|
+
...(resultSummary?.recoveryActions ?? []),
|
|
8389
|
+
...prioritizedTargets.map((target) => `${resultTargetName(target)} · ${platformLabel(target.platform)} · ${scopeLabel(target.scope)} · ${operationTargetStateLabel(target.state).label}`),
|
|
8390
|
+
...prioritizedPortablePairs.map((pair) => `${pair.skill} · ${pair.agent ?? 'Agent 未确认'} · ${portablePairStateLabel(pair)}`),
|
|
8391
|
+
...(taskSummary?.rootResults ?? []).map((root) => `${root.pluginId} · ${root.state}`),
|
|
8392
|
+
...(resultSummary?.batch?.rootResults ?? []).map((root) => `${root.pluginId} · ${root.state}`),
|
|
8393
|
+
].join('\n');
|
|
8353
8394
|
const portableResultDetailPageRows = responsiveBudget(5, 10);
|
|
8354
8395
|
const safePortableResultDetailOffset = Math.min(portableResultDetailOffset, Math.max(0, portableResultDetailLines.length - 1));
|
|
8355
8396
|
const visiblePortableResultDetailLines = portableResultDetailLines.slice(safePortableResultDetailOffset, safePortableResultDetailOffset + portableResultDetailPageRows);
|
|
8356
8397
|
if (portableOperation && portableResultDetailOpen) {
|
|
8357
8398
|
title = '当前结果完整字段';
|
|
8358
8399
|
description = '按行显示当前 Skill、Agent、状态和技术证据。';
|
|
8359
|
-
help = '
|
|
8360
|
-
const detailPaginationActions = portableResultDetailLines.length > portableResultDetailPageRows
|
|
8361
|
-
? paginationActions({
|
|
8362
|
-
offset: safePortableResultDetailOffset,
|
|
8363
|
-
total: portableResultDetailLines.length,
|
|
8364
|
-
pageRows: portableResultDetailPageRows,
|
|
8365
|
-
move: (direction) => setPortableResultDetailOffset((value) => Math.min(Math.max(0, portableResultDetailLines.length - 1), Math.max(0, value + direction * portableResultDetailPageRows))),
|
|
8366
|
-
})
|
|
8367
|
-
: [];
|
|
8400
|
+
help = '←→ 阅读全部字段 · ↑↓ 移动 · Enter 选择 · Esc 返回结果摘要';
|
|
8368
8401
|
actions = [
|
|
8369
|
-
...detailPaginationActions,
|
|
8370
8402
|
{ label: '返回结果摘要', run: () => {
|
|
8371
8403
|
setPortableResultDetailOpen(false);
|
|
8372
8404
|
setPortableResultDetailOffset(0);
|
|
@@ -8392,29 +8424,16 @@ export function ConsoleAppV4(props) {
|
|
|
8392
8424
|
setScrollOffset(0);
|
|
8393
8425
|
},
|
|
8394
8426
|
} : undefined;
|
|
8395
|
-
const pagination = resultPaginationTotal > 1 ? paginationActions({
|
|
8396
|
-
offset: batchTargetOffset,
|
|
8397
|
-
total: resultPaginationTotal,
|
|
8398
|
-
pageRows: resultPageRows,
|
|
8399
|
-
move: (direction) => moveBatchTargetPage(resultPaginationTotal, resultPageRows, direction),
|
|
8400
|
-
}) : [];
|
|
8401
8427
|
actions = [
|
|
8402
8428
|
...actions.slice(0, 1),
|
|
8403
|
-
...pagination,
|
|
8404
8429
|
...(detailAction ? [detailAction] : []),
|
|
8405
8430
|
...actions.slice(1),
|
|
8406
8431
|
];
|
|
8407
|
-
if (
|
|
8432
|
+
if (resultPaginationTotal > resultPageRows) {
|
|
8408
8433
|
referenceDetailPagination = { total: resultPaginationTotal, pageRows: resultPageRows };
|
|
8409
8434
|
}
|
|
8410
8435
|
}
|
|
8411
8436
|
else if (resultPaginationTotal > 1) {
|
|
8412
|
-
actions.push(...paginationActions({
|
|
8413
|
-
offset: batchTargetOffset,
|
|
8414
|
-
total: resultPaginationTotal,
|
|
8415
|
-
pageRows: resultPageRows,
|
|
8416
|
-
move: (direction) => moveBatchTargetPage(resultPaginationTotal, resultPageRows, direction),
|
|
8417
|
-
}));
|
|
8418
8437
|
referenceDetailPagination = { total: resultPaginationTotal, pageRows: resultPageRows };
|
|
8419
8438
|
}
|
|
8420
8439
|
const portableTechnicalFieldCount = portableReceipt
|
|
@@ -8508,7 +8527,7 @@ export function ConsoleAppV4(props) {
|
|
|
8508
8527
|
const requestedTargets = taskSummary?.requestedTargets.filter((target) => target.pluginId === root.pluginId) ?? [];
|
|
8509
8528
|
return _jsx(ResultRow, { title: rootName, description: `${requestedTargets.length} 个使用位置`, meta: rootState.label, status: rootState.status, compact: true }, `root:${root.pluginId}`);
|
|
8510
8529
|
});
|
|
8511
|
-
const
|
|
8530
|
+
const taskLocationItems = taskRootResults.flatMap((root) => {
|
|
8512
8531
|
return root.targets.map((target) => {
|
|
8513
8532
|
const targetPluginId = target.pluginId ?? root.pluginId;
|
|
8514
8533
|
const key = [targetPluginId, target.platform, target.scope].join('\0');
|
|
@@ -8520,11 +8539,29 @@ export function ConsoleAppV4(props) {
|
|
|
8520
8539
|
: { label: '未开始', status: 'muted' };
|
|
8521
8540
|
const relation = target.relation === 'direct' ? '直接依赖'
|
|
8522
8541
|
: target.relation === 'transitive' ? '间接依赖' : '所选插件位置';
|
|
8523
|
-
return
|
|
8542
|
+
return {
|
|
8543
|
+
key: `target:${root.pluginId}:${key}`,
|
|
8544
|
+
title: `${root.pluginId}${targetPluginId === root.pluginId ? '' : ` → ${targetPluginId}`} · ${platformLabel(target.platform)} · ${scopeLabel(target.scope)}`,
|
|
8545
|
+
description: blockedTarget
|
|
8524
8546
|
? pluginWriteTaskBlockLabel(blockedTarget.reason)
|
|
8525
|
-
: `${relation}${target.errorCode ? ` · ${target.errorCode}` : ''}`,
|
|
8547
|
+
: `${relation}${target.errorCode ? ` · ${target.errorCode}` : ''}`,
|
|
8548
|
+
meta: `${targetState.label}${target.errorCode ? ` · ${target.errorCode}` : ''}`,
|
|
8549
|
+
status: targetState.status,
|
|
8550
|
+
compact: !blockedTarget,
|
|
8551
|
+
};
|
|
8526
8552
|
});
|
|
8527
8553
|
});
|
|
8554
|
+
const taskLocationRows = taskLocationItems.map(({ key, ...item }) => _jsx(ResultRow, { ...item }, key));
|
|
8555
|
+
if (taskOperation)
|
|
8556
|
+
readingText = [
|
|
8557
|
+
resultSummary?.message ?? (blocked ? result.message : '操作结果'),
|
|
8558
|
+
...(resultSummary?.messages ?? []).map(productResultMessage),
|
|
8559
|
+
...(resultSummary?.changes ?? []),
|
|
8560
|
+
...(resultSummary?.warnings ?? []),
|
|
8561
|
+
...(resultSummary?.recoveryActions ?? []),
|
|
8562
|
+
...taskRootResults.map((root) => `${root.pluginId} · ${taskRootState(root.state).label}`),
|
|
8563
|
+
...taskLocationItems.flatMap((item) => [`${item.title} · ${item.meta}`, item.description]),
|
|
8564
|
+
].join('\n');
|
|
8528
8565
|
const batchPluginResultRows = (resultSummary?.batch?.rootResults ?? []).map((root) => {
|
|
8529
8566
|
const rootState = taskRootState(root.state);
|
|
8530
8567
|
const rootName = props.controller.getPluginOverview(root.pluginId)?.displayName
|
|
@@ -8550,7 +8587,7 @@ export function ConsoleAppV4(props) {
|
|
|
8550
8587
|
const visibleLocationResultRows = locationResultRows.slice(visibleLocationStart, visibleLocationStart + remainingResultRows);
|
|
8551
8588
|
if (taskOperation || batchOperation || resultTargets.length > resultTargetLimit
|
|
8552
8589
|
|| prioritizedPortablePairs.length > portableSkillLimit) {
|
|
8553
|
-
help = '
|
|
8590
|
+
help = '←→ 查看全部项目 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
8554
8591
|
}
|
|
8555
8592
|
content = taskOperation || batchOperation ? _jsxs(Box, { flexDirection: "column", children: [taskResultOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${taskResultOffset} 项`, status: "muted", compact: true }) : null, visiblePluginResultRows.length > 0 ? _jsx(ResultCard, { status: resultStatus, title: "\u63D2\u4EF6\u7ED3\u679C", meta: `${pluginResultRows.length} 个插件`, children: visiblePluginResultRows }) : null, visibleLocationResultRows.length > 0 ? _jsx(ResultCard, { status: resultStatus, title: "\u4F7F\u7528\u4F4D\u7F6E\u4E0E\u6240\u9700\u63D2\u4EF6", meta: `${locationResultRows.length} 项`, children: visibleLocationResultRows }) : null, combinedResultRows.length > taskResultOffset + visiblePluginResultRows.length + visibleLocationResultRows.length
|
|
8556
8593
|
? _jsx(StaticRow, { title: "\u2193 \u540E\u9762\u8FD8\u6709", meta: `${combinedResultRows.length - taskResultOffset - visiblePluginResultRows.length - visibleLocationResultRows.length} 项`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: resultActionViewport.offset, limit: resultActionViewport.limit })] }) : portableOperation ? _jsxs(Box, { flexDirection: "column", children: [portableRecheckBusy
|
|
@@ -8638,19 +8675,14 @@ export function ConsoleAppV4(props) {
|
|
|
8638
8675
|
] : []),
|
|
8639
8676
|
...plugin.installedPlacements.map((placement) => `${platformLabel(placement.platform)} target · ${placementStatus(placement).value}`),
|
|
8640
8677
|
];
|
|
8678
|
+
readingText = technicalFields.join('\n');
|
|
8641
8679
|
const technicalLines = technicalFields.flatMap((field) => wrapDisplayText(field, size.columns - 6));
|
|
8642
8680
|
const technicalPageRows = Math.max(1, pageActionBudget(7));
|
|
8643
8681
|
const technicalOffset = Math.min(batchTargetOffset, Math.max(0, technicalLines.length - 1));
|
|
8644
8682
|
const visibleTechnicalLines = technicalLines.slice(technicalOffset, technicalOffset + technicalPageRows);
|
|
8645
8683
|
if (technicalLines.length > technicalPageRows) {
|
|
8646
|
-
actions.push(...paginationActions({
|
|
8647
|
-
offset: technicalOffset,
|
|
8648
|
-
total: technicalLines.length,
|
|
8649
|
-
pageRows: technicalPageRows,
|
|
8650
|
-
move: (direction) => moveBatchTargetPage(technicalLines.length, technicalPageRows, direction),
|
|
8651
|
-
}));
|
|
8652
8684
|
referenceDetailPagination = { total: technicalLines.length, pageRows: technicalPageRows };
|
|
8653
|
-
help = '
|
|
8685
|
+
help = '←→ 或 PgUp/PgDn 阅读技术字段 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
8654
8686
|
}
|
|
8655
8687
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsxs(TechnicalDetails, { children: [technicalOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${technicalOffset} 行`, status: "muted", compact: true }) : null, visibleTechnicalLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${technicalOffset + index}:${line}`)), technicalOffset + visibleTechnicalLines.length < technicalLines.length
|
|
8656
8688
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${technicalLines.length - technicalOffset - visibleTechnicalLines.length} 行`, status: "muted", compact: true }) : null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
@@ -8752,8 +8784,8 @@ export function ConsoleAppV4(props) {
|
|
|
8752
8784
|
: 'h/H 完成后导航'} · Esc 撤销等待 · ${help}`
|
|
8753
8785
|
: `h 首页 · H 重载 · ${help}`;
|
|
8754
8786
|
}
|
|
8755
|
-
const helpParts = help.split(' · ')
|
|
8756
|
-
const isRoutineKey = (part) => /^(↑|Enter|Space|Esc|Ctrl-C
|
|
8787
|
+
const helpParts = help.split(' · ');
|
|
8788
|
+
const isRoutineKey = (part) => /^(↑|Enter|Space|Esc|Ctrl-C|←→)/u.test(part);
|
|
8757
8789
|
help = [...helpParts.filter(isRoutineKey), ...helpParts.filter((part) => !isRoutineKey(part))].join(' · ');
|
|
8758
8790
|
if (searchFocus)
|
|
8759
8791
|
help = '←→ 光标 · ↑↓ 移动结果 · Enter/Esc 完成输入';
|
|
@@ -8770,6 +8802,16 @@ export function ConsoleAppV4(props) {
|
|
|
8770
8802
|
|| route.name === 'batchSelection' && batchDraft?.stage === 'select'
|
|
8771
8803
|
? actions.filter((action) => action.pluginId !== undefined) : [];
|
|
8772
8804
|
const listCandidateSignature = listCandidates.map((action) => action.pluginId).join('\0');
|
|
8805
|
+
useEffect(() => {
|
|
8806
|
+
const pluginId = listCandidates[focus]?.pluginId;
|
|
8807
|
+
if (route.name === 'batchSelection' && batchDraft?.stage === 'select'
|
|
8808
|
+
&& !batchDraft.showSelectionTools && pluginId) {
|
|
8809
|
+
batchSelectionAnchor.current = {
|
|
8810
|
+
frameId: snapshot.router.currentFrameId, pluginId, index: focus, scrollOffset,
|
|
8811
|
+
};
|
|
8812
|
+
}
|
|
8813
|
+
}, [snapshot.router.currentFrameId, route.name, batchDraft?.stage,
|
|
8814
|
+
batchDraft?.showSelectionTools, listCandidateSignature, focus, scrollOffset]);
|
|
8773
8815
|
useEffect(() => {
|
|
8774
8816
|
if (route.name !== 'pluginList' && !(route.name === 'batchSelection' && batchDraft?.stage === 'select')) {
|
|
8775
8817
|
listFocusAnchor.current = undefined;
|
|
@@ -8963,10 +9005,19 @@ export function ConsoleAppV4(props) {
|
|
|
8963
9005
|
}
|
|
8964
9006
|
if (busy) {
|
|
8965
9007
|
const sessionNavigation = resolveTuiSessionNavigationKey({ input, key }, { characterInput: false });
|
|
8966
|
-
if ((key.pageUp || key.pageDown
|
|
9008
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9009
|
+
&& route.name === 'progress' && !overlay) {
|
|
8967
9010
|
const total = snapshot.progressTargets.length;
|
|
8968
9011
|
const pageRows = 1;
|
|
8969
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + (key.pageUp ? -pageRows : pageRows))));
|
|
9012
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + (key.pageUp || key.leftArrow ? -pageRows : pageRows))));
|
|
9013
|
+
}
|
|
9014
|
+
else if (!overlay && input.toLowerCase() === 'y' && readingText !== undefined) {
|
|
9015
|
+
const currentRouteKey = routeKey;
|
|
9016
|
+
void copyToClipboard(readingText).then(() => {
|
|
9017
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '全文已复制' });
|
|
9018
|
+
}).catch(() => {
|
|
9019
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '复制失败,请重试' });
|
|
9020
|
+
});
|
|
8970
9021
|
}
|
|
8971
9022
|
else if (overlay === 'help') {
|
|
8972
9023
|
if (key.escape || key.return || input.toLowerCase() === 'b' || input === '?') {
|
|
@@ -9072,31 +9123,31 @@ export function ConsoleAppV4(props) {
|
|
|
9072
9123
|
closeConfirmation();
|
|
9073
9124
|
requestSessionNavigation(navigation);
|
|
9074
9125
|
}
|
|
9075
|
-
else if ((
|
|
9076
|
-
|
|
9126
|
+
else if (input.toLowerCase() === 'y' && confirmationText !== undefined) {
|
|
9127
|
+
const currentRouteKey = `${routeKey}:confirmation`;
|
|
9128
|
+
void copyToClipboard(confirmationText).then(() => {
|
|
9129
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '全文已复制' });
|
|
9130
|
+
}).catch(() => {
|
|
9131
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '复制失败,请重试' });
|
|
9132
|
+
});
|
|
9133
|
+
}
|
|
9134
|
+
else if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9077
9135
|
&& confirmationPagination) {
|
|
9078
9136
|
const warningCount = confirmationPagination.total;
|
|
9079
9137
|
const warningLimit = confirmationPagination.pageRows;
|
|
9080
9138
|
setOperationConfirmation((current) => current ? {
|
|
9081
9139
|
...current,
|
|
9082
9140
|
warningOffset: Math.min(Math.max(0, warningCount - 1), Math.max(0, current.warningOffset
|
|
9083
|
-
+ (key.pageUp ||
|
|
9141
|
+
+ (key.pageUp || key.leftArrow ? -warningLimit : warningLimit))),
|
|
9084
9142
|
} : current);
|
|
9085
9143
|
}
|
|
9086
9144
|
else if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {
|
|
9087
|
-
setOverlayFocus((value) => moveIndex(
|
|
9145
|
+
setOverlayFocus((value) => moveIndex(2, value, key.upArrow || key.leftArrow ? -1 : 1));
|
|
9088
9146
|
}
|
|
9089
9147
|
else if (key.return) {
|
|
9090
9148
|
if (overlayFocus === 0) {
|
|
9091
9149
|
closeConfirmation();
|
|
9092
9150
|
}
|
|
9093
|
-
else if (confirmationPagination && (overlayFocus === 2 || overlayFocus === 3)) {
|
|
9094
|
-
const direction = overlayFocus === 2 ? -1 : 1;
|
|
9095
|
-
setOperationConfirmation((current) => current ? {
|
|
9096
|
-
...current,
|
|
9097
|
-
warningOffset: Math.min(Math.max(0, confirmationPagination.total - 1), Math.max(0, current.warningOffset + direction * confirmationPagination.pageRows)),
|
|
9098
|
-
} : current);
|
|
9099
|
-
}
|
|
9100
9151
|
else if (activeReview?.reviewToken !== operationConfirmation.reviewToken) {
|
|
9101
9152
|
closeConfirmation();
|
|
9102
9153
|
setActionError('确认内容已变化。请重新检查操作汇总。');
|
|
@@ -9266,22 +9317,31 @@ export function ConsoleAppV4(props) {
|
|
|
9266
9317
|
setReportSaveError(undefined);
|
|
9267
9318
|
return;
|
|
9268
9319
|
}
|
|
9269
|
-
if (
|
|
9320
|
+
if (input.toLowerCase() === 'y' && readingText !== undefined) {
|
|
9321
|
+
const currentRouteKey = routeKey;
|
|
9322
|
+
void copyToClipboard(readingText).then(() => {
|
|
9323
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '全文已复制' });
|
|
9324
|
+
}).catch(() => {
|
|
9325
|
+
setCopyFeedback({ routeKey: currentRouteKey, message: '复制失败,请重试' });
|
|
9326
|
+
});
|
|
9327
|
+
return;
|
|
9328
|
+
}
|
|
9329
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9270
9330
|
&& route.name === 'result' && portableResultDetailOpen
|
|
9271
9331
|
&& portableResultDetailPagination) {
|
|
9272
9332
|
const { total, pageRows } = portableResultDetailPagination;
|
|
9273
|
-
const direction = key.pageUp ||
|
|
9333
|
+
const direction = key.pageUp || key.leftArrow ? -1 : 1;
|
|
9274
9334
|
setPortableResultDetailOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + direction * pageRows)));
|
|
9275
9335
|
return;
|
|
9276
9336
|
}
|
|
9277
|
-
if ((key.pageUp || key.pageDown ||
|
|
9337
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9278
9338
|
&& route.name === 'portableDependencies' && plugin) {
|
|
9279
9339
|
const total = dependencyOverview(plugin)?.dependencies.length ?? 0;
|
|
9280
9340
|
const pageRows = showTechnical ? 1 : responsiveBudget(2, 3);
|
|
9281
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp ||
|
|
9341
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp || key.leftArrow ? -pageRows : pageRows))));
|
|
9282
9342
|
return;
|
|
9283
9343
|
}
|
|
9284
|
-
if ((key.pageUp || key.pageDown ||
|
|
9344
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9285
9345
|
&& (route.name === 'pluginContent'
|
|
9286
9346
|
|| route.name === 'pluginTechnical'
|
|
9287
9347
|
|| route.name === 'projectStatus' && showTechnical
|
|
@@ -9291,7 +9351,6 @@ export function ConsoleAppV4(props) {
|
|
|
9291
9351
|
|| route.name === 'sourceRemoveBlocked' && sourceDependenciesExpanded
|
|
9292
9352
|
|| route.name === 'pluginDependencies' && route.view === 'removeBlocked' && !showTechnical
|
|
9293
9353
|
|| route.name === 'pluginDependencyNode'
|
|
9294
|
-
&& (route.view === 'references' || route.view === 'details')
|
|
9295
9354
|
|| route.name === 'pluginDetail'
|
|
9296
9355
|
|| route.name === 'configSave' && route.view === 'changes'
|
|
9297
9356
|
|| route.name === 'configFields' && route.view === 'values'
|
|
@@ -9300,21 +9359,21 @@ export function ConsoleAppV4(props) {
|
|
|
9300
9359
|
|| route.name === 'result')
|
|
9301
9360
|
&& referenceDetailPagination) {
|
|
9302
9361
|
const { total, pageRows } = referenceDetailPagination;
|
|
9303
|
-
moveBatchTargetPage(total, pageRows, key.pageUp ||
|
|
9362
|
+
moveBatchTargetPage(total, pageRows, key.pageUp || key.leftArrow ? -1 : 1);
|
|
9304
9363
|
return;
|
|
9305
9364
|
}
|
|
9306
|
-
if ((key.pageUp || key.pageDown)
|
|
9365
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9307
9366
|
&& route.name === 'pluginWriteTask') {
|
|
9308
9367
|
const total = props.controller.listPluginWriteTaskCandidates(route.goal)
|
|
9309
9368
|
.filter((candidate) => candidate.target.pluginId === route.pluginId
|
|
9310
9369
|
&& (!route.targetKeys || route.targetKeys.includes(pluginWriteTaskTargetKey(candidate)))).length;
|
|
9311
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + (key.pageUp ? -1 : 1))));
|
|
9370
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + (key.pageUp || key.leftArrow ? -1 : 1))));
|
|
9312
9371
|
return;
|
|
9313
9372
|
}
|
|
9314
|
-
if ((key.pageUp || key.pageDown ||
|
|
9373
|
+
if ((key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)
|
|
9315
9374
|
&& route.name === 'sourceTechnical') {
|
|
9316
9375
|
const total = diagnosticDetailLines(resolveSourceTechnicalDiagnostic(route.sourceId), size.columns - 6).length;
|
|
9317
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - sourceTechnicalPageRows), Math.max(0, value + (key.pageUp ||
|
|
9376
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - sourceTechnicalPageRows), Math.max(0, value + (key.pageUp || key.leftArrow
|
|
9318
9377
|
? -sourceTechnicalPageRows : sourceTechnicalPageRows))));
|
|
9319
9378
|
return;
|
|
9320
9379
|
}
|
|
@@ -9338,15 +9397,16 @@ export function ConsoleAppV4(props) {
|
|
|
9338
9397
|
return;
|
|
9339
9398
|
}
|
|
9340
9399
|
if ((route.name === 'operationDiagnostic' || route.name === 'operationReportPreview')
|
|
9341
|
-
&& (key.pageUp || key.pageDown ||
|
|
9400
|
+
&& (key.pageUp || key.pageDown || key.leftArrow || key.rightArrow)) {
|
|
9342
9401
|
const detail = route.name === 'operationDiagnostic'
|
|
9343
9402
|
? props.controller.getOperationDiagnostic(route.recordId) : undefined;
|
|
9344
9403
|
const preview = route.name === 'operationReportPreview'
|
|
9345
9404
|
? props.controller.previewOperationReport(route.recordId) : undefined;
|
|
9346
9405
|
const total = detail ? operationDiagnosticLineCount(detail, size.columns)
|
|
9347
9406
|
: preview ? operationReportLineCount(preview, size.columns) : 0;
|
|
9348
|
-
const pageRows =
|
|
9349
|
-
|
|
9407
|
+
const pageRows = route.name === 'operationReportPreview'
|
|
9408
|
+
? operationReportPageRows : operationDetailPageRows;
|
|
9409
|
+
setScrollOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp || key.leftArrow ? -pageRows : pageRows))));
|
|
9350
9410
|
return;
|
|
9351
9411
|
}
|
|
9352
9412
|
if (route.name === 'portableAgentInput') {
|
|
@@ -9764,12 +9824,6 @@ export function ConsoleAppV4(props) {
|
|
|
9764
9824
|
setFocus(portableResultDetailReturnFocus.current);
|
|
9765
9825
|
setScrollOffset(0);
|
|
9766
9826
|
}
|
|
9767
|
-
else if (globalAction === 'back' && route.name === 'pluginDetail' && showTechnical) {
|
|
9768
|
-
setShowTechnical(false);
|
|
9769
|
-
setBatchTargetOffset(0);
|
|
9770
|
-
setFocus(0);
|
|
9771
|
-
setScrollOffset(0);
|
|
9772
|
-
}
|
|
9773
9827
|
else if (globalAction === 'back' && route.name === 'portableSkillSelect' && portableToolsOpen) {
|
|
9774
9828
|
setPortableToolsOpen(false);
|
|
9775
9829
|
setFocus(0);
|
|
@@ -9777,13 +9831,14 @@ export function ConsoleAppV4(props) {
|
|
|
9777
9831
|
}
|
|
9778
9832
|
else if (globalAction === 'back' && route.name === 'batchSelection'
|
|
9779
9833
|
&& batchDraft?.stage === 'select' && batchDraft.showSelectionTools) {
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9834
|
+
closeBatchSelectionTools();
|
|
9835
|
+
}
|
|
9836
|
+
else if (globalAction === 'back' && route.name === 'installPlacement'
|
|
9837
|
+
&& returnToPreviousInstallPlatform) {
|
|
9838
|
+
returnToPreviousInstallPlatform();
|
|
9783
9839
|
}
|
|
9784
9840
|
else if (globalAction === 'back'
|
|
9785
|
-
&& (route.name === 'configSave' || route.name === 'sourceSave')
|
|
9786
|
-
&& route.view === 'changes') {
|
|
9841
|
+
&& (route.name === 'configSave' || route.name === 'sourceSave' && route.view === 'changes')) {
|
|
9787
9842
|
back();
|
|
9788
9843
|
}
|
|
9789
9844
|
else if (globalAction === 'back' && route.name === 'configLayer') {
|
|
@@ -10032,6 +10087,19 @@ export function ConsoleAppV4(props) {
|
|
|
10032
10087
|
if (tooSmall && !overlay) {
|
|
10033
10088
|
return (_jsx(ScreenFrame, { title: "\u7EC8\u7AEF\u7A7A\u95F4\u4E0D\u8DB3", breadcrumb: "\u7EC8\u7AEF\u7A7A\u95F4\u4E0D\u8DB3", context: `${size.columns} × ${size.rows}`, help: "q \u9000\u51FA", size: size, children: _jsx(Callout, { status: "warning", title: "\u2194 \u8BF7\u5C06\u7EC8\u7AEF\u8C03\u6574\u5230\u81F3\u5C11 60 \u00D7 18", description: "\u8C03\u6574\u540E\u4F1A\u8FD4\u56DE\u539F\u9875\u9762\uFF0C\u4E0D\u4F1A\u4E22\u5931\u5F53\u524D\u9009\u62E9\u3002" }) }));
|
|
10034
10089
|
}
|
|
10090
|
+
if (readingText !== undefined && route.name !== 'progress') {
|
|
10091
|
+
const paginated = referenceDetailPagination !== undefined
|
|
10092
|
+
|| portableResultDetailPagination !== undefined
|
|
10093
|
+
|| route.name === 'sourceTechnical'
|
|
10094
|
+
|| route.name === 'operationDiagnostic'
|
|
10095
|
+
|| route.name === 'operationReportPreview'
|
|
10096
|
+
|| route.name === 'portableDependencies';
|
|
10097
|
+
help = `${paginated ? '←→ 翻页 · ' : ''}[y] 复制全文 · Esc 返回${supportsTechnicalDetails
|
|
10098
|
+
? ' · d 技术详情' : ''} · ${size.columns < 80
|
|
10099
|
+
? '↑↓/Enter 菜单' : '↑↓ 移动 · Enter 选择'}`;
|
|
10100
|
+
if (copyFeedback?.routeKey === routeKey)
|
|
10101
|
+
description = copyFeedback.message;
|
|
10102
|
+
}
|
|
10035
10103
|
if (actionError)
|
|
10036
10104
|
description = actionError;
|
|
10037
10105
|
const base = (_jsx(ScreenFrame, { title: projectReminderOpen ? '' : title, description: projectReminderOpen ? undefined : description, breadcrumb: breadcrumb, context: context, help: portableEmptySelectionOpen ? 'Enter 返回选择 · Esc 返回' : help, size: size, children: projectReminderOpen || sourceTransportOverlay ? null : content }));
|
|
@@ -10087,12 +10155,13 @@ export function ConsoleAppV4(props) {
|
|
|
10087
10155
|
const visibleWarnings = shortConfirmation
|
|
10088
10156
|
? warningLines : warningLines.slice(warningOffset, warningOffset + warningLimit);
|
|
10089
10157
|
const warningPaginated = !shortConfirmation && warningLines.length > warningLimit;
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10158
|
+
confirmationText = portableUserConfirmation
|
|
10159
|
+
? '! 本次在所有项目范围安装选定 Skills。\n具体对象和范围以刚才的汇总为准。'
|
|
10160
|
+
: [
|
|
10161
|
+
`操作:${review.title} · ${review.subject.name}`,
|
|
10162
|
+
...(review.confirmationDetails ?? []),
|
|
10163
|
+
...operationRiskWarnings(review).map((warning) => `! ${warning}`),
|
|
10164
|
+
].join('\n');
|
|
10096
10165
|
if (warningPaginated) {
|
|
10097
10166
|
confirmationPagination = { total: warningLines.length, pageRows: warningLimit };
|
|
10098
10167
|
}
|
|
@@ -10102,14 +10171,9 @@ export function ConsoleAppV4(props) {
|
|
|
10102
10171
|
label: portableUserConfirmation ? '确认并执行' : `我已了解影响,${review.primaryLabel}`,
|
|
10103
10172
|
status: 'error',
|
|
10104
10173
|
},
|
|
10105
|
-
...(warningPaginated ? paginationActions({
|
|
10106
|
-
offset: warningOffset,
|
|
10107
|
-
total: warningLines.length,
|
|
10108
|
-
pageRows: warningLimit,
|
|
10109
|
-
move: moveWarningPage,
|
|
10110
|
-
}) : []),
|
|
10111
10174
|
];
|
|
10112
|
-
const confirmationCard = (_jsxs(ReviewCard, { title: portableUserConfirmation ? '确认本次影响' : '请确认本次风险', description:
|
|
10175
|
+
const confirmationCard = (_jsxs(ReviewCard, { title: portableUserConfirmation ? '确认本次影响' : '请确认本次风险', description: `${copyFeedback?.routeKey === `${routeKey}:confirmation`
|
|
10176
|
+
? `${copyFeedback.message} · ` : ''}确认只对当前操作汇总有效;[y] 复制全文。`, children: [!shortConfirmation && warningOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${warningOffset} 行`, status: "muted", compact: true }) : null, visibleWarnings.length > 0
|
|
10113
10177
|
? visibleWarnings.map((warning, index) => _jsx(StaticRow, { title: warning, status: warning.startsWith('! ') ? 'warning' : 'info', compact: true }, `${warningOffset + index}:${warning}`))
|
|
10114
10178
|
: _jsx(StaticRow, { title: "! \u6B64\u64CD\u4F5C\u9700\u8981\u660E\u786E\u6388\u6743", status: "warning", compact: true }), !shortConfirmation && warningLines.length - warningOffset - visibleWarnings.length > 0
|
|
10115
10179
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${warningLines.length - warningOffset - visibleWarnings.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: confirmationActions, focus: overlayFocus, kind: "action", compact: true })] }));
|
|
@@ -10118,7 +10182,7 @@ export function ConsoleAppV4(props) {
|
|
|
10118
10182
|
}
|
|
10119
10183
|
return _jsx(ScreenFrame, { title: review.operationKind === 'catalogStorePrune'
|
|
10120
10184
|
? `确认${review.title}?`
|
|
10121
|
-
: `确认${review.title} ${review.subject.name}?`, breadcrumb: `${review.subject.name} / 风险确认`, context: "\u72EC\u7ACB\u6388\u6743", help: "PgUp/PgDn \
|
|
10185
|
+
: `确认${review.title} ${review.subject.name}?`, breadcrumb: `${review.subject.name} / 风险确认`, context: "\u72EC\u7ACB\u6388\u6743", help: "\u2190\u2192/PgUp/PgDn \u7FFB\u9875 \u00B7 [y] \u590D\u5236\u5168\u6587 \u00B7 Esc \u8FD4\u56DE", size: size, children: confirmationCard });
|
|
10122
10186
|
}
|
|
10123
10187
|
if (sourceTransportOverlay) {
|
|
10124
10188
|
const configuredSource = route.name === 'sourceEdit'
|