@lesliechan721/aw 0.1.0-beta.19 → 0.1.0-beta.21
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/commands/rebuild-command.js +0 -5
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +0 -1
- package/dist/src/commands/rebuild-integration.js +3 -152
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/status-v6.js +44 -25
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/tui/components.d.ts +1 -0
- package/dist/src/tui/components.js +3 -1
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +1 -1
- package/dist/src/tui/console-app-v4.js +765 -1129
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +94 -51
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +4 -30
- package/dist/src/tui/controller.js +11 -219
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/dependency-graph.d.ts +3 -3
- package/dist/src/tui/dependency-graph.js +15 -14
- package/dist/src/tui/dependency-graph.js.map +1 -1
- package/dist/src/tui/glossary.d.ts +1 -1
- package/dist/src/tui/glossary.js +1 -1
- package/dist/src/tui/glossary.js.map +1 -1
- package/dist/src/tui/model.d.ts +2 -0
- package/dist/src/tui/model.js +63 -30
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-review-planner.js +8 -195
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/tui/plugin-write-task.js +4 -0
- package/dist/src/tui/plugin-write-task.js.map +1 -1
- package/dist/src/tui/router.d.ts +4 -16
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/screen-registry.d.ts +10 -57
- package/dist/src/tui/screen-registry.js +1 -15
- package/dist/src/tui/screen-registry.js.map +1 -1
- package/package.json +3 -3
- package/dist/src/tui/catalog-management-screens.d.ts +0 -45
- package/dist/src/tui/catalog-management-screens.js +0 -25
- package/dist/src/tui/catalog-management-screens.js.map +0 -1
- package/dist/src/tui/catalog-management.d.ts +0 -240
- package/dist/src/tui/catalog-management.js +0 -856
- package/dist/src/tui/catalog-management.js.map +0 -1
|
@@ -16,7 +16,6 @@ import { safeDiagnosticCode, sanitizeDiagnosticText, } from './diagnostics.js';
|
|
|
16
16
|
import { extractPortableError, TuiConfigInvalidStoreError, userIssueKey, } from './controller.js';
|
|
17
17
|
import { pluginWriteTaskVersionEvidence } from './plugin-write-task.js';
|
|
18
18
|
import { catalogSourceFreshnessLabel, catalogSourceListPresentation, } from './catalog-sources/screens.js';
|
|
19
|
-
import { CatalogManagementIntro, CatalogPublicationSummary, CatalogStoreSummary, CatalogWorkspaceSummary, } from './catalog-management-screens.js';
|
|
20
19
|
import { operationDiagnosticLineCount, operationHistoryMeta, operationHistoryState, operationReportLineCount, OperationDiagnosticScreen, OperationReportPreviewScreen, } from './operation-diagnostic-screens.js';
|
|
21
20
|
import { resolveTuiSizePolicy } from './layout.js';
|
|
22
21
|
import { buildDependencyGraphProjection, } from './dependency-graph.js';
|
|
@@ -34,7 +33,6 @@ function sourceOperationBlockLabel(reason) {
|
|
|
34
33
|
case 'configDraft': return '未保存的插件设置';
|
|
35
34
|
case 'sourceDraft': return '未保存的来源修改';
|
|
36
35
|
case 'batchDraft': return '未完成的批量操作选择';
|
|
37
|
-
case 'catalogDraft': return '未完成的 Catalog 管理输入';
|
|
38
36
|
case 'portableDraft': return '未完成的通用 Skills 选择';
|
|
39
37
|
case 'activeReview': return '等待确认的操作';
|
|
40
38
|
case 'reviewPreparation': return '正在准备确认信息的操作';
|
|
@@ -69,14 +67,7 @@ function batchPluginVersionSummary(plugin) {
|
|
|
69
67
|
? changes[0]
|
|
70
68
|
: `${updates.length} 个位置版本不同(Enter 查看)`;
|
|
71
69
|
}
|
|
72
|
-
function
|
|
73
|
-
if (placement.state === 'notInstalled')
|
|
74
|
-
return { text: '未添加', status: 'muted' };
|
|
75
|
-
if (placement.state === 'blocked')
|
|
76
|
-
return { text: '无法添加:输出位置有冲突', status: 'error' };
|
|
77
|
-
if (placement.state === 'scopeConflict')
|
|
78
|
-
return { text: '使用位置冲突,需要选择一个位置', status: 'warning' };
|
|
79
|
-
const location = placement.desiredScopes?.map(scopeLabel).join('、') || scopeLabel(placement.scope);
|
|
70
|
+
function scopedPluginPlacementConclusion(placement, location) {
|
|
80
71
|
if (placement.blockingReason === 'artifactCollision' || placement.actualState === 'blocked') {
|
|
81
72
|
return { text: `${location}暂时不可用`, status: 'error' };
|
|
82
73
|
}
|
|
@@ -87,6 +78,42 @@ function pluginPlacementConclusion(placement) {
|
|
|
87
78
|
return { text: `${location}状态未知`, status: 'warning' };
|
|
88
79
|
return { text: `${location}可用`, status: 'success' };
|
|
89
80
|
}
|
|
81
|
+
function pluginPlacementConclusions(placement) {
|
|
82
|
+
if (placement.state === 'notInstalled')
|
|
83
|
+
return [{ text: '未添加', status: 'muted' }];
|
|
84
|
+
if (placement.state === 'blocked')
|
|
85
|
+
return [{ text: '无法添加:输出位置有冲突', status: 'error' }];
|
|
86
|
+
if (placement.state === 'scopeConflict')
|
|
87
|
+
return [{ text: '使用位置冲突,需要选择一个位置', status: 'warning' }];
|
|
88
|
+
if (!placement.scopedPlacements?.length) {
|
|
89
|
+
const location = placement.desiredScopes?.map(scopeLabel).join('、') || scopeLabel(placement.scope);
|
|
90
|
+
return [scopedPluginPlacementConclusion(placement, location)];
|
|
91
|
+
}
|
|
92
|
+
const grouped = new Map();
|
|
93
|
+
for (const scoped of placement.scopedPlacements) {
|
|
94
|
+
const conclusion = scopedPluginPlacementConclusion({
|
|
95
|
+
platform: placement.platform,
|
|
96
|
+
state: 'installed',
|
|
97
|
+
scope: scoped.scope,
|
|
98
|
+
health: scoped.health,
|
|
99
|
+
revision: scoped.revision,
|
|
100
|
+
desiredScopes: [scoped.scope],
|
|
101
|
+
...(scoped.actualState ? { actualState: scoped.actualState } : {}),
|
|
102
|
+
...(scoped.recovery ? { recovery: scoped.recovery } : {}),
|
|
103
|
+
...(scoped.blockingReason ? { blockingReason: scoped.blockingReason } : {}),
|
|
104
|
+
}, '');
|
|
105
|
+
const key = `${conclusion.status}\0${conclusion.text}`;
|
|
106
|
+
const current = grouped.get(key);
|
|
107
|
+
if (current)
|
|
108
|
+
current.scopes.push(scoped.scope);
|
|
109
|
+
else
|
|
110
|
+
grouped.set(key, { scopes: [scoped.scope], status: conclusion.status, suffix: conclusion.text });
|
|
111
|
+
}
|
|
112
|
+
return [...grouped.values()].map((entry) => ({
|
|
113
|
+
text: `${entry.scopes.map(scopeLabel).join('、')}${entry.suffix}`,
|
|
114
|
+
status: entry.status,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
90
117
|
function isCharacterInputMode(route, searchMode) {
|
|
91
118
|
if (routeDefinition(route).keymap !== 'menuOrTextInput')
|
|
92
119
|
return false;
|
|
@@ -98,13 +125,17 @@ function isCharacterInputMode(route, searchMode) {
|
|
|
98
125
|
|| route.name === 'configObjectPropertyEditor'
|
|
99
126
|
&& (route.stage === 'key' || route.stage === 'custom')
|
|
100
127
|
|| route.name === 'sourceAdd' && route.step !== 'type' && route.step !== 'refPolicy'
|
|
101
|
-
|| route.name === 'catalogWorkspace'
|
|
102
|
-
&& (route.view === 'select' || route.view === 'create'
|
|
103
|
-
|| route.view === 'version' && route.step === 'catalogVersion')
|
|
104
|
-
|| route.name === 'catalogDev' && route.step !== undefined && route.step !== 'overview'
|
|
105
|
-
|| route.name === 'catalogPublish' && route.step !== 'overview'
|
|
106
128
|
|| route.name === 'scriptTimeout';
|
|
107
129
|
}
|
|
130
|
+
function supportsScriptTimeout(intent) {
|
|
131
|
+
return intent?.kind === 'pluginWrite'
|
|
132
|
+
&& (intent.action === 'install' || intent.action === 'sync'
|
|
133
|
+
|| intent.action === 'refreshAndSync' || intent.action === 'reinstall')
|
|
134
|
+
|| intent?.kind === 'pluginWriteBatch'
|
|
135
|
+
&& (intent.action === 'install' || intent.action === 'sync' || intent.action === 'reinstall')
|
|
136
|
+
|| intent?.kind === 'pluginWriteTask'
|
|
137
|
+
|| intent?.kind === 'configSave' && intent.apply;
|
|
138
|
+
}
|
|
108
139
|
function helpRowsForRoute(route, actionCount, supportsTechnicalDetails, busy, sessionNavigation) {
|
|
109
140
|
const rows = [];
|
|
110
141
|
if (!busy && actionCount > 1)
|
|
@@ -354,6 +385,17 @@ function wrapConsoleText(value, columns) {
|
|
|
354
385
|
lines.push(line);
|
|
355
386
|
return lines;
|
|
356
387
|
}
|
|
388
|
+
function changeDetailLines(changes, columns) {
|
|
389
|
+
const valueLines = (label, value) => [
|
|
390
|
+
label,
|
|
391
|
+
...wrapConsoleText(value ?? '未设置', Math.max(1, columns - 4)).map((line) => ` ${line}`),
|
|
392
|
+
];
|
|
393
|
+
return changes.flatMap((change) => [
|
|
394
|
+
`修改项 · ${change.title}`,
|
|
395
|
+
...valueLines('修改前', change.before),
|
|
396
|
+
...valueLines('修改后', change.after),
|
|
397
|
+
]);
|
|
398
|
+
}
|
|
357
399
|
function operationRiskWarnings(review) {
|
|
358
400
|
return [...new Set([
|
|
359
401
|
...(review.sharedImpact.warning ? [review.sharedImpact.warning] : []),
|
|
@@ -884,7 +926,7 @@ function dependencyReferenceUsageLabel(reference, consumerName) {
|
|
|
884
926
|
const location = reference.consumer.scope === 'user'
|
|
885
927
|
? '所有项目'
|
|
886
928
|
: reference.consumer.project === 'current' ? '当前项目' : '其他项目';
|
|
887
|
-
return `${consumerName}
|
|
929
|
+
return `${consumerName} · ${location} · ${platformLabel(reference.consumer.platform)}`;
|
|
888
930
|
}
|
|
889
931
|
function dependencySummaryText(summary) {
|
|
890
932
|
return `${summary.directCount} 个直接 · ${summary.totalCount} 个总计`;
|
|
@@ -1002,23 +1044,9 @@ export function ConsoleAppV4(props) {
|
|
|
1002
1044
|
const [expandedDependencyPluginIds, setExpandedDependencyPluginIds] = useState();
|
|
1003
1045
|
const [sourceInput, setSourceInput] = useState('');
|
|
1004
1046
|
const [sourceInputError, setSourceInputError] = useState();
|
|
1005
|
-
const [catalogInput, setCatalogInput] = useState('');
|
|
1006
|
-
const [catalogInputError, setCatalogInputError] = useState();
|
|
1007
|
-
const [catalogWorkspace, setCatalogWorkspace] = useState();
|
|
1008
|
-
const [catalogValidation, setCatalogValidation] = useState();
|
|
1009
|
-
const [catalogDev, setCatalogDev] = useState();
|
|
1010
|
-
const [catalogStore, setCatalogStore] = useState();
|
|
1011
|
-
const [catalogPublication, setCatalogPublication] = useState();
|
|
1012
|
-
const [catalogLoading, setCatalogLoading] = useState(false);
|
|
1013
|
-
const [catalogWorkspaceDraft, setCatalogWorkspaceDraft] = useState({
|
|
1014
|
-
ownerName: '', ownerUrl: '', displayName: '', catalogVersion: '0.1.0',
|
|
1015
|
-
});
|
|
1016
|
-
const [catalogPublishDraft, setCatalogPublishDraft] = useState({
|
|
1017
|
-
targetKind: 'remote', target: '', branch: 'catalog',
|
|
1018
|
-
});
|
|
1019
|
-
const [catalogDevSourceId, setCatalogDevSourceId] = useState('');
|
|
1020
1047
|
const [pendingReviewIntent, setPendingReviewIntent] = useState();
|
|
1021
1048
|
const pendingReviewIntentRef = useRef(undefined);
|
|
1049
|
+
const pendingActionFocus = useRef(undefined);
|
|
1022
1050
|
const [scriptTimeoutInput, setScriptTimeoutInput] = useState(String(SCRIPT_TIMEOUT_DEFAULT_MS));
|
|
1023
1051
|
const [scriptTimeoutError, setScriptTimeoutError] = useState();
|
|
1024
1052
|
const [sourceReferenceSummary, setSourceReferenceSummary] = useState();
|
|
@@ -1033,10 +1061,9 @@ export function ConsoleAppV4(props) {
|
|
|
1033
1061
|
const [pendingLayerFieldKey, setPendingLayerFieldKey] = useState();
|
|
1034
1062
|
const dynamicMenuFocus = useRef(undefined);
|
|
1035
1063
|
const dependencyGraphContexts = useRef(new Map());
|
|
1036
|
-
const externalDraftRevision = useRef({ config: 0, source: 0, batch: 0
|
|
1064
|
+
const externalDraftRevision = useRef({ config: 0, source: 0, batch: 0 });
|
|
1037
1065
|
const previousExternalDraftValues = useRef({
|
|
1038
1066
|
draftUpdates, draftRemoves, objectDrafts, changedObjectDraftKeys, sourceDraft, batchDraft,
|
|
1039
|
-
catalogInput, catalogWorkspaceDraft, catalogPublishDraft, catalogDevSourceId,
|
|
1040
1067
|
});
|
|
1041
1068
|
const externalDraftFlowIds = useRef(new Map());
|
|
1042
1069
|
const exitSent = useRef(false);
|
|
@@ -1152,23 +1179,6 @@ export function ConsoleAppV4(props) {
|
|
|
1152
1179
|
setBatchDraft(undefined);
|
|
1153
1180
|
setDirty(false);
|
|
1154
1181
|
}, [batchDraft?.flowId, route.name, snapshot.result]);
|
|
1155
|
-
useEffect(() => {
|
|
1156
|
-
if (route.name !== 'result'
|
|
1157
|
-
|| snapshot.result?.state !== 'succeeded'
|
|
1158
|
-
|| snapshot.result.operationKind !== 'catalogManagement')
|
|
1159
|
-
return;
|
|
1160
|
-
const action = snapshot.result.summary.catalogManagement?.action;
|
|
1161
|
-
if (action === 'workspaceInit') {
|
|
1162
|
-
setCatalogInput('');
|
|
1163
|
-
setCatalogWorkspaceDraft({
|
|
1164
|
-
ownerName: '', ownerUrl: '', displayName: '', catalogVersion: '0.1.0',
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
if (action === 'publishApply') {
|
|
1168
|
-
setCatalogInput('');
|
|
1169
|
-
setCatalogPublishDraft({ targetKind: 'remote', target: '', branch: 'catalog' });
|
|
1170
|
-
}
|
|
1171
|
-
}, [route.name, snapshot.result]);
|
|
1172
1182
|
useEffect(() => {
|
|
1173
1183
|
if (!batchDraft || (route.name !== 'batchSelection' && route.name !== 'batchPlacement'))
|
|
1174
1184
|
return;
|
|
@@ -1178,74 +1188,6 @@ export function ConsoleAppV4(props) {
|
|
|
1178
1188
|
if (route.name !== 'sourceAdd')
|
|
1179
1189
|
setSourceInput('');
|
|
1180
1190
|
}, [route.name]);
|
|
1181
|
-
useEffect(() => {
|
|
1182
|
-
if (route.name !== 'catalogWorkspace' || route.view !== 'overview')
|
|
1183
|
-
return;
|
|
1184
|
-
let current = true;
|
|
1185
|
-
setCatalogLoading(true);
|
|
1186
|
-
setCatalogInputError(undefined);
|
|
1187
|
-
void props.controller.getCatalogWorkspaceManagement()
|
|
1188
|
-
.then((value) => { if (current)
|
|
1189
|
-
setCatalogWorkspace(value); })
|
|
1190
|
-
.catch((error) => {
|
|
1191
|
-
if (current)
|
|
1192
|
-
setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], [catalogInput]));
|
|
1193
|
-
})
|
|
1194
|
-
.finally(() => { if (current)
|
|
1195
|
-
setCatalogLoading(false); });
|
|
1196
|
-
return () => { current = false; };
|
|
1197
|
-
}, [props.controller, route.name, route.name === 'catalogWorkspace' ? route.view : '']);
|
|
1198
|
-
useEffect(() => {
|
|
1199
|
-
if (route.name !== 'catalogDev' || route.step && route.step !== 'overview')
|
|
1200
|
-
return;
|
|
1201
|
-
let current = true;
|
|
1202
|
-
setCatalogLoading(true);
|
|
1203
|
-
setCatalogInputError(undefined);
|
|
1204
|
-
void props.controller.getCatalogDevManagement()
|
|
1205
|
-
.then((value) => { if (current)
|
|
1206
|
-
setCatalogDev(value); })
|
|
1207
|
-
.catch((error) => {
|
|
1208
|
-
if (current)
|
|
1209
|
-
setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], [catalogInput]));
|
|
1210
|
-
})
|
|
1211
|
-
.finally(() => { if (current)
|
|
1212
|
-
setCatalogLoading(false); });
|
|
1213
|
-
return () => { current = false; };
|
|
1214
|
-
}, [props.controller, route.name, route.name === 'catalogDev' ? route.step : '']);
|
|
1215
|
-
useEffect(() => {
|
|
1216
|
-
if (route.name !== 'catalogStore')
|
|
1217
|
-
return;
|
|
1218
|
-
let current = true;
|
|
1219
|
-
setCatalogLoading(true);
|
|
1220
|
-
setCatalogInputError(undefined);
|
|
1221
|
-
void props.controller.getCatalogStoreManagement()
|
|
1222
|
-
.then((value) => { if (current)
|
|
1223
|
-
setCatalogStore(value); })
|
|
1224
|
-
.catch((error) => {
|
|
1225
|
-
if (current)
|
|
1226
|
-
setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], []));
|
|
1227
|
-
})
|
|
1228
|
-
.finally(() => { if (current)
|
|
1229
|
-
setCatalogLoading(false); });
|
|
1230
|
-
return () => { current = false; };
|
|
1231
|
-
}, [props.controller, route.name]);
|
|
1232
|
-
useEffect(() => {
|
|
1233
|
-
if (route.name !== 'catalogPublish' || route.step !== 'overview')
|
|
1234
|
-
return;
|
|
1235
|
-
let current = true;
|
|
1236
|
-
setCatalogLoading(true);
|
|
1237
|
-
setCatalogInputError(undefined);
|
|
1238
|
-
void props.controller.getCatalogPublicationManagement()
|
|
1239
|
-
.then((value) => { if (current)
|
|
1240
|
-
setCatalogPublication(value); })
|
|
1241
|
-
.catch((error) => {
|
|
1242
|
-
if (current)
|
|
1243
|
-
setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], [catalogPublishDraft.target]));
|
|
1244
|
-
})
|
|
1245
|
-
.finally(() => { if (current)
|
|
1246
|
-
setCatalogLoading(false); });
|
|
1247
|
-
return () => { current = false; };
|
|
1248
|
-
}, [props.controller, route.name, route.name === 'catalogPublish' ? route.step : '']);
|
|
1249
1191
|
useEffect(() => {
|
|
1250
1192
|
if (route.name === 'operationReportPreview')
|
|
1251
1193
|
return;
|
|
@@ -1291,14 +1233,8 @@ export function ConsoleAppV4(props) {
|
|
|
1291
1233
|
externalDraftRevision.current.source += 1;
|
|
1292
1234
|
if (previous.batchDraft !== batchDraft)
|
|
1293
1235
|
externalDraftRevision.current.batch += 1;
|
|
1294
|
-
if (previous.catalogInput !== catalogInput
|
|
1295
|
-
|| previous.catalogWorkspaceDraft !== catalogWorkspaceDraft
|
|
1296
|
-
|| previous.catalogPublishDraft !== catalogPublishDraft
|
|
1297
|
-
|| previous.catalogDevSourceId !== catalogDevSourceId)
|
|
1298
|
-
externalDraftRevision.current.catalog += 1;
|
|
1299
1236
|
previousExternalDraftValues.current = {
|
|
1300
1237
|
draftUpdates, draftRemoves, objectDrafts, changedObjectDraftKeys, sourceDraft, batchDraft,
|
|
1301
|
-
catalogInput, catalogWorkspaceDraft, catalogPublishDraft, catalogDevSourceId,
|
|
1302
1238
|
};
|
|
1303
1239
|
const currentFlowId = snapshot.router.currentFlowId;
|
|
1304
1240
|
if (currentFlowId && configRouteOwner) {
|
|
@@ -1327,26 +1263,10 @@ export function ConsoleAppV4(props) {
|
|
|
1327
1263
|
flowId: batchDraft.flowId,
|
|
1328
1264
|
});
|
|
1329
1265
|
}
|
|
1330
|
-
const catalogWorkspaceDirty = catalogWorkspaceDraft.ownerName !== ''
|
|
1331
|
-
|| catalogWorkspaceDraft.ownerUrl !== '' || catalogWorkspaceDraft.displayName !== '';
|
|
1332
|
-
const catalogPublishDirty = catalogPublishDraft.target !== '';
|
|
1333
|
-
const catalogDraftActive = route.name === 'catalogWorkspace'
|
|
1334
|
-
&& (route.view === 'create' || route.view === 'version' && route.step === 'catalogVersion')
|
|
1335
|
-
|| route.name === 'catalogPublish' && route.step !== 'overview'
|
|
1336
|
-
|| route.name === 'catalogDev' && route.step !== undefined && route.step !== 'overview'
|
|
1337
|
-
|| route.name === 'catalogWorkspace' && route.view === 'overview' && catalogWorkspaceDirty
|
|
1338
|
-
|| route.name === 'catalogPublish' && route.step === 'overview' && catalogPublishDirty;
|
|
1339
|
-
if (catalogDraftActive)
|
|
1340
|
-
drafts.push({
|
|
1341
|
-
kind: 'catalogDraft', owner: 'catalog-management', revision: externalDraftRevision.current.catalog,
|
|
1342
|
-
});
|
|
1343
1266
|
props.controller.setExternalDraftState(drafts);
|
|
1344
1267
|
}, [
|
|
1345
1268
|
props.controller, batchDraft, changedObjectDraftKeys, configRouteOwner, dirty, draftOwner,
|
|
1346
|
-
draftRemoves, draftUpdates, objectDrafts, snapshot.router.currentFlowId, sourceDraft,
|
|
1347
|
-
catalogInput, catalogWorkspaceDraft, catalogPublishDraft, catalogDevSourceId, route.name,
|
|
1348
|
-
route.name === 'catalogWorkspace' ? `${route.view}:${route.step ?? ''}` : '',
|
|
1349
|
-
route.name === 'catalogPublish' || route.name === 'catalogDev' ? route.step : '',
|
|
1269
|
+
draftRemoves, draftUpdates, objectDrafts, route.name, snapshot.router.currentFlowId, sourceDraft,
|
|
1350
1270
|
]);
|
|
1351
1271
|
useEffect(() => () => props.controller.setExternalDraftState(), [props.controller]);
|
|
1352
1272
|
const currentConfigPage = configPageMatches(configPage, configRoute) ? configPage : undefined;
|
|
@@ -1521,7 +1441,7 @@ export function ConsoleAppV4(props) {
|
|
|
1521
1441
|
useEffect(() => {
|
|
1522
1442
|
let count;
|
|
1523
1443
|
if (route.name === 'sourceList')
|
|
1524
|
-
count = props.controller.listSources().length +
|
|
1444
|
+
count = props.controller.listSources().length + 2;
|
|
1525
1445
|
else if (route.name === 'issueList') {
|
|
1526
1446
|
const issueCount = props.controller.listUserIssues().length;
|
|
1527
1447
|
count = issueCount || 2;
|
|
@@ -1823,6 +1743,7 @@ export function ConsoleAppV4(props) {
|
|
|
1823
1743
|
let content;
|
|
1824
1744
|
let actions = [];
|
|
1825
1745
|
let referenceDetailPagination;
|
|
1746
|
+
let placementConclusionPagination;
|
|
1826
1747
|
let pluginRows = [];
|
|
1827
1748
|
let visibleConfigTabs = [];
|
|
1828
1749
|
let activeConfigTabId;
|
|
@@ -2012,16 +1933,8 @@ export function ConsoleAppV4(props) {
|
|
|
2012
1933
|
setActionError(undefined);
|
|
2013
1934
|
};
|
|
2014
1935
|
const beginReview = (intent, returnRoute) => {
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|| intent.action === 'refreshAndSync' || intent.action === 'reinstall')
|
|
2018
|
-
|| intent.kind === 'pluginWriteBatch'
|
|
2019
|
-
&& (intent.action === 'install' || intent.action === 'sync' || intent.action === 'reinstall')
|
|
2020
|
-
|| intent.kind === 'pluginWriteTask'
|
|
2021
|
-
|| intent.kind === 'configSave' && intent.apply;
|
|
2022
|
-
const pendingIntent = supportsScriptTimeout ? intent : undefined;
|
|
2023
|
-
pendingReviewIntentRef.current = pendingIntent;
|
|
2024
|
-
setPendingReviewIntent(pendingIntent);
|
|
1936
|
+
pendingReviewIntentRef.current = intent;
|
|
1937
|
+
setPendingReviewIntent(intent);
|
|
2025
1938
|
const underlyingResultRoute = returnRoute ?? (route.name === 'result' && snapshot.result && 'returnRoute' in snapshot.result
|
|
2026
1939
|
? snapshot.result.returnRoute
|
|
2027
1940
|
: undefined);
|
|
@@ -2358,7 +2271,7 @@ export function ConsoleAppV4(props) {
|
|
|
2358
2271
|
const beginRestrictedForceCleanup = async (pluginId, platform, selectedScope) => {
|
|
2359
2272
|
const candidate = await props.controller.getForceCleanupCandidate(pluginId, platform, selectedScope);
|
|
2360
2273
|
if (!candidate) {
|
|
2361
|
-
setActionError('
|
|
2274
|
+
setActionError('当前没有可安全确认的受限清理目标。不属于插件、被共用、符号链接和原生内容会保持不变。');
|
|
2362
2275
|
return;
|
|
2363
2276
|
}
|
|
2364
2277
|
try {
|
|
@@ -3250,7 +3163,7 @@ export function ConsoleAppV4(props) {
|
|
|
3250
3163
|
description = batchDraft?.stage === 'select'
|
|
3251
3164
|
? 'Space 切换选择,Enter 查看插件。选择会跨来源、搜索和筛选保留。'
|
|
3252
3165
|
: batchDraft?.stage === 'task'
|
|
3253
|
-
? '
|
|
3166
|
+
? '更新和恢复沿用已经添加的位置;移除会逐项显示已有位置。'
|
|
3254
3167
|
: '同步、重新安装和普通清理使用所选插件的已有位置。';
|
|
3255
3168
|
if (!batchDraft) {
|
|
3256
3169
|
actions = [{ label: '返回插件列表', run: back }];
|
|
@@ -3312,9 +3225,10 @@ export function ConsoleAppV4(props) {
|
|
|
3312
3225
|
}
|
|
3313
3226
|
};
|
|
3314
3227
|
const continueAction = {
|
|
3228
|
+
actionId: 'batch-selection-continue',
|
|
3315
3229
|
label: `查看确认(${batchDraft.selectedPluginIds.length})`,
|
|
3316
3230
|
description: batchDraft.selectedPluginIds.length > 0
|
|
3317
|
-
? batchDraft.recommendedGoal ? '
|
|
3231
|
+
? batchDraft.recommendedGoal ? '重新读取更新信息并显示操作汇总' : '继续选择任务和确认范围'
|
|
3318
3232
|
: '先选择至少一个插件',
|
|
3319
3233
|
disabled: batchDraft.selectedPluginIds.length === 0 ? '先选择至少一个插件' : undefined,
|
|
3320
3234
|
run: continueSelection,
|
|
@@ -3434,7 +3348,7 @@ export function ConsoleAppV4(props) {
|
|
|
3434
3348
|
actions = [
|
|
3435
3349
|
{ label: '同步已保存使用设置…', description: `重新应用 ${syncTargets.length} 个已保存或现场目标`, run: () => startExistingBatch('sync') },
|
|
3436
3350
|
{ label: '重新安装…', description: `重新生成 ${props.controller.listPluginWriteBatchTargets('reinstall', selectedIds).length} 个已保存或现场目标`, run: () => startExistingBatch('reinstall') },
|
|
3437
|
-
{ label: '清理遗留内容…', description: `${props.controller.listPluginWriteBatchTargets('cleanup', selectedIds).length}
|
|
3351
|
+
{ label: '清理遗留内容…', description: `${props.controller.listPluginWriteBatchTargets('cleanup', selectedIds).length} 个已核验位置;保留不属于插件或被共用的内容`, run: () => startExistingBatch('cleanup') },
|
|
3438
3352
|
{
|
|
3439
3353
|
label: '返回任务选择',
|
|
3440
3354
|
run: () => moveBatchStage('task'),
|
|
@@ -3449,13 +3363,13 @@ export function ConsoleAppV4(props) {
|
|
|
3449
3363
|
actions = [
|
|
3450
3364
|
...(updates.length > 0 ? [{
|
|
3451
3365
|
label: `更新所选中的 ${updateRoots} 个可更新插件…`,
|
|
3452
|
-
description: '
|
|
3366
|
+
description: '使用已验证版本和已经添加的位置',
|
|
3453
3367
|
status: 'warning',
|
|
3454
3368
|
run: () => openSelectedPluginTask('update', selectedIds),
|
|
3455
3369
|
}] : []),
|
|
3456
3370
|
...(restores.length > 0 ? [{
|
|
3457
3371
|
label: `恢复所选中的 ${restoreRoots} 个插件…`,
|
|
3458
|
-
description: '
|
|
3372
|
+
description: '按当前问题检查已经添加的位置',
|
|
3459
3373
|
status: 'warning',
|
|
3460
3374
|
run: () => openSelectedPluginTask('restore', selectedIds),
|
|
3461
3375
|
}] : []),
|
|
@@ -3490,8 +3404,10 @@ export function ConsoleAppV4(props) {
|
|
|
3490
3404
|
: `设置批量${batchDraft?.action ? batchActionLabel(batchDraft.action) : ''}位置`;
|
|
3491
3405
|
description = maintenanceMode
|
|
3492
3406
|
? '默认沿用进入此页时的现有位置。可以取消位置,也可以恢复本次集合中的位置。'
|
|
3493
|
-
: '
|
|
3407
|
+
: '分别选择使用范围和工具。操作汇总会重新读取状态;本次安装位置变化时需要重新确认。';
|
|
3494
3408
|
let installPlacementTargets = [];
|
|
3409
|
+
let installPlacementGroups = [];
|
|
3410
|
+
let installPlacementActions = [];
|
|
3495
3411
|
let maintenanceTargetCount = 0;
|
|
3496
3412
|
if (!batchDraft?.action && !batchDraft?.maintenanceGoal) {
|
|
3497
3413
|
actions = [{ label: '返回批量选择', run: back }];
|
|
@@ -3558,6 +3474,92 @@ export function ConsoleAppV4(props) {
|
|
|
3558
3474
|
const addTargets = installPlacementTargets.filter((target) => target.state === 'add');
|
|
3559
3475
|
const blockedTargets = installPlacementTargets.filter((target) => target.state === 'blocked');
|
|
3560
3476
|
const existingTargets = installPlacementTargets.filter((target) => target.state === 'existing');
|
|
3477
|
+
installPlacementGroups = [
|
|
3478
|
+
{
|
|
3479
|
+
kind: 'action',
|
|
3480
|
+
actions: [
|
|
3481
|
+
...(installPlacementTargets.length > 0 ? [{
|
|
3482
|
+
actionId: 'batch-placement-details',
|
|
3483
|
+
label: '查看全部位置和受阻原因…',
|
|
3484
|
+
description: `${addTargets.length} 个可添加 · ${existingTargets.length} 个已有 · ${blockedTargets.length} 个受阻`,
|
|
3485
|
+
run: () => {
|
|
3486
|
+
setBatchDraft((current) => current ? { ...current, showPlacementTargets: true } : current);
|
|
3487
|
+
setFocus(0);
|
|
3488
|
+
setScrollOffset(0);
|
|
3489
|
+
},
|
|
3490
|
+
}] : []),
|
|
3491
|
+
{
|
|
3492
|
+
actionId: 'batch-placement-confirm',
|
|
3493
|
+
label: batchDraft.action === 'install' && blockedTargets.length > 0
|
|
3494
|
+
? `仅添加可执行的 ${addTargets.length} 个位置`
|
|
3495
|
+
: `查看批量${batchActionLabel(batchDraft.action)}确认`,
|
|
3496
|
+
description: batchDraft.action === 'install'
|
|
3497
|
+
? `${addTargets.length} 个可添加 · ${existingTargets.length} 个已有 · ${blockedTargets.length} 个受阻`
|
|
3498
|
+
: `${batchDraft.selection === 'selected' ? `${batchDraft.selectedPluginIds.length} 个所选插件` : '当前项目全部保存目标'} · ${scopeLabel(batchDraft.scope)}`,
|
|
3499
|
+
disabled: batchDraft.selection === 'selected' && batchDraft.selectedPluginIds.length === 0
|
|
3500
|
+
? '请至少选择一个插件'
|
|
3501
|
+
: batchDraft.action === 'install' && addTargets.length === 0
|
|
3502
|
+
? '所选工具和位置没有可添加目标'
|
|
3503
|
+
: undefined,
|
|
3504
|
+
run: () => {
|
|
3505
|
+
if (invalidBatchSelection(batchDraft).length > 0) {
|
|
3506
|
+
setActionError('已选插件状态已变化。请返回选择页检查并取消失效项。');
|
|
3507
|
+
return;
|
|
3508
|
+
}
|
|
3509
|
+
const intent = {
|
|
3510
|
+
kind: 'pluginWriteBatch',
|
|
3511
|
+
action: batchDraft.action,
|
|
3512
|
+
selection: batchDraft.action === 'install'
|
|
3513
|
+
? { kind: 'targets', targets: addTargets.map(({ pluginId, platform, scope }) => ({
|
|
3514
|
+
pluginId, platform, scope,
|
|
3515
|
+
})) }
|
|
3516
|
+
: batchDraft.selection === 'selected'
|
|
3517
|
+
? {
|
|
3518
|
+
kind: 'selected',
|
|
3519
|
+
pluginIds: [...new Set(batchDraft.selectedPluginIds)]
|
|
3520
|
+
.sort((left, right) => left.localeCompare(right, 'en')),
|
|
3521
|
+
}
|
|
3522
|
+
: { kind: 'currentProjectIntentRoots' },
|
|
3523
|
+
platform: addTargets[0]?.platform ?? batchDraft.platform,
|
|
3524
|
+
scope: addTargets[0]?.scope ?? batchDraft.scope,
|
|
3525
|
+
};
|
|
3526
|
+
beginReview(intent);
|
|
3527
|
+
setDirty(false);
|
|
3528
|
+
setFocus(0);
|
|
3529
|
+
setScrollOffset(0);
|
|
3530
|
+
},
|
|
3531
|
+
},
|
|
3532
|
+
],
|
|
3533
|
+
},
|
|
3534
|
+
{
|
|
3535
|
+
title: '在哪里使用',
|
|
3536
|
+
kind: 'choice',
|
|
3537
|
+
actions: [
|
|
3538
|
+
{
|
|
3539
|
+
actionId: 'batch-placement-scope-project',
|
|
3540
|
+
label: '当前项目', selected: batchDraft.scope === 'project',
|
|
3541
|
+
run: () => setBatchDraft((current) => current ? { ...current, scope: 'project' } : current),
|
|
3542
|
+
},
|
|
3543
|
+
{
|
|
3544
|
+
actionId: 'batch-placement-scope-user',
|
|
3545
|
+
label: '所有项目', selected: batchDraft.scope === 'user',
|
|
3546
|
+
disabled: projectIntent ? '项目全部同步固定使用当前项目' : undefined,
|
|
3547
|
+
run: () => setBatchDraft((current) => current ? { ...current, scope: 'user' } : current),
|
|
3548
|
+
},
|
|
3549
|
+
],
|
|
3550
|
+
},
|
|
3551
|
+
{
|
|
3552
|
+
title: '用于哪个工具',
|
|
3553
|
+
kind: 'choice',
|
|
3554
|
+
actions: ['codex', 'claude', 'both'].map((platform) => ({
|
|
3555
|
+
actionId: `batch-placement-platform-${platform}`,
|
|
3556
|
+
label: platform === 'both' ? 'Codex 和 Claude Code' : platformLabel(platform),
|
|
3557
|
+
selected: batchDraft.platform === platform,
|
|
3558
|
+
run: () => setBatchDraft((current) => current ? { ...current, platform } : current),
|
|
3559
|
+
})),
|
|
3560
|
+
},
|
|
3561
|
+
];
|
|
3562
|
+
installPlacementActions = installPlacementGroups.flatMap((group) => group.actions);
|
|
3561
3563
|
if (batchDraft.showPlacementTargets) {
|
|
3562
3564
|
actions = [
|
|
3563
3565
|
...installPlacementTargets.map((target) => ({
|
|
@@ -3571,78 +3573,13 @@ export function ConsoleAppV4(props) {
|
|
|
3571
3573
|
label: '返回位置选择',
|
|
3572
3574
|
run: () => {
|
|
3573
3575
|
setBatchDraft((current) => current ? { ...current, showPlacementTargets: false } : current);
|
|
3574
|
-
|
|
3575
|
-
setScrollOffset(0);
|
|
3576
|
+
restoreActionFocus('batch-placement-details');
|
|
3576
3577
|
},
|
|
3577
3578
|
},
|
|
3578
3579
|
];
|
|
3579
3580
|
}
|
|
3580
3581
|
else
|
|
3581
|
-
actions =
|
|
3582
|
-
{
|
|
3583
|
-
label: '当前项目', selected: batchDraft.scope === 'project',
|
|
3584
|
-
run: () => setBatchDraft((current) => current ? { ...current, scope: 'project' } : current),
|
|
3585
|
-
},
|
|
3586
|
-
{
|
|
3587
|
-
label: '所有项目', selected: batchDraft.scope === 'user',
|
|
3588
|
-
disabled: projectIntent ? '项目全部同步固定使用当前项目' : undefined,
|
|
3589
|
-
run: () => setBatchDraft((current) => current ? { ...current, scope: 'user' } : current),
|
|
3590
|
-
},
|
|
3591
|
-
...['codex', 'claude', 'both'].map((platform) => ({
|
|
3592
|
-
label: platform === 'both' ? 'Codex 和 Claude Code' : platformLabel(platform),
|
|
3593
|
-
selected: batchDraft.platform === platform,
|
|
3594
|
-
run: () => setBatchDraft((current) => current ? { ...current, platform } : current),
|
|
3595
|
-
})),
|
|
3596
|
-
...(installPlacementTargets.length > 0 ? [{
|
|
3597
|
-
label: '查看全部位置和受阻原因…',
|
|
3598
|
-
description: `${addTargets.length} 个可添加 · ${existingTargets.length} 个已有 · ${blockedTargets.length} 个受阻`,
|
|
3599
|
-
run: () => {
|
|
3600
|
-
setBatchDraft((current) => current ? { ...current, showPlacementTargets: true } : current);
|
|
3601
|
-
setFocus(0);
|
|
3602
|
-
setScrollOffset(0);
|
|
3603
|
-
},
|
|
3604
|
-
}] : []),
|
|
3605
|
-
{
|
|
3606
|
-
label: batchDraft.action === 'install' && blockedTargets.length > 0
|
|
3607
|
-
? `仅添加可执行的 ${addTargets.length} 个位置`
|
|
3608
|
-
: `查看批量${batchActionLabel(batchDraft.action)}确认`,
|
|
3609
|
-
description: batchDraft.action === 'install'
|
|
3610
|
-
? `${addTargets.length} 个可添加 · ${existingTargets.length} 个已有 · ${blockedTargets.length} 个受阻`
|
|
3611
|
-
: `${batchDraft.selection === 'selected' ? `${batchDraft.selectedPluginIds.length} 个所选插件` : '当前项目全部保存目标'} · ${scopeLabel(batchDraft.scope)}`,
|
|
3612
|
-
disabled: batchDraft.selection === 'selected' && batchDraft.selectedPluginIds.length === 0
|
|
3613
|
-
? '请至少选择一个插件'
|
|
3614
|
-
: batchDraft.action === 'install' && addTargets.length === 0
|
|
3615
|
-
? '所选工具和位置没有可添加目标'
|
|
3616
|
-
: undefined,
|
|
3617
|
-
run: () => {
|
|
3618
|
-
if (invalidBatchSelection(batchDraft).length > 0) {
|
|
3619
|
-
setActionError('已选插件状态已变化。请返回选择页检查并取消失效项。');
|
|
3620
|
-
return;
|
|
3621
|
-
}
|
|
3622
|
-
const intent = {
|
|
3623
|
-
kind: 'pluginWriteBatch',
|
|
3624
|
-
action: batchDraft.action,
|
|
3625
|
-
selection: batchDraft.action === 'install'
|
|
3626
|
-
? { kind: 'targets', targets: addTargets.map(({ pluginId, platform, scope }) => ({
|
|
3627
|
-
pluginId, platform, scope,
|
|
3628
|
-
})) }
|
|
3629
|
-
: batchDraft.selection === 'selected'
|
|
3630
|
-
? {
|
|
3631
|
-
kind: 'selected',
|
|
3632
|
-
pluginIds: [...new Set(batchDraft.selectedPluginIds)]
|
|
3633
|
-
.sort((left, right) => left.localeCompare(right, 'en')),
|
|
3634
|
-
}
|
|
3635
|
-
: { kind: 'currentProjectIntentRoots' },
|
|
3636
|
-
platform: addTargets[0]?.platform ?? batchDraft.platform,
|
|
3637
|
-
scope: addTargets[0]?.scope ?? batchDraft.scope,
|
|
3638
|
-
};
|
|
3639
|
-
beginReview(intent);
|
|
3640
|
-
setDirty(false);
|
|
3641
|
-
setFocus(0);
|
|
3642
|
-
setScrollOffset(0);
|
|
3643
|
-
},
|
|
3644
|
-
},
|
|
3645
|
-
];
|
|
3582
|
+
actions = installPlacementActions;
|
|
3646
3583
|
}
|
|
3647
3584
|
context = batchDraft?.selection === 'selected'
|
|
3648
3585
|
? maintenanceMode
|
|
@@ -3662,7 +3599,14 @@ export function ConsoleAppV4(props) {
|
|
|
3662
3599
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SectionCard, { title: "\u5904\u7406\u8303\u56F4", meta: `${maintenanceSelection.size} 个位置`, compact: true, children: targetLimit > 0 ? _jsx(SemanticRows, { actions: actions.slice(0, maintenanceTargetCount), focus: focus, kind: "toggle", compact: true, offset: targetOffset, limit: targetLimit }) : null }), actionLimit > 0 ? _jsx(SemanticRows, { actions: actions.slice(maintenanceTargetCount), focus: focus - maintenanceTargetCount, kind: "action", compact: policy.mode === 'compact', offset: actionOffset, limit: actionLimit }) : null] });
|
|
3663
3600
|
}
|
|
3664
3601
|
else if (!placementDetail && batchDraft?.action === 'install') {
|
|
3665
|
-
content =
|
|
3602
|
+
content = _jsx(Box, { flexDirection: "column", children: installPlacementGroups.map((group) => {
|
|
3603
|
+
const groupOffset = installPlacementActions.findIndex((action) => action.actionId === group.actions[0]?.actionId);
|
|
3604
|
+
const localOffset = Math.max(0, viewport.offset - groupOffset);
|
|
3605
|
+
const localLimit = Math.max(0, Math.min(group.actions.length - localOffset, viewport.offset + viewport.limit - groupOffset - localOffset));
|
|
3606
|
+
if (localLimit === 0)
|
|
3607
|
+
return null;
|
|
3608
|
+
return _jsxs(Box, { flexDirection: "column", children: [group.title ? _jsx(Text, { color: tuiTheme.colors.muted, children: group.title }) : null, _jsx(SemanticRows, { actions: group.actions, focus: focus - groupOffset, kind: group.kind, compact: group.kind === 'choice' || policy.mode === 'compact', offset: localOffset, limit: localLimit })] }, group.title ?? 'actions');
|
|
3609
|
+
}) });
|
|
3666
3610
|
}
|
|
3667
3611
|
else
|
|
3668
3612
|
content = _jsx(SemanticRows, { actions: actions, focus: focus, kind: placementDetail ? 'action' : 'choice', compact: placementDetail ? false : policy.mode === 'compact', offset: viewport.offset, limit: viewport.limit });
|
|
@@ -3935,11 +3879,11 @@ export function ConsoleAppV4(props) {
|
|
|
3935
3879
|
...(expandedDependencyPluginIds ? { expandedPluginIds: expandedDependencyPluginIds } : {}),
|
|
3936
3880
|
});
|
|
3937
3881
|
const visibleRows = projection.rows;
|
|
3938
|
-
context = direction === 'dependencies' ? '它需要的' : '
|
|
3939
|
-
title = hasInstalledPlacement(plugin) ? '
|
|
3882
|
+
context = direction === 'dependencies' ? '它需要的' : '哪些插件依赖它';
|
|
3883
|
+
title = hasInstalledPlacement(plugin) ? '依赖与当前可用关系' : '安装所需插件';
|
|
3940
3884
|
description = direction === 'dependencies'
|
|
3941
3885
|
? '每一层表示上面的插件需要下面的插件。'
|
|
3942
|
-
: '
|
|
3886
|
+
: '每一层表示下面的插件在本次检查中需要上面的插件。';
|
|
3943
3887
|
const rowActions = visibleRows.map((row) => {
|
|
3944
3888
|
const state = row.depth === 0
|
|
3945
3889
|
? { value: statusText(plugin), status: plugin.aggregateStatus === 'needsAttention'
|
|
@@ -3953,7 +3897,7 @@ export function ConsoleAppV4(props) {
|
|
|
3953
3897
|
? `${row.label}(当前插件)`
|
|
3954
3898
|
: `${compactBranch}${row.label}${row.sharedWithRowId ? '(共用,见上方)' : ''}`,
|
|
3955
3899
|
description: row.hiddenDescendantCount > 0
|
|
3956
|
-
? `另有 ${row.hiddenDescendantCount} 个${direction === 'dependencies' ? '所需插件' : '
|
|
3900
|
+
? `另有 ${row.hiddenDescendantCount} 个${direction === 'dependencies' ? '所需插件' : '当前可用依赖者'}`
|
|
3957
3901
|
: row.depth === 0 ? '当前插件' : undefined,
|
|
3958
3902
|
meta: state.value,
|
|
3959
3903
|
status: state.status,
|
|
@@ -3974,7 +3918,7 @@ export function ConsoleAppV4(props) {
|
|
|
3974
3918
|
const declared = overview?.dependents.find((entry) => entry.pluginId === pluginId);
|
|
3975
3919
|
return {
|
|
3976
3920
|
label: declared?.displayName ?? pluginId,
|
|
3977
|
-
description: '
|
|
3921
|
+
description: '有依赖声明,但本次尚未确认依赖可用',
|
|
3978
3922
|
meta: declared?.aggregateStatus === 'notInstalled' ? '仅声明 · 未安装' : '仅声明 · 未验证',
|
|
3979
3923
|
status: 'muted',
|
|
3980
3924
|
run: () => {
|
|
@@ -3993,7 +3937,7 @@ export function ConsoleAppV4(props) {
|
|
|
3993
3937
|
...rowActions,
|
|
3994
3938
|
...unverifiedConsumerActions,
|
|
3995
3939
|
{
|
|
3996
|
-
label: direction === 'dependencies' ? '
|
|
3940
|
+
label: direction === 'dependencies' ? '切换到“哪些插件依赖它”' : '切换到“它需要的”',
|
|
3997
3941
|
description: '切换关系方向',
|
|
3998
3942
|
run: () => {
|
|
3999
3943
|
persistDependencyGraphContext(route, projection, expandedDependencyPluginIds ?? new Set(projection.defaultExpandedPluginIds), focus, scrollOffset);
|
|
@@ -4006,17 +3950,14 @@ export function ConsoleAppV4(props) {
|
|
|
4006
3950
|
},
|
|
4007
3951
|
{ label: showTechnical ? '隐藏检查详情' : '查看检查详情', run: () => toggleTechnical() },
|
|
4008
3952
|
];
|
|
4009
|
-
const
|
|
4010
|
-
? projection.scopeSummary.references.map((entry) => `${platformLabel(entry.platform)} · ${scopeLabel(entry.scope)}`).join(';')
|
|
4011
|
-
: '当前加载范围;其他项目引用未检查';
|
|
4012
|
-
const relationViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, showTechnical ? responsiveBudget(3, 6) : responsiveBudget(6, 10));
|
|
3953
|
+
const relationViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, showTechnical ? responsiveBudget(2, 5) : responsiveBudget(5, 9));
|
|
4013
3954
|
const focusedGraphRow = focus < rowActions.length ? visibleRows[focus] : undefined;
|
|
4014
3955
|
help = '↑↓ 选择 · → 展开 · ← 收起 · Enter 节点详情 · Esc 返回';
|
|
4015
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StaticRow, { title:
|
|
3956
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StaticRow, { title: "\u68C0\u67E5\u8303\u56F4", 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 }), projection.status.state === 'invalid'
|
|
4016
3957
|
? _jsx(Callout, { status: "error", title: "\u4F9D\u8D56\u5173\u7CFB\u65E0\u6548", description: projection.status.message }) : null, unverifiedConsumerActions.length > 0
|
|
4017
|
-
? _jsx(StaticRow, { title: `未验证声明者 · ${unverifiedConsumerActions.length} 个`, description: "\u4EE5\u4E0B\u58F0\u660E\u8005\u4E0D\u8BA1\u5165\
|
|
4018
|
-
: null, focusedGraphRow ? _jsx(StaticRow, { title: "\u7528\u9014",
|
|
4019
|
-
.getPluginOverview(focusedGraphRow.pluginId)?.description ?? '当前目录没有用途说明', compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: relationViewport.offset, limit: relationViewport.limit }), showTechnical ? _jsxs(TechnicalDetails, { children: [_jsx(StaticRow, { title: `${dependencyCount} 个依赖 · ${projection.scopeSummary.
|
|
3958
|
+
? _jsx(StaticRow, { title: `未验证声明者 · ${unverifiedConsumerActions.length} 个`, description: "\u4EE5\u4E0B\u58F0\u660E\u8005\u4E0D\u8BA1\u5165\u5F53\u524D\u53EF\u7528\u5173\u7CFB", status: "muted", compact: true })
|
|
3959
|
+
: null, focusedGraphRow ? _jsx(StaticRow, { title: "\u7528\u9014", value: props.controller
|
|
3960
|
+
.getPluginOverview(focusedGraphRow.pluginId)?.description ?? '当前目录没有用途说明', compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: relationViewport.offset, limit: relationViewport.limit }), showTechnical ? _jsxs(TechnicalDetails, { children: [_jsx(StaticRow, { title: `${dependencyCount} 个依赖 · ${projection.scopeSummary.availableConsumerPluginIds.length} 个当前可用依赖者`, meta: plugin.pluginId, compact: true }), _jsx(StaticRow, { title: `未验证声明者 · ${projection.scopeSummary.unknownConsumerPluginIds.length} 个`, compact: true })] }) : null] });
|
|
4020
3961
|
}
|
|
4021
3962
|
}
|
|
4022
3963
|
else if (route.name === 'pluginDependencyNode' && plugin) {
|
|
@@ -4038,10 +3979,10 @@ export function ConsoleAppV4(props) {
|
|
|
4038
3979
|
?.find((entry) => entry.pluginId === route.nodePluginId);
|
|
4039
3980
|
const state = item ? dependencyStatus(item) : undefined;
|
|
4040
3981
|
const relationship = selectedRow?.relationship
|
|
4041
|
-
?? ((item?.
|
|
3982
|
+
?? ((item?.availablePlacementReferences?.length ?? 0) > 0 ? 'unknown'
|
|
4042
3983
|
: item ? 'declared' : undefined);
|
|
4043
3984
|
breadcrumb = `${plugin.displayName} / 依赖关系 / ${node?.displayName ?? route.nodePluginId}`;
|
|
4044
|
-
context = route.direction === 'dependencies' ? '它需要的' : '
|
|
3985
|
+
context = route.direction === 'dependencies' ? '它需要的' : '哪些插件依赖它';
|
|
4045
3986
|
title = node?.displayName ?? route.nodePluginId;
|
|
4046
3987
|
const pathPluginIds = selectedRow?.pathPluginIds ?? nodePathPluginIds;
|
|
4047
3988
|
const intermediateNames = pathPluginIds.slice(1, -1).reverse().map((pluginId) => props.controller.getPluginOverview(pluginId)?.displayName ?? pluginId);
|
|
@@ -4050,37 +3991,61 @@ export function ConsoleAppV4(props) {
|
|
|
4050
3991
|
?? declaringPluginId;
|
|
4051
3992
|
description = relationship === 'root'
|
|
4052
3993
|
? '这是当前关系图的根插件。'
|
|
4053
|
-
: relationship === '
|
|
3994
|
+
: relationship === 'directAvailable'
|
|
4054
3995
|
? route.direction === 'dependencies'
|
|
4055
|
-
? `${plugin.displayName}
|
|
4056
|
-
: `${node?.displayName ?? route.nodePluginId}
|
|
4057
|
-
: relationship === '
|
|
3996
|
+
? `${plugin.displayName} 在本次检查的位置需要此插件,所需依赖当前可用。`
|
|
3997
|
+
: `${node?.displayName ?? route.nodePluginId} 在本次检查的位置需要当前插件,所需依赖当前可用。`
|
|
3998
|
+
: relationship === 'indirectAvailable'
|
|
4058
3999
|
? route.direction === 'dependencies'
|
|
4059
|
-
? `${plugin.displayName} 通过 ${intermediateNames.join('、')}
|
|
4060
|
-
: `${node?.displayName ?? route.nodePluginId} 通过 ${intermediateNames.join('、')}
|
|
4000
|
+
? `${plugin.displayName} 通过 ${intermediateNames.join('、')} 需要 ${node?.displayName ?? route.nodePluginId},且各段依赖当前可用。`
|
|
4001
|
+
: `${node?.displayName ?? route.nodePluginId} 通过 ${intermediateNames.join('、')} 需要 ${plugin.displayName},且各段依赖当前可用。`
|
|
4061
4002
|
: relationship === 'unknown'
|
|
4062
|
-
? '
|
|
4003
|
+
? '本次检查的位置不能组成连续路径,不能显示这项间接关系。'
|
|
4063
4004
|
: relationship === 'declared'
|
|
4064
4005
|
? route.direction === 'dependencies'
|
|
4065
|
-
? `${declaringPluginName} 声明需要 ${node?.displayName ?? route.nodePluginId}
|
|
4066
|
-
: `${node?.displayName ?? route.nodePluginId}
|
|
4006
|
+
? `${declaringPluginName} 声明需要 ${node?.displayName ?? route.nodePluginId},但本次尚未确认依赖可用。`
|
|
4007
|
+
: `${node?.displayName ?? route.nodePluginId} 声明需要当前插件,但本次尚未确认依赖可用。`
|
|
4067
4008
|
: '当前数据不足,不能判断这项依赖关系。';
|
|
4068
|
-
const references = selectedRow?.edge?.
|
|
4009
|
+
const references = selectedRow?.edge?.availablePlacementReferences
|
|
4010
|
+
?? item?.availablePlacementReferences ?? [];
|
|
4069
4011
|
const referenceActions = references.map((reference) => {
|
|
4070
4012
|
const consumerName = props.controller.getPluginOverview(reference.consumer.pluginId)?.displayName
|
|
4071
4013
|
?? reference.consumer.pluginId.split('/').at(-1);
|
|
4072
4014
|
return {
|
|
4073
4015
|
label: dependencyReferenceUsageLabel(reference, consumerName),
|
|
4074
|
-
meta: '
|
|
4016
|
+
meta: '依赖当前可用',
|
|
4075
4017
|
};
|
|
4076
4018
|
});
|
|
4077
|
-
if (route.view === '
|
|
4019
|
+
if (route.view === 'details') {
|
|
4020
|
+
const detailSections = [
|
|
4021
|
+
['用途', node?.description ?? '当前目录没有用途说明'],
|
|
4022
|
+
['为何需要', description],
|
|
4023
|
+
['影响', state?.value ?? (node ? statusText(node) : '尚未检查当前状态')],
|
|
4024
|
+
];
|
|
4025
|
+
const detailLines = detailSections.flatMap(([label, value]) => [
|
|
4026
|
+
label,
|
|
4027
|
+
...wrapConsoleText(value, Math.max(1, size.columns - 6)).map((line) => ` ${line}`),
|
|
4028
|
+
]);
|
|
4029
|
+
const pageRows = responsiveBudget(5, 10);
|
|
4030
|
+
const detailOffset = Math.min(batchTargetOffset, Math.max(0, detailLines.length - 1));
|
|
4031
|
+
const visibleDetailLines = detailLines.slice(detailOffset, detailOffset + pageRows);
|
|
4032
|
+
referenceDetailPagination = { total: detailLines.length, pageRows };
|
|
4033
|
+
breadcrumb = `${plugin.displayName} / 依赖关系 / ${node?.displayName ?? route.nodePluginId} / 完整说明`;
|
|
4034
|
+
context = `${Math.min(detailOffset + 1, detailLines.length)}–${Math.min(detailOffset + visibleDetailLines.length, detailLines.length)} / ${detailLines.length}`;
|
|
4035
|
+
title = `${node?.displayName ?? route.nodePluginId} 的完整说明`;
|
|
4036
|
+
description = '用途、关系原因和当前影响。';
|
|
4037
|
+
help = 'PgUp/PgDn 阅读 · Enter 返回节点详情 · Esc 返回节点详情';
|
|
4038
|
+
actions = [{ label: '返回节点详情', run: back }];
|
|
4039
|
+
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
|
|
4040
|
+
? _jsx(StaticRow, { title: `↓ 后面还有 ${detailLines.length - detailOffset - visibleDetailLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
4041
|
+
}
|
|
4042
|
+
else if (route.view === 'references') {
|
|
4078
4043
|
breadcrumb = `${plugin.displayName} / 依赖关系 / ${node?.displayName ?? route.nodePluginId} / 使用位置`;
|
|
4079
4044
|
context = showTechnical ? '技术详情' : '使用位置';
|
|
4080
|
-
title =
|
|
4045
|
+
title = `当前可用依赖位置 ${references.length} 个`;
|
|
4081
4046
|
description = showTechnical
|
|
4082
4047
|
? '显示当前选择的完整引用字段。'
|
|
4083
|
-
: '
|
|
4048
|
+
: '这些位置的所需依赖当前可用,且本次检查发现它们同时满足依赖声明和安装位置。';
|
|
4084
4049
|
actions = [...referenceActions, { label: '返回节点详情', run: back }];
|
|
4085
4050
|
const referenceViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(3, 6));
|
|
4086
4051
|
const selectedReference = references[Math.min(focus, references.length - 1)];
|
|
@@ -4110,7 +4075,7 @@ export function ConsoleAppV4(props) {
|
|
|
4110
4075
|
? 'PgUp/PgDn 查看当前位置详情 · ↑↓ 查看全部位置 · d 隐藏技术详情 · Esc 返回节点详情'
|
|
4111
4076
|
: '↑↓ 查看全部位置 · d 技术详情 · Enter 返回节点详情 · Esc 返回节点详情';
|
|
4112
4077
|
content = _jsxs(Box, { flexDirection: "column", children: [showTechnical ? null
|
|
4113
|
-
: _jsx(StaticRow, { title: "\
|
|
4078
|
+
: _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
|
|
4114
4079
|
? _jsx(StaticRow, { title: `↑ 前面还有 ${referenceDetailOffset} 行`, status: "muted", compact: true }) : null, showTechnical ? visibleReferenceDetailLines.map((line, index) => _jsx(StaticRow, { title: line, compact: true }, `${referenceDetailOffset + index}:${line}`)) : null, showTechnical && referenceDetailOffset + visibleReferenceDetailLines.length < referenceDetailLines.length
|
|
4115
4080
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${referenceDetailLines.length - referenceDetailOffset - visibleReferenceDetailLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: referenceViewport.offset, limit: referenceViewport.limit })] });
|
|
4116
4081
|
}
|
|
@@ -4118,7 +4083,7 @@ export function ConsoleAppV4(props) {
|
|
|
4118
4083
|
actions = [
|
|
4119
4084
|
...(references.length > 0 ? [{
|
|
4120
4085
|
label: `查看全部位置(${references.length})`,
|
|
4121
|
-
description: '
|
|
4086
|
+
description: '查看每个位置的当前可用依赖',
|
|
4122
4087
|
run: () => go({ ...route, view: 'references' }),
|
|
4123
4088
|
}] : []),
|
|
4124
4089
|
...(route.nodePluginId !== plugin.pluginId ? [{
|
|
@@ -4130,11 +4095,20 @@ export function ConsoleAppV4(props) {
|
|
|
4130
4095
|
direction: route.direction,
|
|
4131
4096
|
}),
|
|
4132
4097
|
}] : []),
|
|
4098
|
+
{
|
|
4099
|
+
label: '阅读完整说明',
|
|
4100
|
+
description: '分页查看用途、为何需要和影响',
|
|
4101
|
+
run: () => {
|
|
4102
|
+
setBatchTargetOffset(0);
|
|
4103
|
+
go({ ...route, view: 'details' });
|
|
4104
|
+
},
|
|
4105
|
+
},
|
|
4133
4106
|
{ label: '返回关系图', run: back },
|
|
4134
4107
|
];
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4108
|
+
const nodeActionViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(2, 4));
|
|
4109
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsxs(SectionCard, { title: "\u8282\u70B9\u72B6\u6001", children: [_jsx(StaticRow, { title: "\u7528\u9014", value: node?.description ?? '当前目录没有用途说明', compact: true }), _jsx(StaticRow, { title: "\u4E3A\u4F55\u9700\u8981", value: description, compact: true }), _jsx(StaticRow, { title: "\u5F71\u54CD", value: state?.value ?? (node ? statusText(node) : '尚未检查当前状态'), status: state?.status ?? 'muted', compact: true }), references.length > 0
|
|
4110
|
+
? _jsx(StaticRow, { title: `当前可用依赖位置 ${references.length} 个`, description: "\u9009\u62E9\u201C\u67E5\u770B\u5168\u90E8\u4F4D\u7F6E\u201D\u53EF\u9010\u9879\u67E5\u770B", compact: true })
|
|
4111
|
+
: null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: nodeActionViewport.offset, limit: nodeActionViewport.limit }), showTechnical ? _jsxs(TechnicalDetails, { children: [_jsx(StaticRow, { title: "pluginId", meta: route.nodePluginId, compact: true }), _jsx(StaticRow, { title: "relationship", meta: relationship ?? 'unknown', compact: true })] }) : null] });
|
|
4138
4112
|
}
|
|
4139
4113
|
}
|
|
4140
4114
|
else if (route.name === 'installPlacement' && plugin) {
|
|
@@ -4143,7 +4117,7 @@ export function ConsoleAppV4(props) {
|
|
|
4143
4117
|
title = `你希望在哪里使用 ${plugin.displayName}?`;
|
|
4144
4118
|
const hasDependencies = (plugin.dependencySummary?.totalCount ?? 0) > 0;
|
|
4145
4119
|
description = hasDependencies
|
|
4146
|
-
? '
|
|
4120
|
+
? '这里只选择根插件的安装位置。依赖会自动安排合适位置,并在操作汇总中显示。'
|
|
4147
4121
|
: '选择位置后,再选择一个或多个目标平台。';
|
|
4148
4122
|
const availableScopes = ['user', 'project'].filter((candidateScope) => props.controller.listInstallTargets(plugin.pluginId, candidateScope)
|
|
4149
4123
|
.some((entry) => entry.compatible));
|
|
@@ -4153,7 +4127,7 @@ export function ConsoleAppV4(props) {
|
|
|
4153
4127
|
selected: candidateScope === scope,
|
|
4154
4128
|
description: candidateScope === 'user'
|
|
4155
4129
|
? hasDependencies ? '根插件在任意项目中可用;依赖位置自动计算' : '在任意项目中可使用,适合个人常用能力'
|
|
4156
|
-
: hasDependencies ? '
|
|
4130
|
+
: hasDependencies ? '根插件只在当前项目使用;操作汇总会说明依赖是否需要用于更多项目' : '仅在当前项目中使用,适合团队共享',
|
|
4157
4131
|
meta: candidateScope === 'user' ? '推荐' : undefined,
|
|
4158
4132
|
run: () => {
|
|
4159
4133
|
const choices = props.controller.listInstallTargets(plugin.pluginId, candidateScope);
|
|
@@ -4176,7 +4150,7 @@ export function ConsoleAppV4(props) {
|
|
|
4176
4150
|
},
|
|
4177
4151
|
})),
|
|
4178
4152
|
];
|
|
4179
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SemanticRows, { actions: actions, focus: focus, kind: "choice", compact: policy.mode === 'compact' }), hasDependencies ? _jsx(SectionCard, { title: "\u4F9D\u8D56\u4F4D\u7F6E", children: _jsx(StaticRow, { title: `${plugin.dependencySummary?.totalCount ?? 0}
|
|
4153
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SemanticRows, { actions: actions, focus: focus, kind: "choice", compact: policy.mode === 'compact' }), hasDependencies ? _jsx(SectionCard, { title: "\u4F9D\u8D56\u4F4D\u7F6E", children: _jsx(StaticRow, { title: `${plugin.dependencySummary?.totalCount ?? 0} 个依赖将自动安排合适位置`, description: "\u53EF\u5728\u64CD\u4F5C\u6C47\u603B\u4E2D\u67E5\u770B\u6216\u8C03\u6574", status: "info" }) }) : null] });
|
|
4180
4154
|
}
|
|
4181
4155
|
else if (route.name === 'installTargets' && plugin) {
|
|
4182
4156
|
breadcrumb = `${plugin.displayName} / 添加 / 目标平台`;
|
|
@@ -4184,8 +4158,8 @@ export function ConsoleAppV4(props) {
|
|
|
4184
4158
|
title = '选择目标平台';
|
|
4185
4159
|
const hasDependencies = (plugin.dependencySummary?.totalCount ?? 0) > 0;
|
|
4186
4160
|
description = hasDependencies
|
|
4187
|
-
? '
|
|
4188
|
-
: '
|
|
4161
|
+
? '根插件必须支持所选位置;确认后会自动安排依赖并显示操作汇总。'
|
|
4162
|
+
: '目标平台按所选位置验证;只含由平台共用内容的插件可同时启用两个位置。';
|
|
4189
4163
|
const choices = props.controller.listInstallTargets(plugin.pluginId, scope);
|
|
4190
4164
|
const validSelectedTargets = selectedTargets.filter((platform) => choices.some((choice) => choice.platform === platform && choice.compatible));
|
|
4191
4165
|
const allUnavailable = choices.length > 0 && choices.every((choice) => !choice.compatible);
|
|
@@ -4268,7 +4242,7 @@ export function ConsoleAppV4(props) {
|
|
|
4268
4242
|
...dependencyActions,
|
|
4269
4243
|
{
|
|
4270
4244
|
label: '继续到确认',
|
|
4271
|
-
description: draft?.canContinue ? '
|
|
4245
|
+
description: draft?.canContinue ? '使用这些最终位置显示操作汇总' : undefined,
|
|
4272
4246
|
disabled: !draft?.canContinue ? draft?.error?.message ?? '依赖位置尚未就绪' : undefined,
|
|
4273
4247
|
run: () => beginReview(props.controller.installPlacementIntent()),
|
|
4274
4248
|
},
|
|
@@ -4285,7 +4259,7 @@ export function ConsoleAppV4(props) {
|
|
|
4285
4259
|
const reusedCount = draft?.targets.filter((target) => target.assignmentSource === 'existingWiderTarget').length ?? 0;
|
|
4286
4260
|
const promotedCount = draft?.targets.filter((target) => target.assignmentSource === 'consumerPromotion').length ?? 0;
|
|
4287
4261
|
const reasonSummary = [
|
|
4288
|
-
...(defaultCount > 0 ? [
|
|
4262
|
+
...(defaultCount > 0 ? [`默认当前项目 ${defaultCount} 项`] : []),
|
|
4289
4263
|
...(reusedCount > 0 ? [`复用健康的所有项目安装 ${reusedCount} 项`] : []),
|
|
4290
4264
|
...(promotedCount > 0 ? [`因依赖自动调整 ${promotedCount} 项`] : []),
|
|
4291
4265
|
].join(';');
|
|
@@ -4389,7 +4363,7 @@ export function ConsoleAppV4(props) {
|
|
|
4389
4363
|
if (updateCandidates.length > 0 && updatePlugin) {
|
|
4390
4364
|
return [[`update:${pluginWriteTaskTargetKey(candidate)}`, {
|
|
4391
4365
|
label: `更新并恢复 ${targetLabel}…`,
|
|
4392
|
-
description: '
|
|
4366
|
+
description: '改用当前候选版本建立新任务;显示操作汇总前仍会重新检查状态',
|
|
4393
4367
|
status: 'warning',
|
|
4394
4368
|
run: () => props.controller.beginNestedPluginWriteTask({
|
|
4395
4369
|
name: 'pluginWriteTask',
|
|
@@ -4469,7 +4443,7 @@ export function ConsoleAppV4(props) {
|
|
|
4469
4443
|
const taskLabel = pluginWriteTaskLabel(route.goal);
|
|
4470
4444
|
const startTaskReview = (executionPolicy) => {
|
|
4471
4445
|
if (targetSetChanged) {
|
|
4472
|
-
setActionError('
|
|
4446
|
+
setActionError('本次安装位置已变化。请返回调整后重新开始。');
|
|
4473
4447
|
return;
|
|
4474
4448
|
}
|
|
4475
4449
|
props.controller.startPluginWriteTaskReview({
|
|
@@ -4546,7 +4520,7 @@ export function ConsoleAppV4(props) {
|
|
|
4546
4520
|
: _jsx(StaticRow, { title: "\u5F53\u524D\u6CA1\u6709\u53EF\u6267\u884C\u76EE\u6807", status: "muted", compact: true }), candidates.length > taskTargetOffset + targetRows.length
|
|
4547
4521
|
? _jsx(StaticRow, { title: `↓ 后面还有 ${candidates.length - taskTargetOffset - targetRows.length} 个位置`, status: "muted", compact: true }) : null] }), blockedCandidates.length > 0 ? _jsx(Callout, { status: "warning", title: `${blockedCandidates.length} 个位置需要先处理或决定`, description: executable.length > 0
|
|
4548
4522
|
? '可以先处理可执行项,或进入下方对应入口处理受阻位置。'
|
|
4549
|
-
: '请进入下方对应入口处理;返回后会重新读取当前证据。', compact: policy.mode === 'compact' }) : null, missingTargetKeys.length > 0 ? _jsx(Callout, { status: "warning", title: `${missingTargetKeys.length}
|
|
4523
|
+
: '请进入下方对应入口处理;返回后会重新读取当前证据。', compact: policy.mode === 'compact' }) : null, missingTargetKeys.length > 0 ? _jsx(Callout, { status: "warning", title: `${missingTargetKeys.length} 个本次安装位置已失效或无需处理`, description: "\u4E0D\u4F1A\u628A\u8FD9\u4E9B\u4F4D\u7F6E\u5F53\u4F5C\u5DF2\u5B8C\u6210\uFF0C\u4E5F\u4E0D\u4F1A\u81EA\u52A8\u7F29\u5C0F\u672C\u6B21\u8303\u56F4\u3002\u8BF7\u8FD4\u56DE\u8C03\u6574\u9009\u62E9\u540E\u91CD\u65B0\u5F00\u59CB\u3002", compact: policy.mode === 'compact' }) : null, addedTargetKeys.length > 0 ? _jsx(Callout, { status: "warning", title: `${addedTargetKeys.length} 个新位置需要重新确认`, description: "\u4E0D\u4F1A\u628A\u5237\u65B0\u540E\u65B0\u589E\u7684\u4F4D\u7F6E\u81EA\u52A8\u52A0\u5165\u672C\u6B21\u64CD\u4F5C\u3002\u8BF7\u8FD4\u56DE\u8C03\u6574\u9009\u62E9\u540E\u91CD\u65B0\u5F00\u59CB\u3002", compact: policy.mode === 'compact' }) : null, versionEvidenceChanged ? _jsx(Callout, { status: "warning", title: "\u63D2\u4EF6\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u5316", description: "\u4E0D\u4F1A\u6CBF\u7528\u6765\u6E90\u542F\u7528\u524D\u7684\u7248\u672C\u8BC1\u636E\uFF0C\u4E5F\u4E0D\u4F1A\u81EA\u52A8\u6267\u884C\u65B0\u7248\u672C\u3002", compact: policy.mode === 'compact' }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true, offset: taskViewport.offset, limit: taskViewport.limit })] });
|
|
4550
4524
|
}
|
|
4551
4525
|
else if (route.name === 'pluginDetail' && plugin) {
|
|
4552
4526
|
breadcrumb = `我的插件 / ${plugin.displayName}`;
|
|
@@ -4656,21 +4630,40 @@ export function ConsoleAppV4(props) {
|
|
|
4656
4630
|
const dependencyOverviewForDetail = dependencyOverview(plugin);
|
|
4657
4631
|
const dependencyDetailText = dependencyOverviewForDetail
|
|
4658
4632
|
&& dependencyOverviewForDetail.summary.totalCount > 0
|
|
4659
|
-
?
|
|
4633
|
+
? `需要 ${dependencyOverviewForDetail.summary.totalCount} 个插件;当前可用关系按当前范围检查,未显示的关系尚未检查通过。`
|
|
4660
4634
|
: undefined;
|
|
4661
|
-
const placementConclusions = plugin.installedPlacements.
|
|
4635
|
+
const placementConclusions = plugin.installedPlacements.flatMap((placement) => pluginPlacementConclusions(placement).map((conclusion, index) => ({
|
|
4662
4636
|
platform: placement.platform,
|
|
4663
|
-
|
|
4664
|
-
|
|
4637
|
+
key: `${placement.platform}:${index}`,
|
|
4638
|
+
...conclusion,
|
|
4639
|
+
})));
|
|
4665
4640
|
const hasUnavailablePlacement = placementConclusions.some((placement) => placement.status === 'error');
|
|
4666
4641
|
const hasUncertainPlacement = placementConclusions.some((placement) => placement.status === 'warning');
|
|
4667
4642
|
const confirmedAvailablePlacements = placementConclusions.filter((placement) => placement.status === 'success');
|
|
4668
|
-
const
|
|
4643
|
+
const placementPageRows = Math.min(2, placementConclusions.length);
|
|
4644
|
+
const placementOffset = Math.min(batchTargetOffset, Math.max(0, placementConclusions.length - placementPageRows));
|
|
4645
|
+
const visiblePlacementConclusions = placementConclusions.slice(placementOffset, placementOffset + placementPageRows);
|
|
4646
|
+
placementConclusionPagination = placementConclusions.length > placementPageRows
|
|
4647
|
+
? { total: placementConclusions.length, pageRows: placementPageRows } : undefined;
|
|
4648
|
+
if (placementConclusionPagination) {
|
|
4649
|
+
help = 'PgUp/PgDn 查看全部使用位置 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
4650
|
+
}
|
|
4651
|
+
const detailStaticRows = 3 + visiblePlacementConclusions.length
|
|
4652
|
+
+ (updateDescription ? policy.mode === 'compact' ? 1 : 4 : 0)
|
|
4653
|
+
+ (dependencyDetailText ? 1 : 0)
|
|
4654
|
+
+ 3;
|
|
4655
|
+
const detailViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(detailStaticRows));
|
|
4669
4656
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StatusCard, { status: hasUnavailablePlacement ? 'error'
|
|
4670
4657
|
: hasUncertainPlacement ? 'warning'
|
|
4671
4658
|
: confirmedAvailablePlacements.length > 0 ? 'success' : 'info', title: hasUnavailablePlacement ? '部分使用位置暂时不可用'
|
|
4672
4659
|
: hasUncertainPlacement ? '部分使用位置需要处理'
|
|
4673
|
-
: confirmedAvailablePlacements.length > 0 ? '已确认的使用位置可用' : '尚未确认使用位置',
|
|
4660
|
+
: confirmedAvailablePlacements.length > 0 ? '已确认的使用位置可用' : '尚未确认使用位置', meta: placementConclusionPagination
|
|
4661
|
+
? `${placementOffset + 1}–${placementOffset + visiblePlacementConclusions.length}/${placementConclusions.length}`
|
|
4662
|
+
: undefined, children: visiblePlacementConclusions.map((placement) => _jsx(StaticRow, { title: platformLabel(placement.platform), meta: placement.text, status: placement.status, compact: true }, placement.key)) }), updateDescription
|
|
4663
|
+
? policy.mode === 'compact'
|
|
4664
|
+
? _jsx(StaticRow, { title: "\u6709\u53EF\u7528\u66F4\u65B0", meta: updateDescription, status: "warning", compact: true })
|
|
4665
|
+
: _jsx(Callout, { status: "warning", title: "\u6709\u53EF\u7528\u66F4\u65B0", description: updateDescription })
|
|
4666
|
+
: null, dependencyDetailText ? _jsx(StaticRow, { title: dependencyDetailText, status: "muted", compact: true }) : null, _jsx(SectionCard, { title: "\u63D2\u4EF6\u64CD\u4F5C", children: _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: detailViewport.offset, limit: detailViewport.limit }) })] });
|
|
4674
4667
|
}
|
|
4675
4668
|
else if (route.name === 'pluginMore' && plugin) {
|
|
4676
4669
|
breadcrumb = `我的插件 / ${plugin.displayName} / 更多操作`;
|
|
@@ -4727,7 +4720,7 @@ export function ConsoleAppV4(props) {
|
|
|
4727
4720
|
};
|
|
4728
4721
|
if (action.id === 'dependencies')
|
|
4729
4722
|
return {
|
|
4730
|
-
label: '
|
|
4723
|
+
label: '依赖与当前可用关系',
|
|
4731
4724
|
description: dependencySummary?.issueCount ? `${dependencySummary.issueCount} 项需要处理` : '查看完整关系',
|
|
4732
4725
|
meta: dependencySummary ? dependencySummaryText(dependencySummary) : undefined,
|
|
4733
4726
|
run: () => go({ name: 'pluginDependencies', pluginId: plugin.pluginId }),
|
|
@@ -4762,8 +4755,8 @@ export function ConsoleAppV4(props) {
|
|
|
4762
4755
|
};
|
|
4763
4756
|
}),
|
|
4764
4757
|
...(!detailMenu.some((action) => action.id === 'dependencies') ? [{
|
|
4765
|
-
label: '
|
|
4766
|
-
description: '
|
|
4758
|
+
label: '依赖与当前可用关系',
|
|
4759
|
+
description: '查看必需依赖、声明者和当前可用关系;当前没有声明的必需依赖',
|
|
4767
4760
|
run: () => go({ name: 'pluginDependencies', pluginId: plugin.pluginId }),
|
|
4768
4761
|
}] : []),
|
|
4769
4762
|
{ label: '使用说明', run: () => go({ name: 'pluginAbout', pluginId: plugin.pluginId }) },
|
|
@@ -4824,7 +4817,7 @@ export function ConsoleAppV4(props) {
|
|
|
4824
4817
|
if (action.id === 'addScope')
|
|
4825
4818
|
return {
|
|
4826
4819
|
label: `在${scopeLabel(action.scope)}中启用…`,
|
|
4827
|
-
description: '
|
|
4820
|
+
description: '增加这个使用位置;已被其它项目共用的内容保持不变',
|
|
4828
4821
|
run: () => beginSecondScope(plugin, action.platform, action.scope),
|
|
4829
4822
|
};
|
|
4830
4823
|
if (action.id === 'about')
|
|
@@ -4870,7 +4863,7 @@ export function ConsoleAppV4(props) {
|
|
|
4870
4863
|
description: placement?.state === 'installed'
|
|
4871
4864
|
? (placement.scopedPlacements?.find((entry) => entry.scope === action.scope)?.recovery
|
|
4872
4865
|
?? placement.recovery)?.find((entry) => entry.command === 'sync')?.description
|
|
4873
|
-
?? '
|
|
4866
|
+
?? '重新检查已保存位置,并在操作汇总中显示需要处理的项目'
|
|
4874
4867
|
: undefined,
|
|
4875
4868
|
run: () => placement?.state === 'installed'
|
|
4876
4869
|
? beginReview({ kind: 'pluginWrite', action: 'sync', pluginId: plugin.pluginId, platform: action.platform, scope: action.scope })
|
|
@@ -4913,7 +4906,7 @@ export function ConsoleAppV4(props) {
|
|
|
4913
4906
|
&& !platformMenu.some((action) => action.id === 'resolveScopeConflict')
|
|
4914
4907
|
? {
|
|
4915
4908
|
label: '检查受限清理…',
|
|
4916
|
-
description: '
|
|
4909
|
+
description: '只在当前单一位置能确认内容只属于此插件时提供;先核验,再取消使用设置并尽力清理;被共用或不属于插件的内容保留。',
|
|
4917
4910
|
status: 'warning',
|
|
4918
4911
|
run: () => beginRestrictedForceCleanup(plugin.pluginId, route.platform, placement.scope),
|
|
4919
4912
|
}
|
|
@@ -4925,10 +4918,17 @@ export function ConsoleAppV4(props) {
|
|
|
4925
4918
|
];
|
|
4926
4919
|
breadcrumb = `${plugin.displayName} / ${platformLabel(route.platform)}`;
|
|
4927
4920
|
const installedPlacementRows = placement?.state === 'installed' ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u5DF2\u4FDD\u5B58\u4F4D\u7F6E", meta: placement.desiredScopes?.map(scopeLabel).join('、') || '无', compact: true }), _jsx(StaticRow, { title: "\u5F53\u524D\u4F4D\u7F6E", meta: placement.actualScopes?.map(scopeLabel).join('、') || '未启用', compact: true }), _jsx(StaticRow, { title: "\u72B6\u6001", meta: placement.actualState === 'ready' ? '可用'
|
|
4928
|
-
: placement.actualState === 'needsSync'
|
|
4921
|
+
: placement.actualState === 'needsSync'
|
|
4922
|
+
? placement.sharedNative?.reason === 'outdated'
|
|
4923
|
+
? placement.revision.state === 'upgradeAvailable' ? '有更新' : '版本待同步'
|
|
4924
|
+
: '需要同步'
|
|
4929
4925
|
: placement.actualState === 'blocked' ? '已阻断'
|
|
4930
4926
|
: placement.health === 'incomplete' ? '需要处理' : '暂时不可用', status: placement.actualState === 'ready' ? 'success' : placement.actualState === 'blocked' ? 'error' : 'warning', compact: true }), placement.health !== 'ready'
|
|
4931
|
-
? _jsx(StaticRow, { title: "\u539F\u56E0", meta: placement.blockingReason === 'artifactCollision'
|
|
4927
|
+
? _jsx(StaticRow, { title: "\u539F\u56E0", meta: placement.blockingReason === 'artifactCollision'
|
|
4928
|
+
? '输出位置存在冲突内容'
|
|
4929
|
+
: placement.sharedNative?.reason === 'outdated'
|
|
4930
|
+
? '已安装版本与当前 Catalog 版本不一致'
|
|
4931
|
+
: typedIssue?.explanation ?? '安装状态需要同步,请查看问题详情', status: "warning", compact: true })
|
|
4932
4932
|
: null] }) : null;
|
|
4933
4933
|
if (plugin.aggregateStatus === 'unavailable') {
|
|
4934
4934
|
const sourceOverview = capabilityUnavailable ? undefined : props.controller.getSourceOverview(plugin.sourceId);
|
|
@@ -5098,10 +5098,10 @@ export function ConsoleAppV4(props) {
|
|
|
5098
5098
|
? (activeGroup?.fields ?? []).filter((field) => field.sharedNativeRender && !field.writable)
|
|
5099
5099
|
: [];
|
|
5100
5100
|
if (projectSharedNativeFields.length > 0) {
|
|
5101
|
-
description += '
|
|
5101
|
+
description += ' 此设置由个人默认控制被各项目共用的内容;当前项目不可改。更改影响所有项目。';
|
|
5102
5102
|
}
|
|
5103
5103
|
if (projectSharedNativeFields.some(configFieldCanUnset)) {
|
|
5104
|
-
description += '
|
|
5104
|
+
description += ' 本项目旧值不再使用;当前继承个人或插件默认。请删除旧值。';
|
|
5105
5105
|
}
|
|
5106
5106
|
if (!readonly && configDraftIssues.length > 0) {
|
|
5107
5107
|
description += ' 字段已变化;失效草稿不会保存。';
|
|
@@ -5132,7 +5132,7 @@ export function ConsoleAppV4(props) {
|
|
|
5132
5132
|
: readonly
|
|
5133
5133
|
? field.sourceLabel === '未设置' ? '没有任何位置提供值' : `来自${field.sourceLabel}`
|
|
5134
5134
|
: !configFieldCanSet(field) && configFieldCanUnset(field)
|
|
5135
|
-
? '
|
|
5135
|
+
? '本项目旧值不再使用 · 当前继承个人或插件默认 · 可删除旧值'
|
|
5136
5136
|
: `${field.description ? `${field.description} · ` : ''}当前有效:${effectiveFieldDisplay(field)} · ${field.effectiveSourceLabel}`,
|
|
5137
5137
|
meta: readonly ? effectiveFieldDisplay(field) : currentFieldDisplay(field),
|
|
5138
5138
|
configKey: field.key,
|
|
@@ -5230,61 +5230,98 @@ export function ConsoleAppV4(props) {
|
|
|
5230
5230
|
}
|
|
5231
5231
|
else if (route.name === 'configSave' && plugin && currentConfigPage) {
|
|
5232
5232
|
const changes = configChanges();
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
.
|
|
5237
|
-
.
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
{
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
run: () => beginConfigSave(false),
|
|
5267
|
-
},
|
|
5268
|
-
...(hasConsumers ? [{
|
|
5269
|
-
label: '只保存,稍后应用',
|
|
5270
|
-
description: '保存所选设置层,不重新应用当前目标',
|
|
5271
|
-
run: () => beginConfigSave(false),
|
|
5272
|
-
}] : configSaveImpact.impactState === 'unknown' ? [{
|
|
5233
|
+
if (route.view === 'changes') {
|
|
5234
|
+
const lines = changeDetailLines(changes, size.columns - 4);
|
|
5235
|
+
const pageRows = responsiveBudget(5, 10);
|
|
5236
|
+
const detailOffset = Math.min(batchTargetOffset, Math.max(0, lines.length - 1));
|
|
5237
|
+
const visibleLines = lines.slice(detailOffset, detailOffset + pageRows);
|
|
5238
|
+
referenceDetailPagination = { total: lines.length, pageRows };
|
|
5239
|
+
breadcrumb = `${plugin.displayName} / 设置 / 完整变化`;
|
|
5240
|
+
context = `${Math.min(detailOffset + 1, lines.length)}–${Math.min(detailOffset + visibleLines.length, lines.length)} / ${lines.length}`;
|
|
5241
|
+
title = '完整设置变化';
|
|
5242
|
+
description = '逐项显示修改前和修改后的完整值。';
|
|
5243
|
+
help = 'PgUp/PgDn 阅读 · Enter 返回保存汇总 · Esc 返回保存汇总';
|
|
5244
|
+
actions = [{ label: '返回保存汇总', run: back }];
|
|
5245
|
+
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
|
|
5246
|
+
? _jsx(StaticRow, { title: `↓ 后面还有 ${lines.length - detailOffset - visibleLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
5247
|
+
}
|
|
5248
|
+
else {
|
|
5249
|
+
const affectedTargets = configSaveImpact?.affectedTargets ?? [];
|
|
5250
|
+
const hasConsumers = configSaveImpact?.impactState === 'known' && affectedTargets.length > 0;
|
|
5251
|
+
const visibleAffectedTargets = affectedTargets.slice(0, 1);
|
|
5252
|
+
const impactRowCount = 2;
|
|
5253
|
+
const configSummaryLimit = 1;
|
|
5254
|
+
const visibleChanges = changes.slice(0, configSummaryLimit);
|
|
5255
|
+
const targetSummary = affectedTargets
|
|
5256
|
+
.map((target) => `${platformLabel(target.platform)} · ${scopeLabel(target.scope)}`)
|
|
5257
|
+
.join('、');
|
|
5258
|
+
breadcrumb = `${plugin.displayName} / 设置 / 保存汇总`;
|
|
5259
|
+
context = `${changes.length} 项未保存`;
|
|
5260
|
+
title = `保存 ${changes.length} 项设置修改?`;
|
|
5261
|
+
description = route.layer.scope === 'project'
|
|
5262
|
+
? '修改将保存到当前项目。'
|
|
5263
|
+
: '修改将保存为个人默认,并影响个人的所有项目;项目设置仍可覆盖。';
|
|
5264
|
+
actions = configSaveImpactError ? [
|
|
5265
|
+
{
|
|
5273
5266
|
label: '重新检查影响',
|
|
5274
|
-
description: '
|
|
5267
|
+
description: '重新读取当前安装位置;检查成功前不能保存',
|
|
5275
5268
|
run: () => setConfigSaveImpactAttempt((value) => value + 1),
|
|
5276
|
-
}
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5269
|
+
},
|
|
5270
|
+
{ label: '返回修改', run: back },
|
|
5271
|
+
] : configSaveImpact ? [
|
|
5272
|
+
hasConsumers ? {
|
|
5273
|
+
label: '保存并生效',
|
|
5274
|
+
description: `保存设置,并重新应用:${targetSummary}`,
|
|
5275
|
+
status: 'success',
|
|
5276
|
+
run: () => beginConfigSave(true),
|
|
5277
|
+
} : configSaveImpact.impactState === 'unknown' ? {
|
|
5278
|
+
label: '仅保存设置(应用范围尚未确认)',
|
|
5279
|
+
description: '保存所选设置层;不扩大到未确认的安装位置',
|
|
5280
|
+
status: 'warning',
|
|
5281
|
+
run: () => beginConfigSave(false),
|
|
5282
|
+
} : {
|
|
5283
|
+
label: '保存设置',
|
|
5284
|
+
description: '当前修改没有需要重新应用的已安装目标',
|
|
5285
|
+
status: 'success',
|
|
5286
|
+
run: () => beginConfigSave(false),
|
|
5287
|
+
},
|
|
5288
|
+
...(hasConsumers ? [{
|
|
5289
|
+
label: '只保存,稍后应用',
|
|
5290
|
+
description: '保存所选设置层,不重新应用当前目标',
|
|
5291
|
+
run: () => beginConfigSave(false),
|
|
5292
|
+
}] : configSaveImpact.impactState === 'unknown' ? [{
|
|
5293
|
+
label: '重新检查影响',
|
|
5294
|
+
description: '再次读取当前安装位置和配置消费者',
|
|
5295
|
+
run: () => setConfigSaveImpactAttempt((value) => value + 1),
|
|
5296
|
+
}] : []),
|
|
5297
|
+
{ label: '返回修改', run: back },
|
|
5298
|
+
] : [{ label: '返回修改', run: back }];
|
|
5299
|
+
actions.splice(Math.max(0, actions.length - 1), 0, {
|
|
5300
|
+
label: '阅读完整设置变化',
|
|
5301
|
+
description: '分页查看每项修改前和修改后的完整值',
|
|
5302
|
+
run: () => {
|
|
5303
|
+
setBatchTargetOffset(0);
|
|
5304
|
+
go({ ...route, view: 'changes' });
|
|
5305
|
+
},
|
|
5306
|
+
});
|
|
5307
|
+
const configSaveStaticRows = 6 + visibleChanges.length * 2 + impactRowCount;
|
|
5308
|
+
const configSaveActionViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(configSaveStaticRows));
|
|
5309
|
+
const changeSectionTitle = visibleChanges.length < changes.length
|
|
5310
|
+
? `设置变更 · 显示 ${visibleChanges.length}/${changes.length}(另 ${changes.length - visibleChanges.length} 项)`
|
|
5311
|
+
: '设置变更';
|
|
5312
|
+
const impactSectionTitle = hasConsumers && visibleAffectedTargets.length < affectedTargets.length
|
|
5313
|
+
? `应用影响 · 显示 ${visibleAffectedTargets.length}/${affectedTargets.length}(另 ${affectedTargets.length - visibleAffectedTargets.length} 个)`
|
|
5314
|
+
: '应用影响';
|
|
5315
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SectionCard, { title: changeSectionTitle, compact: policy.mode === 'compact', children: visibleChanges.map((change) => _jsx(ReviewChangeRow, { title: `~ ${draftRemoves.includes(change.key) ? `删除 ${change.title} 中的值` : change.title}`, value: `${change.before} → ${change.after}`, compact: true }, change.key)) }), _jsxs(SectionCard, { title: impactSectionTitle, compact: policy.mode === 'compact', children: [!configSaveImpact && !configSaveImpactError
|
|
5316
|
+
? _jsx(ProgressRow, { title: "\u5206\u6790\u5B9E\u9645\u914D\u7F6E\u6D88\u8D39\u8005", state: "active" })
|
|
5317
|
+
: hasConsumers
|
|
5318
|
+
? visibleAffectedTargets.map((target) => _jsx(StaticRow, { title: `${platformLabel(target.platform)} · ${scopeLabel(target.scope)}`, meta: "\u9700\u8981\u91CD\u65B0\u5E94\u7528", status: "warning", compact: true }, `${target.platform}:${target.scope}`))
|
|
5319
|
+
: _jsx(StaticRow, { title: configSaveImpactError
|
|
5320
|
+
? '影响检查失败;设置尚未保存'
|
|
5321
|
+
: configSaveImpact?.impactState === 'unknown'
|
|
5322
|
+
? '应用范围尚未确认;可以仅保存并稍后重查'
|
|
5323
|
+
: '没有需要重新应用的已安装目标', status: configSaveImpactError || configSaveImpact?.impactState === 'unknown' ? 'warning' : 'success', compact: true }), _jsx(StaticRow, { title: "\u5176\u4ED6\u8BBE\u7F6E\u5C42\u4FDD\u6301\u4E0D\u53D8", status: "success", compact: true })] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: configSaveActionViewport.offset, limit: configSaveActionViewport.limit })] });
|
|
5324
|
+
}
|
|
5288
5325
|
}
|
|
5289
5326
|
else if (route.name === 'configFieldAction' && plugin && activeField) {
|
|
5290
5327
|
const layer = configLayerLabel(route.layer);
|
|
@@ -5314,7 +5351,7 @@ export function ConsoleAppV4(props) {
|
|
|
5314
5351
|
content = _jsxs(Box, { flexDirection: "column", children: [_jsxs(SectionCard, { children: [activeField.invalidOverrideIssue
|
|
5315
5352
|
? _jsx(StaticRow, { title: "\u5F53\u524D\u8986\u76D6\u65E0\u6548", meta: activeField.invalidOverrideIssue, status: "warning" })
|
|
5316
5353
|
: null, !configFieldCanSet(activeField) && configFieldCanUnset(activeField)
|
|
5317
|
-
? _jsx(StaticRow, { title: "\u4E0D\u518D\
|
|
5354
|
+
? _jsx(StaticRow, { title: "\u672C\u9879\u76EE\u65E7\u503C\u4E0D\u518D\u4F7F\u7528", meta: "\u5F53\u524D\u7EE7\u627F\u4E2A\u4EBA\u6216\u63D2\u4EF6\u9ED8\u8BA4\uFF1B\u5220\u9664\u65E7\u503C\u540E\u4FDD\u6301\u7EE7\u627F", status: "warning" })
|
|
5318
5355
|
: null, _jsx(StaticRow, { title: `${layer}中的值`, meta: currentFieldDisplay(activeField) }), _jsx(StaticRow, { title: "\u5F53\u524D\u5B9E\u9645\u751F\u6548", meta: `${effectiveFieldDisplay(activeField)} · 来自${activeField.effectiveSourceLabel}` }), !activeField.invalidOverrideIssue || activeField.invalidOverrideOwnedByLayer
|
|
5319
5356
|
? _jsx(StaticRow, { title: "\u5220\u9664\u540E\u5C06\u6062\u590D", meta: `${activeField.fallbackDisplayValue ?? '未设置'} · 来自${activeField.fallbackSourceLabel ?? '未设置'}` })
|
|
5320
5357
|
: null] }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
@@ -5591,217 +5628,6 @@ export function ConsoleAppV4(props) {
|
|
|
5591
5628
|
]), _jsx(StaticRow, { title: "stage", meta: safeDiagnosticCode(route.diagnosticStage, 'read-config'), compact: true })] }) : null, unsupportedRows, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] })
|
|
5592
5629
|
: _jsxs(Box, { flexDirection: "column", children: [_jsx(DiagnosticSummary, { diagnostic: diagnostic, technical: showTechnical, compact: policy.mode === 'compact' }), unsupportedRows, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
5593
5630
|
}
|
|
5594
|
-
else if (route.name === 'catalogManagement') {
|
|
5595
|
-
breadcrumb = '插件来源 / 目录管理';
|
|
5596
|
-
title = '目录管理';
|
|
5597
|
-
description = '选择任务后才读取对应的本地状态。';
|
|
5598
|
-
actions = [
|
|
5599
|
-
{ label: 'Catalog 工作区', description: '选择、创建、查看状态、修改版本、构建和验证', run: () => go({ name: 'catalogWorkspace', view: 'overview' }) },
|
|
5600
|
-
{ label: '开发来源', description: '查看、启用或停用当前 Workspace 的开发来源', run: () => go({ name: 'catalogDev' }) },
|
|
5601
|
-
{ label: '本地存储', description: '查看保留项并预览可安全清理的空间', run: () => go({ name: 'catalogStore' }) },
|
|
5602
|
-
{ label: 'Catalog 发布', description: '准备计划、独立应用和恢复可信 pending 计划', run: () => go({ name: 'catalogPublish', step: 'overview' }) },
|
|
5603
|
-
];
|
|
5604
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(CatalogManagementIntro, {}), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "task", compact: policy.mode === 'compact' })] });
|
|
5605
|
-
}
|
|
5606
|
-
else if (route.name === 'catalogWorkspace' && route.view === 'overview') {
|
|
5607
|
-
const model = catalogWorkspace ? {
|
|
5608
|
-
label: catalogWorkspace.label,
|
|
5609
|
-
state: catalogWorkspace.state,
|
|
5610
|
-
workspaceIdentity: catalogWorkspace.identity ?? undefined,
|
|
5611
|
-
catalogVersion: catalogWorkspace.catalog.version ?? undefined,
|
|
5612
|
-
channel: catalogWorkspace.catalog.channel ?? undefined,
|
|
5613
|
-
pluginCount: catalogWorkspace.plugins.length,
|
|
5614
|
-
snapshotState: catalogWorkspace.snapshot.state,
|
|
5615
|
-
gitState: !catalogWorkspace.git.checked ? '未检查'
|
|
5616
|
-
: !catalogWorkspace.git.hasHead ? '没有 HEAD'
|
|
5617
|
-
: catalogWorkspace.git.clean ? 'clean' : '有未提交变化',
|
|
5618
|
-
issues: catalogWorkspace.issues.map((issue) => issue.message),
|
|
5619
|
-
} : undefined;
|
|
5620
|
-
breadcrumb = '目录管理 / Catalog 工作区';
|
|
5621
|
-
title = 'Catalog 工作区';
|
|
5622
|
-
description = '状态读取不会 build、fetch、创建生成目录或运行插件代码。';
|
|
5623
|
-
actions = [
|
|
5624
|
-
{ label: '选择其他工作区…', description: '输入路径;界面只显示目录名', run: () => { setCatalogInput(''); go({ name: 'catalogWorkspace', view: 'select' }); } },
|
|
5625
|
-
...(catalogWorkspace?.state !== 'ready' ? [{
|
|
5626
|
-
label: '在所选目录创建工作区…', description: '输入 owner、显示名称和初始 Catalog 版本',
|
|
5627
|
-
run: () => { setCatalogInput(catalogWorkspaceDraft.ownerName); go({ name: 'catalogWorkspace', view: 'create', step: 'ownerName' }); },
|
|
5628
|
-
}] : []),
|
|
5629
|
-
...(catalogWorkspace?.state === 'ready' ? [
|
|
5630
|
-
{ label: '修改 Catalog 版本…', description: '选择 bump,或输入稳定版和精确 beta 版本', run: () => go({ name: 'catalogWorkspace', view: 'version' }) },
|
|
5631
|
-
...(catalogWorkspace.snapshot.state === 'absent' ? [{
|
|
5632
|
-
label: '构建 Catalog…', description: `bundle 并验证 ${catalogWorkspace.plugins.length} 个 canonical plugins;写入 .aw/catalog`,
|
|
5633
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceBuild' }),
|
|
5634
|
-
}] : catalogWorkspace.snapshot.valid ? [{
|
|
5635
|
-
label: '重新构建 Catalog…', description: '替换已证明为生成物的 .aw/catalog;不删除其他内容',
|
|
5636
|
-
status: 'warning',
|
|
5637
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceBuild', force: true }),
|
|
5638
|
-
}] : [{
|
|
5639
|
-
label: '生成目录无效,不能自动替换', description: '请检查问题并移开无法证明为生成物的目录后再构建',
|
|
5640
|
-
status: 'error', disabled: '现有生成目录未通过安全验证',
|
|
5641
|
-
}]),
|
|
5642
|
-
{ label: '完整验证生成目录', description: '只读验证现有 .aw/catalog,不重新构建', run: async () => {
|
|
5643
|
-
setCatalogLoading(true);
|
|
5644
|
-
setCatalogValidation(undefined);
|
|
5645
|
-
setCatalogInputError(undefined);
|
|
5646
|
-
try {
|
|
5647
|
-
setCatalogValidation(await props.controller.validateCatalogWorkspace());
|
|
5648
|
-
}
|
|
5649
|
-
catch (error) {
|
|
5650
|
-
setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], []));
|
|
5651
|
-
}
|
|
5652
|
-
finally {
|
|
5653
|
-
setCatalogLoading(false);
|
|
5654
|
-
}
|
|
5655
|
-
} },
|
|
5656
|
-
] : []),
|
|
5657
|
-
];
|
|
5658
|
-
const viewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(6));
|
|
5659
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(CatalogWorkspaceSummary, { model: model, loading: catalogLoading }), catalogValidation ? _jsxs(SectionCard, { title: "\u5B8C\u6574\u9A8C\u8BC1\u7ED3\u679C", children: [_jsx(StaticRow, { title: catalogValidation.state === 'valid' ? '生成目录有效' : catalogValidation.state === 'absent' ? '生成目录不存在' : '生成目录无效', meta: catalogValidation.catalogVersion ?? undefined, status: catalogValidation.state === 'valid' ? 'success' : 'warning', compact: true }), catalogValidation.issues.map((issue) => _jsx(StaticRow, { title: issue.message, meta: issue.code, status: "warning", compact: true }, issue.code))] }) : null, catalogInputError ? _jsx(Callout, { status: "error", title: "\u65E0\u6CD5\u8BFB\u53D6\u5DE5\u4F5C\u533A", description: catalogInputError }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: viewport.offset, limit: viewport.limit })] });
|
|
5660
|
-
}
|
|
5661
|
-
else if (route.name === 'catalogWorkspace' && route.view === 'select') {
|
|
5662
|
-
breadcrumb = '目录管理 / Catalog 工作区 / 选择';
|
|
5663
|
-
title = '输入 Workspace 路径';
|
|
5664
|
-
description = '相对路径从当前目录解析;输入保持在本地,不写入配置。';
|
|
5665
|
-
help = '输入 · Enter 选择 · Ctrl-U 清空 · Esc 取消';
|
|
5666
|
-
content = _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: privatePathInput(catalogInput), columns: Math.max(8, size.columns - 8) }), description: catalogInputError ?? '留空可恢复从当前目录自动发现。', status: catalogInputError ? 'error' : undefined });
|
|
5667
|
-
}
|
|
5668
|
-
else if (route.name === 'catalogWorkspace' && route.view === 'create') {
|
|
5669
|
-
const step = route.step ?? 'ownerName';
|
|
5670
|
-
breadcrumb = '目录管理 / Catalog 工作区 / 创建';
|
|
5671
|
-
context = { ownerName: '第 1 步,共 4 步', ownerUrl: '第 2 步,共 4 步', displayName: '第 3 步,共 4 步', catalogVersion: '第 4 步,共 4 步' }[step];
|
|
5672
|
-
title = { ownerName: '输入 owner 名称', ownerUrl: '输入 owner URL', displayName: '输入 Catalog 显示名称', catalogVersion: '输入初始 Catalog 版本' }[step];
|
|
5673
|
-
description = step === 'catalogVersion' ? '允许稳定 x.y.z 或精确 x.y.z-beta.N。' : '所有字段会在创建确认中再次显示。';
|
|
5674
|
-
help = '输入 · Enter 继续 · Ctrl-U 清空 · Esc 取消';
|
|
5675
|
-
const displayValue = step === 'ownerUrl'
|
|
5676
|
-
? catalogInput ? `已输入 owner URL(${Array.from(catalogInput).length} 字符)` : ''
|
|
5677
|
-
: catalogInput;
|
|
5678
|
-
content = _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: displayValue, columns: Math.max(8, size.columns - 8) }), description: catalogInputError ?? '按 Enter 继续。', status: catalogInputError ? 'error' : undefined });
|
|
5679
|
-
}
|
|
5680
|
-
else if (route.name === 'catalogWorkspace' && route.view === 'version') {
|
|
5681
|
-
breadcrumb = '目录管理 / Catalog 工作区 / 版本';
|
|
5682
|
-
title = route.step === 'catalogVersion' ? '输入精确 Catalog 版本' : '修改 Catalog 版本';
|
|
5683
|
-
description = route.step === 'catalogVersion' ? '允许稳定 x.y.z 或精确 x.y.z-beta.N。' : `当前版本:${catalogWorkspace?.catalog.version ?? '未知'}`;
|
|
5684
|
-
if (route.step === 'catalogVersion') {
|
|
5685
|
-
help = '输入 · Enter 确认 · Ctrl-U 清空 · Esc 取消';
|
|
5686
|
-
content = _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: catalogInput, columns: Math.max(8, size.columns - 8) }), description: catalogInputError ?? '此动作会进入独立确认。', status: catalogInputError ? 'error' : undefined });
|
|
5687
|
-
}
|
|
5688
|
-
else {
|
|
5689
|
-
actions = [
|
|
5690
|
-
{ label: '提高 patch 版本', run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceVersion', bump: 'patch' }, { name: 'catalogWorkspace', view: 'overview' }) },
|
|
5691
|
-
{ label: '提高 minor 版本', run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceVersion', bump: 'minor' }, { name: 'catalogWorkspace', view: 'overview' }) },
|
|
5692
|
-
{ label: '提高 major 版本', run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceVersion', bump: 'major' }, { name: 'catalogWorkspace', view: 'overview' }) },
|
|
5693
|
-
{ label: '输入精确版本…', description: '用于指定稳定版或精确 beta.N', run: () => { setCatalogInput(''); go({ name: 'catalogWorkspace', view: 'version', step: 'catalogVersion' }); } },
|
|
5694
|
-
];
|
|
5695
|
-
content = _jsx(SemanticRows, { actions: actions, focus: focus, kind: "choice", compact: policy.mode === 'compact' });
|
|
5696
|
-
}
|
|
5697
|
-
}
|
|
5698
|
-
else if (route.name === 'catalogDev' && (!route.step || route.step === 'overview')) {
|
|
5699
|
-
const snapshotReady = catalogDev?.snapshot.state === 'current' && catalogDev.snapshot.valid;
|
|
5700
|
-
breadcrumb = '目录管理 / 开发来源';
|
|
5701
|
-
title = '开发来源';
|
|
5702
|
-
description = '状态只读取所选 Workspace、managed Path source 和 Active digest。';
|
|
5703
|
-
actions = [
|
|
5704
|
-
{ label: '设置开发来源 ID…', description: catalogDevSourceId || '使用安全默认值', run: () => { setCatalogInput(catalogDevSourceId); go({ name: 'catalogDev', step: 'sourceId' }); } },
|
|
5705
|
-
...!snapshotReady ? catalogDev?.snapshot.state === 'absent' ? [
|
|
5706
|
-
{ label: '先构建 Catalog…', description: '先完成独立构建确认;构建成功后返回此页再确认启用',
|
|
5707
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceBuild' }, { name: 'catalogDev' }) },
|
|
5708
|
-
] : catalogDev?.snapshot.state === 'stale' && catalogDev.snapshot.valid ? [
|
|
5709
|
-
{ label: '先重新构建 Catalog…', description: '独立确认替换受管的旧 .aw/catalog;成功后返回此页再确认启用',
|
|
5710
|
-
status: 'warning',
|
|
5711
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'workspaceBuild', force: true }, { name: 'catalogDev' }) },
|
|
5712
|
-
] : [
|
|
5713
|
-
{ label: '生成目录无效,不能自动替换', description: '请先在 Workspace 管理页检查问题;移开无法证明为生成物的目录后再构建',
|
|
5714
|
-
status: 'error', disabled: '现有生成目录未通过安全验证' },
|
|
5715
|
-
] : catalogDev?.source.exists ? [
|
|
5716
|
-
...!catalogDev.ready && snapshotReady ? [{
|
|
5717
|
-
label: '重新启用并同步开发来源…', description: '来源配置已存在;重新使用当前有效 snapshot 完成 sync 和 Active 切换',
|
|
5718
|
-
status: 'warning',
|
|
5719
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'devActivate',
|
|
5720
|
-
...(catalogDevSourceId ? { sourceId: catalogDevSourceId } : {}) }, { name: 'catalogDev' }),
|
|
5721
|
-
}] : [],
|
|
5722
|
-
{ label: '停用开发来源…', description: '保留 .aw/catalog;检查安装、设置和 Marketplace 引用', run: () => beginReview({ kind: 'catalogManagement', action: 'devDeactivate' }) },
|
|
5723
|
-
{ label: '停用并选择替代主来源…', description: '开发来源为主来源时使用', run: () => { setCatalogInput(''); go({ name: 'catalogDev', step: 'replacementPrimary' }); } },
|
|
5724
|
-
] : [
|
|
5725
|
-
{ label: '启用开发来源…', description: '使用当前有效 snapshot 注册 managed Path source 并 sync', run: () => beginReview({ kind: 'catalogManagement', action: 'devActivate', ...(catalogDevSourceId ? { sourceId: catalogDevSourceId } : {}) }) },
|
|
5726
|
-
{ label: '启用并设为主来源…', description: '将来源启用和主来源变化放在同一影响确认中', run: () => beginReview({ kind: 'catalogManagement', action: 'devActivate', primary: true, ...(catalogDevSourceId ? { sourceId: catalogDevSourceId } : {}) }) },
|
|
5727
|
-
],
|
|
5728
|
-
];
|
|
5729
|
-
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(StatusCard, { status: catalogDev?.ready ? 'success' : catalogDev?.state === 'needsAttention' ? 'warning' : 'info', title: catalogLoading ? '正在读取开发来源' : catalogDev?.ready ? '开发来源可用' : catalogDev?.state === 'inactive' ? '开发来源未启用' : '开发来源需要处理', children: catalogDev ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: "\u751F\u6210\u76EE\u5F55", meta: catalogDev.snapshot.state, compact: true }), _jsx(StaticRow, { title: "\u6765\u6E90", meta: catalogDev.source.id ?? '未注册', compact: true }), _jsx(StaticRow, { title: "Active", meta: catalogDev.active.ready ? '可用' : catalogDev.active.exists ? '需要处理' : '不存在', compact: true })] }) : null }), catalogInputError ? _jsx(Callout, { status: "error", title: "\u65E0\u6CD5\u8BFB\u53D6\u5F00\u53D1\u6765\u6E90", description: catalogInputError }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
5730
|
-
}
|
|
5731
|
-
else if (route.name === 'catalogDev') {
|
|
5732
|
-
const replacement = route.step === 'replacementPrimary';
|
|
5733
|
-
breadcrumb = '目录管理 / 开发来源 / 输入';
|
|
5734
|
-
title = replacement ? '输入替代主来源 ID' : '输入开发来源 ID';
|
|
5735
|
-
description = replacement ? '停用和主来源变化会进入同一次影响确认。' : '留空可使用安全默认 ID。';
|
|
5736
|
-
help = '输入 · Enter 继续 · Ctrl-U 清空 · Esc 取消';
|
|
5737
|
-
content = _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: catalogInput, columns: Math.max(8, size.columns - 8) }), description: catalogInputError ?? '按 Enter 继续。', status: catalogInputError ? 'error' : undefined });
|
|
5738
|
-
}
|
|
5739
|
-
else if (route.name === 'catalogStore') {
|
|
5740
|
-
const entries = catalogStore?.entries ?? [];
|
|
5741
|
-
const pageRows = responsiveBudget(3, 7);
|
|
5742
|
-
const entryOffset = Math.min(batchTargetOffset, Math.max(0, entries.length - 1));
|
|
5743
|
-
const entryEnd = Math.min(entries.length, entryOffset + pageRows);
|
|
5744
|
-
const reclaimable = entries.filter((entry) => entry.status === 'reclaimable');
|
|
5745
|
-
breadcrumb = '目录管理 / 本地存储';
|
|
5746
|
-
title = '本地 Catalog Store';
|
|
5747
|
-
description = '只清理已确认且执行时仍安全的弱状态;未知、foreign 和 Active 内容始终保留。';
|
|
5748
|
-
if (entries.length > pageRows)
|
|
5749
|
-
help = 'PgUp/PgDn 查看全部条目 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
5750
|
-
actions = [{
|
|
5751
|
-
label: '预览并清理可安全释放的空间…',
|
|
5752
|
-
description: `${reclaimable.length} 项;确认后新增候选不进入本次删除集合`,
|
|
5753
|
-
disabled: reclaimable.length ? undefined : '当前没有可安全清理的条目',
|
|
5754
|
-
run: () => beginReview({ kind: 'catalogManagement', action: 'storePrune', items: reclaimable.map((entry) => entry.item) }),
|
|
5755
|
-
}];
|
|
5756
|
-
content = _jsxs(Box, { flexDirection: "column", children: [catalogStore ? _jsx(CatalogStoreSummary, { reclaimableCount: catalogStore.totals.reclaimableEntries, reclaimableBytes: catalogStore.totals.reclaimableBytes ?? 0, retainedCount: catalogStore.totals.retainedEntries, entries: entries.map((entry) => ({ key: entry.itemKey, title: `${entry.category} · ${entry.itemKey}`, meta: `${entry.reason}${entry.reclaimableBytes === null ? '' : ` · ${entry.reclaimableBytes} bytes`}`, status: entry.status === 'error' ? 'unsafe' : entry.status === 'active' ? 'retained' : entry.status })), before: entryOffset, after: entryEnd }) : _jsx(StatusCard, { status: "info", title: "\u6B63\u5728\u8BFB\u53D6\u672C\u5730 Catalog Store" }), catalogInputError ? _jsx(Callout, { status: "error", title: "\u65E0\u6CD5\u8BFB\u53D6 Store", description: catalogInputError }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact' })] });
|
|
5757
|
-
}
|
|
5758
|
-
else if (route.name === 'catalogPublish' && route.step === 'overview') {
|
|
5759
|
-
const records = catalogPublication?.records ?? [];
|
|
5760
|
-
const pageRows = responsiveBudget(3, 7);
|
|
5761
|
-
const recordOffset = Math.min(batchTargetOffset, Math.max(0, records.length - 1));
|
|
5762
|
-
const recordEnd = Math.min(records.length, recordOffset + pageRows);
|
|
5763
|
-
breadcrumb = '目录管理 / Catalog 发布';
|
|
5764
|
-
title = 'Catalog 发布';
|
|
5765
|
-
description = '准备计划与应用计划是两个独立写入动作。';
|
|
5766
|
-
if (records.length > pageRows)
|
|
5767
|
-
help = 'PgUp/PgDn 查看全部记录 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
5768
|
-
actions = [
|
|
5769
|
-
{ label: '准备新发布计划…', description: '下一步输入 remote 或 URL 与 branch;执行 plan 会写 version-scoped journal 和隔离仓库', run: () => { setCatalogInput(catalogPublishDraft.expectedPlanDigest ? '' : catalogPublishDraft.target); setCatalogPublishDraft((draft) => draft.expectedPlanDigest ? { targetKind: 'remote', target: '', branch: 'catalog' } : draft); go({ name: 'catalogPublish', step: 'target' }); } },
|
|
5770
|
-
...records.filter((record) => record.canApply && record.planDigest).map((record) => ({
|
|
5771
|
-
label: `${record.state === 'uncertain' ? '对账或继续' : '应用'} ${record.catalogVersion}…`,
|
|
5772
|
-
description: record.requiresRemoteInput
|
|
5773
|
-
? '重新输入原 remote 名称或 URL;只恢复现有可信 plan digest'
|
|
5774
|
-
: '只使用现有可信 plan digest;不会从当前源码重建计划',
|
|
5775
|
-
status: record.state === 'uncertain' ? 'warning' : undefined,
|
|
5776
|
-
run: () => record.requiresRemoteInput
|
|
5777
|
-
? (() => {
|
|
5778
|
-
setCatalogPublishDraft({ targetKind: 'remote', target: '', branch: record.branch ?? 'catalog', expectedPlanDigest: record.planDigest });
|
|
5779
|
-
setCatalogInput('');
|
|
5780
|
-
go({ name: 'catalogPublish', step: 'target' });
|
|
5781
|
-
})()
|
|
5782
|
-
: beginReview({ kind: 'catalogManagement', action: 'publishApply', expectedPlanDigest: record.planDigest, ...(record.remote ? { remote: record.remote } : {}), ...(record.branch ? { branch: record.branch } : {}) }, { name: 'catalogPublish', step: 'overview' }),
|
|
5783
|
-
})),
|
|
5784
|
-
...records.filter((record) => record.mustIncreaseVersion).map((record) => ({
|
|
5785
|
-
label: `${record.catalogVersion} 无法恢复`, description: 'journal 或 pending repository 缺失或损坏;请提高 Catalog 版本后创建新计划', status: 'error', disabled: '不能重建或复用此版本',
|
|
5786
|
-
})),
|
|
5787
|
-
];
|
|
5788
|
-
const viewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(5));
|
|
5789
|
-
content = _jsxs(Box, { flexDirection: "column", children: [catalogPublication ? _jsx(CatalogPublicationSummary, { records: records.map((record) => ({ key: `${record.catalogVersion}:${record.state}`, catalogVersion: record.catalogVersion, state: record.state, branch: record.branch ?? undefined, message: record.issue?.message })), before: recordOffset, after: recordEnd }) : _jsx(StatusCard, { status: "info", title: "\u6B63\u5728\u8BFB\u53D6\u672C\u5730\u53D1\u5E03\u8BB0\u5F55" }), catalogInputError ? _jsx(Callout, { status: "error", title: "\u65E0\u6CD5\u8BFB\u53D6\u53D1\u5E03\u8BB0\u5F55", description: catalogInputError }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: viewport.offset, limit: viewport.limit })] });
|
|
5790
|
-
}
|
|
5791
|
-
else if (route.name === 'catalogPublish') {
|
|
5792
|
-
breadcrumb = '目录管理 / Catalog 发布 / 准备计划';
|
|
5793
|
-
title = route.step === 'target' ? '输入 remote 名称或 remote URL' : '输入发布 branch';
|
|
5794
|
-
description = route.step === 'target'
|
|
5795
|
-
? catalogPublishDraft.expectedPlanDigest
|
|
5796
|
-
? '重新输入原目标。后端会与现有 plan digest 中的目标身份核对。'
|
|
5797
|
-
: 'URL 只显示脱敏摘要;remote 名称按原样使用。'
|
|
5798
|
-
: '留空使用固定默认 branch:catalog。';
|
|
5799
|
-
help = '输入 · Enter 继续 · Ctrl-U 清空 · Esc 取消';
|
|
5800
|
-
const displayValue = route.step === 'target'
|
|
5801
|
-
? catalogInput ? `已输入远程目标(${Array.from(catalogInput).length} 字符)` : ''
|
|
5802
|
-
: catalogInput;
|
|
5803
|
-
content = _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: displayValue, columns: Math.max(8, size.columns - 8) }), description: catalogInputError ?? (route.step === 'branch' ? '执行 plan 会写 publication journal 和隔离仓库;取消 Review 不写入。' : '按 Enter 继续。'), status: catalogInputError ? 'error' : undefined });
|
|
5804
|
-
}
|
|
5805
5631
|
else if (route.name === 'sourceList') {
|
|
5806
5632
|
breadcrumb = '插件来源';
|
|
5807
5633
|
title = '插件来源';
|
|
@@ -5836,14 +5662,9 @@ export function ConsoleAppV4(props) {
|
|
|
5836
5662
|
description: '并行检查各来源;结果不会自动启用待检查版本',
|
|
5837
5663
|
run: () => props.controller.recheckAllCatalogSources(),
|
|
5838
5664
|
},
|
|
5839
|
-
{
|
|
5840
|
-
label: '目录管理…',
|
|
5841
|
-
description: 'Catalog 工作区、开发来源、本地存储和发布',
|
|
5842
|
-
run: () => go({ name: 'catalogManagement' }),
|
|
5843
|
-
},
|
|
5844
5665
|
];
|
|
5845
5666
|
const viewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, responsiveBudget(8, 12));
|
|
5846
|
-
const sourceCount = Math.max(0, actions.length -
|
|
5667
|
+
const sourceCount = Math.max(0, actions.length - 2);
|
|
5847
5668
|
content = _jsx(Box, { flexDirection: "column", children: _jsx(SemanticRows, { actions: actions, focus: focus, kind: focus < sourceCount ? 'section' : 'action', compact: policy.mode === 'compact', offset: viewport.offset, limit: viewport.limit }) });
|
|
5848
5669
|
}
|
|
5849
5670
|
else if (route.name === 'sourceDetail') {
|
|
@@ -6233,13 +6054,13 @@ export function ConsoleAppV4(props) {
|
|
|
6233
6054
|
setSourceTransportOverlay({ owner: active.owner });
|
|
6234
6055
|
setOverlayFocus(officialTransport === 'HTTPS' ? 0 : 1);
|
|
6235
6056
|
},
|
|
6236
|
-
}] : [{ label: draft?.type === 'path' || detail?.type === 'path' ? '本地目录' : 'Git 仓库地址',
|
|
6057
|
+
}] : [{ label: draft?.type === 'path' || detail?.type === 'path' ? '本地目录' : 'Git 仓库地址', meta: locationSummary, run: () => startDraftField('location') }]),
|
|
6237
6058
|
...(draft?.type === 'git' || !draft && detail?.type === 'git' ? [
|
|
6238
|
-
{ label: '版本引用',
|
|
6239
|
-
{ label: '高级:Catalog 子目录',
|
|
6059
|
+
{ label: '版本引用', meta: draft ? draft.refPolicy === 'explicit' ? `固定:${draft.ref}` : '跟随 AW 版本通道' : detail?.refPolicy === 'explicit' ? `固定:${detail.explicitRef}` : '跟随 AW 版本通道', run: () => startDraftField('refPolicy') },
|
|
6060
|
+
{ label: '高级:Catalog 子目录', meta: catalogSubdir === '' || catalogSubdir === undefined
|
|
6240
6061
|
? '仓库根目录' : catalogSubdir, run: () => startDraftField('subdir') },
|
|
6241
6062
|
] : []),
|
|
6242
|
-
{ label: '自动检查更新',
|
|
6063
|
+
{ label: '自动检查更新', meta: (draft?.autoCheck ?? detail?.autoCheck) ? '已开启' : '已关闭', selected: draft?.autoCheck ?? detail?.autoCheck, run: () => {
|
|
6243
6064
|
if (!draft) {
|
|
6244
6065
|
const source = props.controller.getConfiguredSource(route.sourceId);
|
|
6245
6066
|
if (!source)
|
|
@@ -6266,32 +6087,59 @@ export function ConsoleAppV4(props) {
|
|
|
6266
6087
|
}
|
|
6267
6088
|
else if (route.name === 'sourceSave' && sourceDraft?.owner === route.owner) {
|
|
6268
6089
|
const changes = sourceDraftChanges(sourceDraft);
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6090
|
+
if (route.view === 'changes') {
|
|
6091
|
+
const lines = changeDetailLines(changes, size.columns - 4);
|
|
6092
|
+
const pageRows = responsiveBudget(5, 10);
|
|
6093
|
+
const detailOffset = Math.min(batchTargetOffset, Math.max(0, lines.length - 1));
|
|
6094
|
+
const visibleLines = lines.slice(detailOffset, detailOffset + pageRows);
|
|
6095
|
+
referenceDetailPagination = { total: lines.length, pageRows };
|
|
6096
|
+
breadcrumb = `插件来源 / ${sourceDraft.sourceId} / 完整变化`;
|
|
6097
|
+
context = `${Math.min(detailOffset + 1, lines.length)}–${Math.min(detailOffset + visibleLines.length, lines.length)} / ${lines.length}`;
|
|
6098
|
+
title = '完整来源变化';
|
|
6099
|
+
description = '逐项显示修改前和修改后的完整值。';
|
|
6100
|
+
help = 'PgUp/PgDn 阅读 · Enter 返回修改汇总 · Esc 返回修改汇总';
|
|
6101
|
+
actions = [{ label: '返回修改汇总', run: back }];
|
|
6102
|
+
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
|
|
6103
|
+
? _jsx(StaticRow, { title: `↓ 后面还有 ${lines.length - detailOffset - visibleLines.length} 行`, status: "muted", compact: true }) : null, _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: true })] });
|
|
6104
|
+
}
|
|
6105
|
+
else {
|
|
6106
|
+
const savedSource = props.controller.getConfiguredSource(sourceDraft.sourceId);
|
|
6107
|
+
const protocolOnly = changes.length === 1 && changes[0]?.title === 'Git 仓库地址'
|
|
6108
|
+
&& savedSource?.type === 'git'
|
|
6109
|
+
&& (savedSource.url === OFFICIAL_CATALOG_SOURCE_URL
|
|
6110
|
+
|| savedSource.url === OFFICIAL_CATALOG_SOURCE_SSH_URL)
|
|
6111
|
+
&& (sourceDraft.location === OFFICIAL_CATALOG_SOURCE_URL
|
|
6112
|
+
|| sourceDraft.location === OFFICIAL_CATALOG_SOURCE_SSH_URL);
|
|
6113
|
+
breadcrumb = `插件来源 / ${sourceDraft.sourceId} / 修改汇总`;
|
|
6114
|
+
context = `${changes.length} 项未保存`;
|
|
6115
|
+
title = sourceDraft.mode === 'add' ? `保存新来源 ${sourceDraft.sourceId}?` : `保存 ${sourceDraft.sourceId} 的修改?`;
|
|
6116
|
+
description = '选择是否在保存后验证候选并启用。保存成功与启用成功会分别报告。';
|
|
6117
|
+
actions = [
|
|
6118
|
+
...(protocolOnly ? [] : [{ label: '保存并启用', description: '保存来源配置,再验证并切换当前目录版本', status: 'success', run: () => beginSourceReview(sourceDraft, true) }]),
|
|
6119
|
+
{ label: protocolOnly ? '只保存下载方式' : '只保存', description: '只保存来源配置;当前目录版本保持不变', status: protocolOnly ? 'success' : undefined, run: () => beginSourceReview(sourceDraft, false) },
|
|
6120
|
+
...(protocolOnly ? [{ label: '保存并启用…', description: '保存后验证并切换当前目录版本', run: () => beginSourceReview(sourceDraft, true) }] : []),
|
|
6121
|
+
{ label: '阅读完整来源变化', description: '分页查看每项修改前和修改后的完整值', run: () => {
|
|
6122
|
+
setBatchTargetOffset(0);
|
|
6123
|
+
go({ ...route, view: 'changes' });
|
|
6124
|
+
} },
|
|
6125
|
+
{ label: '返回修改', run: back },
|
|
6126
|
+
];
|
|
6127
|
+
const sourceSummaryLimit = 1;
|
|
6128
|
+
const visibleChanges = changes.slice(0, sourceSummaryLimit);
|
|
6129
|
+
const sourceSaveActionViewport = actionViewport(actions, policy.mode === 'compact', focus, scrollOffset, pageActionBudget(3 + visibleChanges.length * 2));
|
|
6130
|
+
const changeSectionTitle = visibleChanges.length < changes.length
|
|
6131
|
+
? `来源变化 · 显示 ${visibleChanges.length}/${changes.length}(另 ${changes.length - visibleChanges.length} 项)`
|
|
6132
|
+
: '来源变化';
|
|
6133
|
+
content = _jsxs(Box, { flexDirection: "column", children: [_jsx(SectionCard, { title: changeSectionTitle, compact: policy.mode === 'compact', children: visibleChanges.map((change) => _jsx(ReviewChangeRow, { title: `~ ${change.title}`, value: `${change.before ?? '未设置'} → ${change.after}`, compact: true }, change.title)) }), _jsx(SemanticRows, { actions: actions, focus: focus, kind: "action", compact: policy.mode === 'compact', offset: sourceSaveActionViewport.offset, limit: sourceSaveActionViewport.limit })] });
|
|
6134
|
+
}
|
|
6287
6135
|
}
|
|
6288
6136
|
else if (route.name === 'scriptTimeout' && pendingReviewIntent) {
|
|
6289
6137
|
breadcrumb = '高级选项 / 安装前检查脚本';
|
|
6290
6138
|
context = '毫秒';
|
|
6291
6139
|
title = '设置脚本超时';
|
|
6292
6140
|
description = `输入 ${SCRIPT_TIMEOUT_MIN_MS}–${SCRIPT_TIMEOUT_MAX_MS} 毫秒。默认 ${SCRIPT_TIMEOUT_DEFAULT_MS} 毫秒。`;
|
|
6293
|
-
help = '输入 · Enter
|
|
6294
|
-
content = _jsx(Box, { flexDirection: "column", children: _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: scriptTimeoutInput, columns: Math.max(8, size.columns - 8) }), description: scriptTimeoutError ?? '
|
|
6141
|
+
help = '输入 · Enter 应用并重新显示操作汇总 · Ctrl-U 清空 · Esc 取消';
|
|
6142
|
+
content = _jsx(Box, { flexDirection: "column", children: _jsx(InputCard, { focused: true, title: _jsx(InputDisplay, { value: scriptTimeoutInput, columns: Math.max(8, size.columns - 8) }), description: scriptTimeoutError ?? '此值只用于本次操作汇总。', status: scriptTimeoutError ? 'error' : undefined }) });
|
|
6295
6143
|
}
|
|
6296
6144
|
else if (route.name === 'sourceRemoveBlocked') {
|
|
6297
6145
|
breadcrumb = `插件来源 / ${route.sourceId} / 移除`;
|
|
@@ -6612,6 +6460,17 @@ export function ConsoleAppV4(props) {
|
|
|
6612
6460
|
? 'Esc 取消 · Ctrl-C 完成后退出'
|
|
6613
6461
|
: '↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6614
6462
|
actions = preparation.state === 'failed' ? [
|
|
6463
|
+
...[...new Map((preparation.operationRecordId
|
|
6464
|
+
? props.controller.getOperationDiagnostic(preparation.operationRecordId)?.diagnostics ?? []
|
|
6465
|
+
: []).flatMap((diagnostic) => diagnostic.stage === 'dependencyPlan'
|
|
6466
|
+
&& diagnostic.target?.pluginId
|
|
6467
|
+
&& props.controller.getPluginOverview(diagnostic.target.pluginId)
|
|
6468
|
+
? [[`${diagnostic.target.pluginId}:${diagnostic.target.platform}`, diagnostic.target]]
|
|
6469
|
+
: [])).values()].map((target) => ({
|
|
6470
|
+
label: `处理 ${props.controller.getPluginOverview(target.pluginId).displayName}`,
|
|
6471
|
+
description: '查看这个依赖的问题和可用的恢复操作',
|
|
6472
|
+
run: () => go({ name: 'platform', pluginId: target.pluginId, platform: target.platform }),
|
|
6473
|
+
})),
|
|
6615
6474
|
{ label: '重试', description: '重新读取和验证当前状态', run: () => {
|
|
6616
6475
|
props.controller.retryReviewPreparation();
|
|
6617
6476
|
setFocus(0);
|
|
@@ -6632,7 +6491,6 @@ export function ConsoleAppV4(props) {
|
|
|
6632
6491
|
: review.pluginAction === 'install' ? snapshot.installPlacementDraft?.pluginId : undefined;
|
|
6633
6492
|
const batchReview = review.operationKind === 'pluginWriteBatch';
|
|
6634
6493
|
const taskReview = review.operationKind === 'pluginWriteTask';
|
|
6635
|
-
const catalogManagementReview = review.operationKind === 'catalogManagement';
|
|
6636
6494
|
breadcrumb = `${review.subject.name} / ${review.title}`;
|
|
6637
6495
|
title = `${snapshot.result?.state === 'stale' ? '状态已变化 · ' : ''}${review.operationKind === 'portableInstall' || taskReview
|
|
6638
6496
|
? review.title : `确认${review.title}`} ${review.subject.name}`;
|
|
@@ -6640,7 +6498,7 @@ export function ConsoleAppV4(props) {
|
|
|
6640
6498
|
? '当前状态已变化。请检查新的变化后再次确认。'
|
|
6641
6499
|
: review.description;
|
|
6642
6500
|
if (taskReview) {
|
|
6643
|
-
context = '
|
|
6501
|
+
context = '本次选择 · 用户任务';
|
|
6644
6502
|
help = 'PgUp/PgDn 查看全部影响 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6645
6503
|
}
|
|
6646
6504
|
else if (batchReview) {
|
|
@@ -6677,7 +6535,7 @@ export function ConsoleAppV4(props) {
|
|
|
6677
6535
|
&& batchDraft?.frozenPluginIds ? [{
|
|
6678
6536
|
label: `调整选择(${new Set(pendingReviewIntent.targets
|
|
6679
6537
|
.map((target) => target.pluginId)).size})`,
|
|
6680
|
-
description: '
|
|
6538
|
+
description: '只可删减或恢复本次推荐插件;调整后重新读取状态并显示操作汇总',
|
|
6681
6539
|
run: () => {
|
|
6682
6540
|
if (!props.controller.returnToPluginWriteTaskBatchSelection(batchDraft.flowId)) {
|
|
6683
6541
|
setActionError('推荐选择已失效。请返回我的插件重新开始。');
|
|
@@ -6733,7 +6591,7 @@ export function ConsoleAppV4(props) {
|
|
|
6733
6591
|
...(installReviewPluginId
|
|
6734
6592
|
&& (snapshot.installPlacementDraft?.targets.length ?? 0) > 0 ? [{
|
|
6735
6593
|
label: '查看/调整依赖位置',
|
|
6736
|
-
description: '
|
|
6594
|
+
description: '当前已自动安排依赖位置;调整后会重新显示操作汇总',
|
|
6737
6595
|
run: () => {
|
|
6738
6596
|
props.controller.push({
|
|
6739
6597
|
name: 'dependencyPlacement',
|
|
@@ -6743,17 +6601,7 @@ export function ConsoleAppV4(props) {
|
|
|
6743
6601
|
setScrollOffset(0);
|
|
6744
6602
|
},
|
|
6745
6603
|
}] : []),
|
|
6746
|
-
...((pendingReviewIntent
|
|
6747
|
-
&& (pendingReviewIntent.action === 'install'
|
|
6748
|
-
|| pendingReviewIntent.action === 'refreshAndSync'
|
|
6749
|
-
|| pendingReviewIntent.action === 'reinstall'
|
|
6750
|
-
|| pendingReviewIntent.action === 'sync')
|
|
6751
|
-
|| pendingReviewIntent?.kind === 'pluginWriteBatch'
|
|
6752
|
-
&& (pendingReviewIntent.action === 'install'
|
|
6753
|
-
|| pendingReviewIntent.action === 'sync'
|
|
6754
|
-
|| pendingReviewIntent.action === 'reinstall')
|
|
6755
|
-
|| pendingReviewIntent?.kind === 'pluginWriteTask'
|
|
6756
|
-
|| pendingReviewIntent?.kind === 'configSave' && pendingReviewIntent.apply) ? [{
|
|
6604
|
+
...(supportsScriptTimeout(pendingReviewIntent) ? [{
|
|
6757
6605
|
label: '高级选项:脚本超时',
|
|
6758
6606
|
description: `${pendingReviewIntent.scriptTimeoutMs ?? SCRIPT_TIMEOUT_DEFAULT_MS} 毫秒`,
|
|
6759
6607
|
run: () => {
|
|
@@ -6900,11 +6748,10 @@ export function ConsoleAppV4(props) {
|
|
|
6900
6748
|
&& (review.changes.length > technicalChangeBudget || technicalDetails.length > technicalDetailLimit)) {
|
|
6901
6749
|
help = 'PgUp/PgDn 查看全部确认信息 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
6902
6750
|
}
|
|
6903
|
-
content = _jsx(Box, { flexDirection: "column", children: _jsxs(ReviewCard, { title: review.subject.name, meta: `${review.subject.sourceLabel ?? ''} ${review.subject.version ?? ''}`, description: showEquivalentCommand ? review.description : undefined, children: [showEquivalentCommand ? _jsxs(Text, { children: ["\u7B49\u4EF7\u547D\u4EE4\uFF1A", review.equivalentCommand] }) : null, showTechnical && review.catalogBinding ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `Catalog:${review.catalogBinding.sourceId} ${review.catalogBinding.catalogVersion} · 当前使用`, meta: `generation ${review.catalogBinding.generationDigestShort}`, status: "success", compact: true }), _jsx(StaticRow, { title: "\u64CD\u4F5C\u671F\u95F4\u4E0D\u68C0\u67E5\u8FDC\u7AEF Catalog", status: "success", compact: true })] }) : null, installDependencyPluginIds.size > 0 ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `需要 ${installDependencyPluginIds.size} 个额外插件;${reusedDependencyPluginIds.size} 个复用、${newDependencyCount} 个新增`, status: "info", compact: true }), _jsx(StaticRow, { title: widenedDependencyCount > 0 ? `${widenedDependencyCount} 个依赖会扩大到所有项目` : '没有依赖会扩大到所有项目', status: widenedDependencyCount > 0 ? 'warning' : 'success', compact: true })] }) : null, review.requiresConfirmation ? _jsx(StaticRow, { title:
|
|
6751
|
+
content = _jsx(Box, { flexDirection: "column", children: _jsxs(ReviewCard, { title: review.subject.name, meta: `${review.subject.sourceLabel ?? ''} ${review.subject.version ?? ''}`, description: showEquivalentCommand ? review.description : undefined, children: [showEquivalentCommand ? _jsxs(Text, { children: ["\u7B49\u4EF7\u547D\u4EE4\uFF1A", review.equivalentCommand] }) : null, showTechnical && review.catalogBinding ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `Catalog:${review.catalogBinding.sourceId} ${review.catalogBinding.catalogVersion} · 当前使用`, meta: `generation ${review.catalogBinding.generationDigestShort}`, status: "success", compact: true }), _jsx(StaticRow, { title: "\u64CD\u4F5C\u671F\u95F4\u4E0D\u68C0\u67E5\u8FDC\u7AEF Catalog", status: "success", compact: true })] }) : null, installDependencyPluginIds.size > 0 ? _jsxs(_Fragment, { children: [_jsx(StaticRow, { title: `需要 ${installDependencyPluginIds.size} 个额外插件;${reusedDependencyPluginIds.size} 个复用、${newDependencyCount} 个新增`, status: "info", compact: true }), _jsx(StaticRow, { title: widenedDependencyCount > 0 ? `${widenedDependencyCount} 个依赖会扩大到所有项目` : '没有依赖会扩大到所有项目', status: widenedDependencyCount > 0 ? 'warning' : 'success', compact: true })] }) : null, review.requiresConfirmation ? _jsx(StaticRow, { title: "! \u9700\u8981\u786E\u8BA4\u4F1A\u5F71\u54CD\u5176\u4ED6\u9879\u76EE\u7684\u5185\u5BB9", meta: review.sharedImpact.pluginIds.length > 0 ? `${review.sharedImpact.pluginIds.length} 个插件` : undefined, description: review.sharedImpact.warning, status: "warning", compact: true }) : null, showTechnical ? technicalChanges : changeGroups, _jsx(SemanticRows, { actions: actions, focus: operationConfirmation ? -1 : focus, kind: "action", compact: true }), compressedReview || showTechnical ? null : _jsx(StaticRow, { title: "\u6280\u672F\u8BE6\u60C5\uFF08d\uFF09", status: "muted" }), showTechnical ? _jsx(TechnicalDetails, { children: visibleTechnicalDetails.map((detail, index) => _jsx(StaticRow, { title: detail, meta: index === visibleTechnicalDetails.length - 1 && hiddenTechnicalDetails > 0 ? `另有 ${hiddenTechnicalDetails} 项` : undefined, compact: true }, detail)) }) : null] }) });
|
|
6904
6752
|
}
|
|
6905
6753
|
else if (route.name === 'progress') {
|
|
6906
6754
|
const taskOperation = snapshot.activeReview?.operationKind === 'pluginWriteTask';
|
|
6907
|
-
const catalogManagementOperation = snapshot.activeReview?.operationKind === 'catalogManagement';
|
|
6908
6755
|
const portableOperation = snapshot.activeReview?.operationKind === 'portableInstall';
|
|
6909
6756
|
const configOperation = snapshot.activeReview?.operationKind === 'configSave'
|
|
6910
6757
|
|| snapshot.activeReview?.operationKind === 'configReset';
|
|
@@ -6912,7 +6759,7 @@ export function ConsoleAppV4(props) {
|
|
|
6912
6759
|
|| snapshot.activeReview?.operationKind === 'catalogGeneration'
|
|
6913
6760
|
|| snapshot.activeReview?.operationKind === 'catalogSourcesRecovery';
|
|
6914
6761
|
const issueOperation = snapshot.activeReview?.originIssue;
|
|
6915
|
-
breadcrumb =
|
|
6762
|
+
breadcrumb = taskOperation ? '插件任务 / 进度' : portableOperation ? '通用 Skills / 进度' : issueOperation ? '需要处理 / 进度' : sourceOperation ? '插件来源 / 保存' : configOperation ? '设置 / 进度' : '插件操作 / 进度';
|
|
6916
6763
|
const configApply = snapshot.activeReview?.operationKind === 'configSave'
|
|
6917
6764
|
&& snapshot.activeReview.changes.some((change) => change.group === 'configImpact' && change.kind === 'change');
|
|
6918
6765
|
const progressAction = snapshot.activeReview?.taskGoal === 'restore' ? '恢复'
|
|
@@ -6926,21 +6773,18 @@ export function ConsoleAppV4(props) {
|
|
|
6926
6773
|
: snapshot.activeReview?.pluginAction === 'sync' ? '同步' : '处理';
|
|
6927
6774
|
const catalogGenerationOperation = snapshot.activeReview?.operationKind === 'catalogGeneration';
|
|
6928
6775
|
const catalogSourcesRecovery = snapshot.activeReview?.operationKind === 'catalogSourcesRecovery';
|
|
6929
|
-
title =
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
: sourceOperation ? '只原子保存来源配置,不访问网络。'
|
|
6942
|
-
: configOperation ? configApply ? '先保存所选层,再重新应用当前可见安装位置。' : '只保存所选设置层。'
|
|
6943
|
-
: '请勿关闭当前终端。';
|
|
6776
|
+
title = taskOperation ? `正在${progressAction}插件` : portableOperation ? '正在安装通用 Skills' : issueOperation ? `正在${progressAction}插件`
|
|
6777
|
+
: catalogGenerationOperation ? '正在验证并启用目录版本'
|
|
6778
|
+
: catalogSourcesRecovery ? '正在恢复插件来源配置'
|
|
6779
|
+
: sourceOperation ? '正在保存来源配置'
|
|
6780
|
+
: configOperation ? configApply ? '正在保存并应用设置' : '正在保存设置'
|
|
6781
|
+
: `正在${progressAction}插件`;
|
|
6782
|
+
description = issueOperation ? '完成后会重新读取状态并检查问题。'
|
|
6783
|
+
: catalogGenerationOperation ? '正在验证并应用已确认的目录版本操作。'
|
|
6784
|
+
: catalogSourcesRecovery ? '正在备份损坏配置并恢复官方默认来源。'
|
|
6785
|
+
: sourceOperation ? '只原子保存来源配置,不访问网络。'
|
|
6786
|
+
: configOperation ? configApply ? '先保存所选层,再重新应用当前可见安装位置。' : '只保存所选设置层。'
|
|
6787
|
+
: '请勿关闭当前终端。';
|
|
6944
6788
|
const batchProgress = snapshot.activeReview?.operationKind === 'pluginWriteBatch' || taskOperation;
|
|
6945
6789
|
const progress = snapshot.progress;
|
|
6946
6790
|
const elapsedSeconds = Math.max(0, Math.floor(((progress.elapsedMs
|
|
@@ -7043,7 +6887,7 @@ export function ConsoleAppV4(props) {
|
|
|
7043
6887
|
return step === 2 ? '正在安装' : step === 3 ? '正在验证' : step === 1 ? '正在生成' : '正在检查';
|
|
7044
6888
|
};
|
|
7045
6889
|
const compactPortableProgress = policy.mode === 'compact' && showTechnical;
|
|
7046
|
-
content =
|
|
6890
|
+
content = portableOperation ? _jsxs(StatusCard, { status: failedProgress ? 'error' : 'info', title: "Skills CLI", children: [_jsx(ProgressRow, { title: "\u68C0\u67E5\u63D2\u4EF6\u548C\u4F9D\u8D56", description: `${snapshot.activeReview?.subject.name ?? '当前插件'} · ${portableDraft?.dependencySummary?.directCount ?? 0} 个直接依赖`, meta: portableProgressMeta(0), state: portableProgressState(0), compact: compactPortableProgress }), _jsx(ProgressRow, { title: "\u751F\u6210\u5DF2\u9009\u5019\u9009 Skills", description: `${portableProviderCount} 个来源或依赖插件提供 ${portableSelectedCount} 个 Skills`, meta: portableProgressMeta(1), state: portableProgressState(1), compact: compactPortableProgress }), _jsx(ProgressRow, { title: `安装已选择的 ${portableSelectedCount} 个 Skills`, description: `Agent:${portableDraft?.agentMode === 'explicit' ? portableDraft.requestedAgents.join('、') : 'Skills CLI 默认选择'}`, meta: portableProgressMeta(2), state: portableProgressState(2), compact: compactPortableProgress }), _jsx(ProgressRow, { title: "\u9A8C\u8BC1\u7ED3\u679C", description: "\u9010\u9879\u786E\u8BA4\u6240\u9009 Skill \u7684\u5B89\u88C5\u76EE\u6807", meta: portableProgressMeta(3), state: portableProgressState(3), compact: compactPortableProgress }), showTechnical ? _jsxs(TechnicalDetails, { children: [technicalMessages.map((message, index) => _jsx(StaticRow, { title: message, compact: true }, `${index}:${message}`)), hiddenTechnicalMessages > 0 ? _jsx(StaticRow, { title: `另有 ${hiddenTechnicalMessages} 条技术消息`, status: "muted", compact: true }) : null] }) : null] }) : _jsxs(StatusCard, { status: "info", children: [dependencyProgress ? _jsxs(_Fragment, { children: [_jsx(ProgressRow, { title: "\u68C0\u67E5\u4F9D\u8D56\u5173\u7CFB", state: relationStep }), _jsx(ProgressRow, { title: "\u751F\u6210\u6267\u884C\u8BA1\u5212", state: planStep }), _jsx(ProgressRow, { title: `${progressAction}所选插件和所需插件`, description: progress.current?.target ? `当前:${progress.current.target}` : undefined, meta: `${elapsedSeconds}s`, state: closureStep, compact: policy.mode === 'compact' }), _jsx(ProgressRow, { title: "\u9A8C\u8BC1\u5B8C\u6574\u7ED3\u679C", state: verificationStep })] }) : _jsxs(_Fragment, { children: [_jsx(ProgressRow, { title: sourceOperation ? '检查来源操作输入' : configOperation ? '验证设置值' : '检查兼容性', state: !currentPhase ? 'pending' : preflightActive ? 'active' : 'complete' }), _jsx(ProgressRow, { title: progress.current?.phase || (sourceOperation ? '保存来源配置' : configOperation ? '保存设置层并重新应用' : '连接到所选目标平台'), description: progress.current?.target ? `当前:${progress.current.target}` : undefined, meta: `${elapsedSeconds}s`, state: failedProgress ? 'error' : executionActive ? 'active' : validationActive ? 'complete' : 'pending', compact: policy.mode === 'compact' }), _jsx(ProgressRow, { title: "\u9A8C\u8BC1\u7ED3\u679C", state: failedProgress ? 'error' : validationActive ? 'active' : 'pending' })] }), dependencyProgress ? _jsxs(SectionCard, { title: "\u6267\u884C\u76EE\u6807", meta: `${snapshot.progressTargets.length} 个目标`, children: [progressTargetOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${progressTargetOffset} 个目标`, status: "muted", compact: true }) : null, visibleProgressTargets.map((entry) => {
|
|
7047
6891
|
const state = progressLabel(entry);
|
|
7048
6892
|
const relation = entry.relation === 'requested' ? '你选择的插件' : entry.relation === 'direct' ? '直接依赖' : '间接依赖';
|
|
7049
6893
|
const title = props.controller.getPluginOverview(entry.pluginId)?.displayName
|
|
@@ -7063,9 +6907,6 @@ export function ConsoleAppV4(props) {
|
|
|
7063
6907
|
: result.state === 'blocked' ? result.summary : undefined;
|
|
7064
6908
|
const action = resultSummary?.action;
|
|
7065
6909
|
const operationKind = 'operationKind' in result ? result.operationKind : undefined;
|
|
7066
|
-
const catalogManagementOperation = operationKind === 'catalogManagement';
|
|
7067
|
-
const catalogManagementResult = catalogManagementOperation
|
|
7068
|
-
? resultSummary?.catalogManagement : undefined;
|
|
7069
6910
|
const taskOperation = operationKind === 'pluginWriteTask';
|
|
7070
6911
|
const taskSummary = resultSummary?.task;
|
|
7071
6912
|
const taskBlockedCount = taskSummary?.blockedTargets.length ?? 0;
|
|
@@ -7122,96 +6963,87 @@ export function ConsoleAppV4(props) {
|
|
|
7122
6963
|
cleanup: '✓ 插件清理完成',
|
|
7123
6964
|
sync: '✓ 插件同步完成',
|
|
7124
6965
|
}[action ?? 'install'];
|
|
7125
|
-
title =
|
|
7126
|
-
? blocked ?
|
|
7127
|
-
: partial ?
|
|
7128
|
-
:
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
:
|
|
7159
|
-
?
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
: batchOperation
|
|
6966
|
+
title = taskOperation
|
|
6967
|
+
? blocked ? `× 插件${pluginWriteTaskLabel(taskSummary?.goal ?? 'restore')}没有完成`
|
|
6968
|
+
: partial ? `! 插件${pluginWriteTaskLabel(taskSummary?.goal ?? 'restore')}只完成了一部分`
|
|
6969
|
+
: `✓ 插件${pluginWriteTaskLabel(taskSummary?.goal ?? 'restore')}完成`
|
|
6970
|
+
: batchOperation
|
|
6971
|
+
? blocked ? '× 批量操作没有完成'
|
|
6972
|
+
: partial ? '! 批量操作只完成了一部分' : `✓ 批量${batchActionLabel(action)}完成`
|
|
6973
|
+
: portableOperation
|
|
6974
|
+
? blocked ? '× 通用 Skills 安装被阻止'
|
|
6975
|
+
: partial ? '! 通用 Skills 结果未完全完成' : '✓ 通用 Skills 已安装'
|
|
6976
|
+
: blocked && result.writeMayHaveCompleted
|
|
6977
|
+
? '× 写入结果未确认'
|
|
6978
|
+
: issueOperation
|
|
6979
|
+
? blocked || partial ? '× 问题仍未解决' : '✓ 问题已处理'
|
|
6980
|
+
: sourceOperation
|
|
6981
|
+
? blocked ? '× 来源操作未完成'
|
|
6982
|
+
: operationKind === 'catalogSourcesRecovery' ? '✓ Catalog 来源配置已恢复'
|
|
6983
|
+
: resultSummary?.catalogAction === 'update'
|
|
6984
|
+
? resultSummary.catalogGeneration?.activeChanged
|
|
6985
|
+
&& resultSummary.catalogGeneration.outcome === 'activated'
|
|
6986
|
+
? '✓ Catalog 已更新' : '✓ Catalog 无需更新'
|
|
6987
|
+
: resultSummary?.catalogAction === 'repair' ? '✓ Catalog 已修复'
|
|
6988
|
+
: resultSummary?.catalogAction === 'replaceDamaged' ? '✓ 损坏的 Catalog 已替换'
|
|
6989
|
+
: resultSummary?.catalogAction === 'recoverState' ? '✓ Catalog 状态已恢复'
|
|
6990
|
+
: operationKind === 'catalogGeneration' ? '✓ Catalog 已启用'
|
|
6991
|
+
: '✓ 来源配置已保存'
|
|
6992
|
+
: configOperation
|
|
6993
|
+
? blocked
|
|
6994
|
+
? '× 设置未确认保存'
|
|
6995
|
+
: partial ? resultSummary?.configApplySkippedReason === 'invalidConfig'
|
|
6996
|
+
? '! 设置已保存,但未应用'
|
|
6997
|
+
: '! 设置已保存,但部分应用失败'
|
|
6998
|
+
: resultSummary?.configApplied ? '✓ 设置已保存并应用' : '✓ 设置已保存'
|
|
6999
|
+
: partial ? '! 插件操作只完成了一部分'
|
|
7000
|
+
: blocked ? result.code === 'operationFailed' ? '× 插件操作没有完成' : '× 插件操作未完成'
|
|
7001
|
+
: completedTitle;
|
|
7002
|
+
description = taskOperation
|
|
7003
|
+
? blocked ? '任务被安全阻止。已完成和未完成目标按实际结果保留。'
|
|
7004
|
+
: partial ? `${taskSummary?.retryTargets?.length ?? 0} 个失败目标可重试 · ${taskBlockedCount} 个目标需要决定。`
|
|
7005
|
+
: `${taskSummary?.rootResults.length ?? 0} 个所选插件已处理;下方显示使用位置。`
|
|
7006
|
+
: batchOperation
|
|
7007
|
+
? blocked
|
|
7008
|
+
? '批量写入被阻止。已完成和未完成目标按实际结果保留。'
|
|
7009
|
+
: partial
|
|
7010
|
+
? (resultSummary?.batch?.retryTargets?.length ?? 0) > 0
|
|
7011
|
+
? `${resultSummary?.batch?.failedRequestedPluginIds.length ?? 0} 个所选插件失败,涉及 ${resultSummary?.batch?.retryTargets?.length ?? 0} 个位置。成功目标不会重放。`
|
|
7012
|
+
: '失败目标无法精确定位。请查看本次记录后重新操作。'
|
|
7013
|
+
: `${resultSummary?.batch?.requestedPluginIds.length ?? 0} 个所选插件已处理;下方显示使用位置和所需插件。`
|
|
7014
|
+
: portableOperation
|
|
7175
7015
|
? blocked
|
|
7176
|
-
? '
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
?
|
|
7180
|
-
:
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
?
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
:
|
|
7016
|
+
? result.code === 'operationReviewExpired' || result.code === 'reviewTicketExpired'
|
|
7017
|
+
? '确认信息已过期,写入未开始。请返回修改并重新确认。'
|
|
7018
|
+
: result.code === 'operationReviewStale'
|
|
7019
|
+
? '安装证据已变化,写入被阻止。请返回修改并重新确认。'
|
|
7020
|
+
: result.writeMayHaveCompleted
|
|
7021
|
+
? '写入结果无法确认。请检查外部 Skills 状态后重试。'
|
|
7022
|
+
: '安装在写入前被阻止。请返回修改后重试。'
|
|
7023
|
+
: portableInstallFailed ? 'Skills CLI 安装失败,可能已有部分目标写入。可以修改 Agent 或使用原选择重试。' : partial ? '无法确认全部已选择 Skills。' : '所选 Skills 已通过安装验证。'
|
|
7024
|
+
: blocked && result.writeMayHaveCompleted
|
|
7025
|
+
? result.message
|
|
7026
|
+
: issueOperation
|
|
7027
|
+
? blocked
|
|
7028
|
+
? result.code === 'issueVerificationFailed'
|
|
7029
|
+
? '写入可能已完成,但当前无法确认。请重新检查状态。'
|
|
7030
|
+
: result.code === 'issueStillPresent'
|
|
7031
|
+
? '写入已完成,但重新检查后原问题仍然存在。'
|
|
7032
|
+
: '操作被安全阻止。可返回问题详情后重试。'
|
|
7033
|
+
: '状态已重新加载;原问题已确认消失。'
|
|
7034
|
+
: sourceOperation
|
|
7195
7035
|
? blocked
|
|
7196
|
-
? result.
|
|
7197
|
-
? '
|
|
7198
|
-
:
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
: partial ? resultSummary?.message ?? '来源配置已保存,但 Catalog 尚未启用。可立即重试。'
|
|
7208
|
-
: resultSummary?.message ?? '来源配置已保存。'
|
|
7209
|
-
: blocked ? result.message
|
|
7210
|
-
: configOperation
|
|
7211
|
-
? partial
|
|
7212
|
-
? resultSummary?.message ?? '设置层已经保存;平台应用失败不会回滚设置。'
|
|
7213
|
-
: '设置层已经更新。'
|
|
7214
|
-
: '状态已刷新。';
|
|
7036
|
+
? result.writeMayHaveCompleted
|
|
7037
|
+
? '来源配置可能已保存。请重新检查来源列表。'
|
|
7038
|
+
: '来源操作未执行。草稿已保留,可返回修改。'
|
|
7039
|
+
: partial ? resultSummary?.message ?? '来源配置已保存,但 Catalog 尚未启用。可立即重试。'
|
|
7040
|
+
: resultSummary?.message ?? '来源配置已保存。'
|
|
7041
|
+
: blocked ? result.message
|
|
7042
|
+
: configOperation
|
|
7043
|
+
? partial
|
|
7044
|
+
? resultSummary?.message ?? '设置层已经保存;平台应用失败不会回滚设置。'
|
|
7045
|
+
: '设置层已经更新。'
|
|
7046
|
+
: '状态已刷新。';
|
|
7215
7047
|
const pluginId = resultSummary?.pluginId
|
|
7216
7048
|
?? ('pluginId' in result ? result.pluginId : undefined);
|
|
7217
7049
|
const configResultPluginId = pluginId ?? ('returnRoute' in result
|
|
@@ -7261,7 +7093,7 @@ export function ConsoleAppV4(props) {
|
|
|
7261
7093
|
const retryAction = failedPluginId && failedTarget && failedTargetState
|
|
7262
7094
|
? selectLifecycleRetryAction({
|
|
7263
7095
|
operationKind: operationKind === 'catalogSourcesRecovery' || operationKind === 'pluginWriteBatch'
|
|
7264
|
-
|| operationKind === 'pluginWriteTask'
|
|
7096
|
+
|| operationKind === 'pluginWriteTask'
|
|
7265
7097
|
? undefined : operationKind,
|
|
7266
7098
|
originalAction: action,
|
|
7267
7099
|
target: {
|
|
@@ -7282,221 +7114,185 @@ export function ConsoleAppV4(props) {
|
|
|
7282
7114
|
&& (candidate.platform ?? failedIssue.platform) === failedTarget?.platform
|
|
7283
7115
|
&& (candidate.scope ?? failedIssue.scope) === failedTarget?.scope)
|
|
7284
7116
|
: undefined;
|
|
7285
|
-
|
|
7286
|
-
&& catalogManagementResult.planDigest && catalogManagementResult.publication
|
|
7287
|
-
? catalogManagementResult : undefined;
|
|
7288
|
-
actions = catalogManagementOperation
|
|
7117
|
+
actions = taskOperation
|
|
7289
7118
|
? [
|
|
7290
|
-
...(
|
|
7291
|
-
label: '
|
|
7292
|
-
description: '
|
|
7119
|
+
...(nestedTaskReturn && taskReturnRoute ? [{
|
|
7120
|
+
label: '返回剩余恢复任务',
|
|
7121
|
+
description: '保留父任务已选择的位置;返回后重新读取当前状态',
|
|
7293
7122
|
status: 'success',
|
|
7294
|
-
run: () =>
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
}, { name: 'catalogPublish', step: 'overview' }),
|
|
7123
|
+
run: () => leaveResult(taskReturnRoute),
|
|
7124
|
+
}] : []),
|
|
7125
|
+
...((partial || blocked) && (taskSummary?.retryTargets?.length ?? 0) > 0 ? [{
|
|
7126
|
+
label: `继续处理剩余 ${taskSummary.retryTargets.length} 项…`,
|
|
7127
|
+
description: '重新检查失败的精确目标和必要依赖,并进入新的确认页',
|
|
7128
|
+
run: () => {
|
|
7129
|
+
props.controller.retryFailedPluginWriteTask();
|
|
7130
|
+
setFocus(0);
|
|
7131
|
+
setScrollOffset(0);
|
|
7132
|
+
},
|
|
7305
7133
|
}] : []),
|
|
7306
|
-
|
|
7307
|
-
:
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7134
|
+
...(taskBlockedCount > 0 && taskReturnRoute ? [{
|
|
7135
|
+
label: `返回任务处理 ${taskBlockedCount} 个需决定项`,
|
|
7136
|
+
description: '受阻目标没有加入失败重试;返回后可查看原因和可用的下一步',
|
|
7137
|
+
status: 'warning',
|
|
7138
|
+
run: () => leaveResult(taskReturnRoute),
|
|
7139
|
+
}] : []),
|
|
7140
|
+
...(!nestedTaskReturn ? [{ label: '完成,返回我的插件', run: () => {
|
|
7141
|
+
if (taskBatchOrigin?.owner === 'batch-write'
|
|
7142
|
+
&& taskBatchOrigin.flowId === batchDraft?.flowId) {
|
|
7143
|
+
setBatchDraft(undefined);
|
|
7144
|
+
setDirty(false);
|
|
7145
|
+
}
|
|
7146
|
+
leaveResult({ name: 'pluginList', mode: 'installed' });
|
|
7147
|
+
} }] : []),
|
|
7318
7148
|
{ label: '查看本次记录', run: () => result.operationRecordId
|
|
7319
7149
|
&& go({ name: 'operationDiagnostic', recordId: result.operationRecordId }) },
|
|
7320
7150
|
]
|
|
7321
|
-
:
|
|
7151
|
+
: batchOperation
|
|
7322
7152
|
? [
|
|
7323
|
-
...(
|
|
7324
|
-
label: '
|
|
7325
|
-
description: '
|
|
7326
|
-
status: 'success',
|
|
7327
|
-
run: () => leaveResult(taskReturnRoute),
|
|
7328
|
-
}] : []),
|
|
7329
|
-
...((partial || blocked) && (taskSummary?.retryTargets?.length ?? 0) > 0 ? [{
|
|
7330
|
-
label: `继续处理剩余 ${taskSummary.retryTargets.length} 项…`,
|
|
7331
|
-
description: '重新检查失败的精确目标和必要依赖,并进入新的确认页',
|
|
7153
|
+
...((partial || blocked) && (resultSummary?.batch?.retryTargets?.length ?? 0) > 0 ? [{
|
|
7154
|
+
label: '仅重试失败目标…',
|
|
7155
|
+
description: '重新读取失败根目标及其依赖,并进入新的确认页',
|
|
7332
7156
|
run: () => {
|
|
7333
|
-
props.controller.
|
|
7157
|
+
props.controller.retryFailedPluginWriteBatch();
|
|
7334
7158
|
setFocus(0);
|
|
7335
7159
|
setScrollOffset(0);
|
|
7336
7160
|
},
|
|
7337
7161
|
}] : []),
|
|
7338
|
-
|
|
7339
|
-
label: `返回任务处理 ${taskBlockedCount} 个需决定项`,
|
|
7340
|
-
description: '受阻目标没有加入失败重试;返回后可查看原因和可用的下一步',
|
|
7341
|
-
status: 'warning',
|
|
7342
|
-
run: () => leaveResult(taskReturnRoute),
|
|
7343
|
-
}] : []),
|
|
7344
|
-
...(!nestedTaskReturn ? [{ label: '完成,返回我的插件', run: () => {
|
|
7345
|
-
if (taskBatchOrigin?.owner === 'batch-write'
|
|
7346
|
-
&& taskBatchOrigin.flowId === batchDraft?.flowId) {
|
|
7347
|
-
setBatchDraft(undefined);
|
|
7348
|
-
setDirty(false);
|
|
7349
|
-
}
|
|
7350
|
-
leaveResult({ name: 'pluginList', mode: 'installed' });
|
|
7351
|
-
} }] : []),
|
|
7162
|
+
{ label: '返回我的插件', run: () => leaveResult() },
|
|
7352
7163
|
{ label: '查看本次记录', run: () => result.operationRecordId
|
|
7353
7164
|
&& go({ name: 'operationDiagnostic', recordId: result.operationRecordId }) },
|
|
7354
7165
|
]
|
|
7355
|
-
:
|
|
7356
|
-
? [
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
setScrollOffset(0);
|
|
7364
|
-
},
|
|
7365
|
-
}] : []),
|
|
7366
|
-
{ label: '返回我的插件', run: () => leaveResult() },
|
|
7367
|
-
{ label: '查看本次记录', run: () => result.operationRecordId
|
|
7368
|
-
&& go({ name: 'operationDiagnostic', recordId: result.operationRecordId }) },
|
|
7369
|
-
]
|
|
7370
|
-
: portableOperation
|
|
7371
|
-
? blocked || partial ? [
|
|
7372
|
-
{ label: blocked || partial ? '返回修改' : portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: async () => {
|
|
7373
|
-
if (!pluginId) {
|
|
7374
|
-
leaveResult();
|
|
7375
|
-
return;
|
|
7376
|
-
}
|
|
7377
|
-
if (!blocked && !partial) {
|
|
7378
|
-
props.controller.discardPortableDraft();
|
|
7379
|
-
leaveResult();
|
|
7380
|
-
return;
|
|
7381
|
-
}
|
|
7382
|
-
if (!await refreshPortableDraft(pluginId))
|
|
7383
|
-
return;
|
|
7384
|
-
if (portableInstallFailed && portableReceipt?.agentMode === 'explicit') {
|
|
7385
|
-
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableAgentInput', pluginId }, true);
|
|
7386
|
-
return;
|
|
7387
|
-
}
|
|
7388
|
-
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableSkillSelect', pluginId }, true);
|
|
7389
|
-
} },
|
|
7390
|
-
{ label: blocked || partial ? '重试' : '再安装其他 Skills…', run: async () => {
|
|
7391
|
-
if (!pluginId)
|
|
7392
|
-
return;
|
|
7393
|
-
if (blocked || partial) {
|
|
7394
|
-
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableSkillSelect', pluginId }, true);
|
|
7395
|
-
await beginPortableReview(pluginId, snapshot.portableDraft?.scope ?? 'project');
|
|
7396
|
-
return;
|
|
7397
|
-
}
|
|
7398
|
-
props.controller.resetPortableFlowToPreview(pluginId);
|
|
7399
|
-
await beginPortable(pluginId);
|
|
7400
|
-
} },
|
|
7401
|
-
{ label: portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: () => { if (pluginId)
|
|
7402
|
-
props.controller.resetPortableFlowToPreview(pluginId); } },
|
|
7403
|
-
] : [
|
|
7404
|
-
{ label: portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: () => {
|
|
7166
|
+
: portableOperation
|
|
7167
|
+
? blocked || partial ? [
|
|
7168
|
+
{ label: blocked || partial ? '返回修改' : portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: async () => {
|
|
7169
|
+
if (!pluginId) {
|
|
7170
|
+
leaveResult();
|
|
7171
|
+
return;
|
|
7172
|
+
}
|
|
7173
|
+
if (!blocked && !partial) {
|
|
7405
7174
|
props.controller.discardPortableDraft();
|
|
7406
7175
|
leaveResult();
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7176
|
+
return;
|
|
7177
|
+
}
|
|
7178
|
+
if (!await refreshPortableDraft(pluginId))
|
|
7179
|
+
return;
|
|
7180
|
+
if (portableInstallFailed && portableReceipt?.agentMode === 'explicit') {
|
|
7181
|
+
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableAgentInput', pluginId }, true);
|
|
7182
|
+
return;
|
|
7183
|
+
}
|
|
7184
|
+
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableSkillSelect', pluginId }, true);
|
|
7185
|
+
} },
|
|
7186
|
+
{ label: blocked || partial ? '重试' : '再安装其他 Skills…', run: async () => {
|
|
7187
|
+
if (!pluginId)
|
|
7188
|
+
return;
|
|
7189
|
+
if (blocked || partial) {
|
|
7190
|
+
props.controller.resetPortableFlowToPreview(pluginId, { name: 'portableSkillSelect', pluginId }, true);
|
|
7191
|
+
await beginPortableReview(pluginId, snapshot.portableDraft?.scope ?? 'project');
|
|
7192
|
+
return;
|
|
7193
|
+
}
|
|
7194
|
+
props.controller.resetPortableFlowToPreview(pluginId);
|
|
7195
|
+
await beginPortable(pluginId);
|
|
7196
|
+
} },
|
|
7197
|
+
{ label: portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: () => { if (pluginId)
|
|
7198
|
+
props.controller.resetPortableFlowToPreview(pluginId); } },
|
|
7199
|
+
] : [
|
|
7200
|
+
{ label: portableOriginIsDetail ? '返回插件详情' : '返回插件预览', run: () => {
|
|
7201
|
+
props.controller.discardPortableDraft();
|
|
7202
|
+
leaveResult();
|
|
7203
|
+
} },
|
|
7204
|
+
{ label: '再安装其他 Skills…', run: async () => {
|
|
7205
|
+
if (!pluginId)
|
|
7206
|
+
return;
|
|
7207
|
+
props.controller.resetPortableFlowToPreview(pluginId);
|
|
7208
|
+
await beginPortable(pluginId);
|
|
7209
|
+
} },
|
|
7210
|
+
]
|
|
7211
|
+
: issueOperation && !dependencyRecovery
|
|
7212
|
+
? blocked || partial
|
|
7213
|
+
? [
|
|
7214
|
+
{ label: '返回问题详情', run: () => blocked
|
|
7215
|
+
? leaveResult()
|
|
7216
|
+
: failedIssue
|
|
7217
|
+
? leaveResult({ name: 'issueDetail', issueId: failedIssue.issueId })
|
|
7218
|
+
: pluginId && failedTarget
|
|
7219
|
+
? leaveResult({ name: 'platform', pluginId, platform: failedTarget.platform })
|
|
7220
|
+
: leaveResult() },
|
|
7221
|
+
{ label: '重新检查问题', run: () => leaveResult({ name: 'issueList' }) },
|
|
7222
|
+
]
|
|
7223
|
+
: [
|
|
7224
|
+
{ label: '查看问题列表', run: () => leaveResult({ name: 'issueList' }) },
|
|
7225
|
+
{ label: '返回首页', run: () => requestSessionNavigation('home') },
|
|
7226
|
+
]
|
|
7227
|
+
: sourceOperation
|
|
7228
|
+
? [{
|
|
7229
|
+
label: !blocked && 'returnRoute' in result && result.returnRoute?.name === 'pluginWriteTask'
|
|
7230
|
+
? '重新准备插件更新' : blocked ? '返回修改' : partial ? '现在启用 / 重试' : '查看来源',
|
|
7231
|
+
run: () => blocked ? props.controller.resumeResultDraft() : leaveResult(),
|
|
7232
|
+
}, { label: '返回首页', run: () => requestSessionNavigation('home') }]
|
|
7233
|
+
: configOperation && partial
|
|
7417
7234
|
? [
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
:
|
|
7421
|
-
|
|
7422
|
-
:
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7235
|
+
...(configRetryAvailable ? [{
|
|
7236
|
+
label: '重试应用',
|
|
7237
|
+
description: '先重新显示操作汇总,并重新读取当前状态',
|
|
7238
|
+
run: () => beginReview({
|
|
7239
|
+
kind: 'configSave',
|
|
7240
|
+
pluginId: configResultPluginId,
|
|
7241
|
+
scope: resultSummary.configScope,
|
|
7242
|
+
apply: true,
|
|
7243
|
+
retryApply: true,
|
|
7244
|
+
}),
|
|
7245
|
+
}] : []),
|
|
7246
|
+
{ label: invalidConfigResult ? '返回设置' : '返回修改', description: '重新打开已保存的设置层', run: () => leaveResult() },
|
|
7247
|
+
{ label: '返回设置删除字段或重置设置层', description: '显式删除顶层字段或整个设置层', run: () => leaveResult() },
|
|
7248
|
+
{ label: '保留设置并退出', run: () => requestExit({ code: 1, reason: 'partial' }) },
|
|
7426
7249
|
]
|
|
7427
|
-
:
|
|
7428
|
-
{ label: '查看问题列表', run: () => leaveResult({ name: 'issueList' }) },
|
|
7429
|
-
{ label: '返回首页', run: () => requestSessionNavigation('home') },
|
|
7430
|
-
]
|
|
7431
|
-
: sourceOperation
|
|
7432
|
-
? [{
|
|
7433
|
-
label: !blocked && 'returnRoute' in result && result.returnRoute?.name === 'pluginWriteTask'
|
|
7434
|
-
? '重新准备插件更新' : blocked ? '返回修改' : partial ? '现在启用 / 重试' : '查看来源',
|
|
7435
|
-
run: () => blocked ? props.controller.resumeResultDraft() : leaveResult(),
|
|
7436
|
-
}, { label: '返回首页', run: () => requestSessionNavigation('home') }]
|
|
7437
|
-
: configOperation && partial
|
|
7250
|
+
: configOperation && blocked
|
|
7438
7251
|
? [
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
description: '先重新进入 Review,并重新采集当前证据',
|
|
7442
|
-
run: () => beginReview({
|
|
7443
|
-
kind: 'configSave',
|
|
7444
|
-
pluginId: configResultPluginId,
|
|
7445
|
-
scope: resultSummary.configScope,
|
|
7446
|
-
apply: true,
|
|
7447
|
-
retryApply: true,
|
|
7448
|
-
}),
|
|
7449
|
-
}] : []),
|
|
7450
|
-
{ label: invalidConfigResult ? '返回设置' : '返回修改', description: '重新打开已保存的设置层', run: () => leaveResult() },
|
|
7451
|
-
{ label: '返回设置删除字段或重置设置层', description: '显式删除顶层字段或整个设置层', run: () => leaveResult() },
|
|
7452
|
-
{ label: '保留设置并退出', run: () => requestExit({ code: 1, reason: 'partial' }) },
|
|
7252
|
+
{ label: '返回设置', run: () => props.controller.resumeResultDraft() },
|
|
7253
|
+
{ label: '返回首页', run: () => requestSessionNavigation('home') },
|
|
7453
7254
|
]
|
|
7454
|
-
:
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
if (
|
|
7465
|
-
leaveResult();
|
|
7466
|
-
|
|
7255
|
+
: [{ label: partial || blockedDependencyFailure ? '查看失败项' : successfulConfigOperation && configOrigin
|
|
7256
|
+
? configOrigin.name === 'pluginPreview' ? '返回插件预览'
|
|
7257
|
+
: configOrigin.name === 'pluginWriteTask' ? '返回恢复任务' : '返回插件详情'
|
|
7258
|
+
: configOperation ? '查看插件'
|
|
7259
|
+
: action === 'uninstall' || action === 'cleanup' ? '返回插件详情' : '查看插件', run: () => {
|
|
7260
|
+
if (successfulConfigOperation && configOrigin) {
|
|
7261
|
+
leaveResult();
|
|
7262
|
+
return;
|
|
7263
|
+
}
|
|
7264
|
+
if ((partial || blockedDependencyFailure) && failedPluginId && failedTarget) {
|
|
7265
|
+
if (failedIssue)
|
|
7266
|
+
leaveResult({ name: 'issueDetail', issueId: failedIssue.issueId });
|
|
7267
|
+
else if (failedPluginPlatforms?.includes(failedTarget.platform)) {
|
|
7268
|
+
leaveResult({ name: 'platform', pluginId: failedPluginId, platform: failedTarget.platform });
|
|
7467
7269
|
}
|
|
7468
|
-
if ((
|
|
7469
|
-
|
|
7470
|
-
leaveResult({ name: 'issueDetail', issueId: failedIssue.issueId });
|
|
7471
|
-
else if (failedPluginPlatforms?.includes(failedTarget.platform)) {
|
|
7472
|
-
leaveResult({ name: 'platform', pluginId: failedPluginId, platform: failedTarget.platform });
|
|
7473
|
-
}
|
|
7474
|
-
else if (snapshot.viewModel?.plugins.some((entry) => entry.pluginId === failedPluginId)) {
|
|
7475
|
-
leaveResult({ name: 'pluginDetail', pluginId: failedPluginId });
|
|
7476
|
-
}
|
|
7477
|
-
else
|
|
7478
|
-
leaveResult({ name: 'pluginList', mode: 'installed' });
|
|
7479
|
-
}
|
|
7480
|
-
else if (pluginId && snapshot.viewModel?.plugins.some((entry) => entry.pluginId === pluginId)) {
|
|
7481
|
-
leaveResult({ name: 'pluginDetail', pluginId });
|
|
7270
|
+
else if (snapshot.viewModel?.plugins.some((entry) => entry.pluginId === failedPluginId)) {
|
|
7271
|
+
leaveResult({ name: 'pluginDetail', pluginId: failedPluginId });
|
|
7482
7272
|
}
|
|
7483
7273
|
else
|
|
7484
7274
|
leaveResult({ name: 'pluginList', mode: 'installed' });
|
|
7485
|
-
}
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7275
|
+
}
|
|
7276
|
+
else if (pluginId && snapshot.viewModel?.plugins.some((entry) => entry.pluginId === pluginId)) {
|
|
7277
|
+
leaveResult({ name: 'pluginDetail', pluginId });
|
|
7278
|
+
}
|
|
7279
|
+
else
|
|
7280
|
+
leaveResult({ name: 'pluginList', mode: 'installed' });
|
|
7281
|
+
} }, ...((partial || blockedDependencyFailure) && failedPluginId && failedTarget && retryAction ? [{
|
|
7282
|
+
label: '重试失败部分…',
|
|
7283
|
+
run: () => {
|
|
7284
|
+
const issueIntent = failedIssue && retryIssueAction
|
|
7285
|
+
? issueWriteIntent(failedIssue, retryIssueAction)
|
|
7286
|
+
: undefined;
|
|
7287
|
+
return beginReview(issueIntent ?? {
|
|
7288
|
+
kind: 'pluginWrite',
|
|
7289
|
+
action: retryAction,
|
|
7290
|
+
pluginId: failedPluginId,
|
|
7291
|
+
platform: failedTarget.platform,
|
|
7292
|
+
scope: failedTarget.scope,
|
|
7293
|
+
});
|
|
7294
|
+
},
|
|
7295
|
+
}] : []), { label: '返回首页', run: () => requestSessionNavigation('home') }];
|
|
7500
7296
|
const visibleMessages = resultSummary?.messages?.slice(policy.mode === 'compact' ? -2 : -4) ?? [];
|
|
7501
7297
|
const visibleChanges = resultSummary?.changes?.slice(0, policy.mode === 'compact' ? 2 : 4) ?? [];
|
|
7502
7298
|
const resultTargetName = (target) => target.pluginId
|
|
@@ -7620,7 +7416,7 @@ export function ConsoleAppV4(props) {
|
|
|
7620
7416
|
|| prioritizedPortableSkills.length > portableSkillLimit) {
|
|
7621
7417
|
help = 'PgUp/PgDn 查看全部项目 · ↑↓ 移动 · Enter 选择 · Esc 返回';
|
|
7622
7418
|
}
|
|
7623
|
-
content =
|
|
7419
|
+
content = taskOperation || batchOperation ? _jsxs(Box, { flexDirection: "column", children: [_jsxs(ResultCard, { status: resultStatus, title: "\u6240\u9009\u63D2\u4EF6\u7ED3\u679C", children: [taskResultOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${taskResultOffset} 项`, status: "muted", compact: true }) : null, visibleTaskResultRows, rootResultRows.length > taskResultOffset + visibleTaskResultRows.length
|
|
7624
7420
|
? _jsx(StaticRow, { title: "\u2193 \u540E\u9762\u8FD8\u6709", meta: `${rootResultRows.length - taskResultOffset - visibleTaskResultRows.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: [portableTechnicalSummary ? _jsxs(_Fragment, { children: [portableSkillOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${portableSkillOffset} 个 Skills`, status: "muted", compact: true }) : null, portableRows, hiddenPortableSkills > 0 ? _jsx(StaticRow, { title: `另有 ${hiddenPortableSkills} 个 Skills`, status: "muted", compact: true }) : null, portableReceipt?.recovery ? _jsx(StaticRow, { title: "\u5B89\u5168\u6062\u590D", meta: portableReceipt.recovery, status: "warning", compact: true }) : null, _jsx(TechnicalDetails, { children: compactTechnicalRows })] }) : _jsx(_Fragment, { children: _jsxs(ResultCard, { status: resultStatus, title: blocked ? '安装未开始或结果未确认' : partial ? '部分 Skills 未确认' : '通用 Skills 安装结果', children: [portableSkillOffset > 0 ? _jsx(StaticRow, { title: `↑ 前面还有 ${portableSkillOffset} 个 Skills`, status: "muted", compact: true }) : null, portableRows, hiddenPortableSkills > 0 ? _jsx(StaticRow, { title: `另有 ${hiddenPortableSkills} 个 Skills`, status: "muted", compact: true }) : null, portableReceipt ? _jsx(StaticRow, { title: `Agent:${portableReceipt.agentMode === 'automatic' ? 'Skills CLI 默认选择' : portableReceipt.requestedAgents.join('、')}`, meta: `范围:${scopeLabel(portableReceipt.scope)}`, compact: true }) : null, portableReceipt?.recovery ? policy.mode === 'compact'
|
|
7625
7421
|
? _jsx(StaticRow, { title: "\u5B89\u5168\u6062\u590D", meta: portableReceipt.recovery, status: "warning", compact: true })
|
|
7626
7422
|
: _jsx(Callout, { status: "warning", title: "\u5B89\u5168\u6062\u590D", description: portableReceipt.recovery }) : null, showTechnical && portableReceipt ? _jsxs(TechnicalDetails, { children: [portableReceipt.failureCode ? _jsx(StaticRow, { title: "failure code", meta: portableReceipt.failureCode, compact: true }) : null, _jsx(StaticRow, { title: "verification missing", meta: String(portableReceipt.missing.length), compact: true }), _jsx(StaticRow, { title: "Skills CLI version", meta: portableReceipt.skillsCliVersion, compact: true }), partial || blocked
|
|
@@ -7709,7 +7505,6 @@ export function ConsoleAppV4(props) {
|
|
|
7709
7505
|
case 'sourceAdd':
|
|
7710
7506
|
case 'sourceSave':
|
|
7711
7507
|
case 'scriptTimeout':
|
|
7712
|
-
case 'catalogWorkspace':
|
|
7713
7508
|
case 'reviewPreparing':
|
|
7714
7509
|
case 'review':
|
|
7715
7510
|
case 'result':
|
|
@@ -7772,6 +7567,16 @@ export function ConsoleAppV4(props) {
|
|
|
7772
7567
|
if (scrollOffset > lastActionIndex)
|
|
7773
7568
|
setScrollOffset(focus);
|
|
7774
7569
|
}, [batchSelectionActionSignature, focus, scrollOffset]);
|
|
7570
|
+
useEffect(() => {
|
|
7571
|
+
if (!pendingActionFocus.current)
|
|
7572
|
+
return;
|
|
7573
|
+
const nextFocus = actions.findIndex((action) => action.actionId === pendingActionFocus.current);
|
|
7574
|
+
if (nextFocus < 0)
|
|
7575
|
+
return;
|
|
7576
|
+
pendingActionFocus.current = undefined;
|
|
7577
|
+
setFocus(nextFocus);
|
|
7578
|
+
setScrollOffset(0);
|
|
7579
|
+
});
|
|
7775
7580
|
useEffect(() => {
|
|
7776
7581
|
if (!targetActionSignature || !actions[focus]?.disabled)
|
|
7777
7582
|
return;
|
|
@@ -7812,6 +7617,19 @@ export function ConsoleAppV4(props) {
|
|
|
7812
7617
|
showSafeUiFailure(error, 'tuiActionFailed', 'ui-action');
|
|
7813
7618
|
}
|
|
7814
7619
|
};
|
|
7620
|
+
function requestConfirmedExit(closeModal) {
|
|
7621
|
+
closeModal?.();
|
|
7622
|
+
const hasDrafts = dirty || props.controller.hasSessionDraft
|
|
7623
|
+
|| (discardDraftConfirmation?.length ?? 0) > 0;
|
|
7624
|
+
setOverlayFocus(0);
|
|
7625
|
+
setDiscardForExit(hasDrafts);
|
|
7626
|
+
setOverlay(hasDrafts ? 'discard' : 'exit');
|
|
7627
|
+
}
|
|
7628
|
+
function restoreActionFocus(actionId) {
|
|
7629
|
+
pendingActionFocus.current = actionId;
|
|
7630
|
+
setFocus(0);
|
|
7631
|
+
setScrollOffset(0);
|
|
7632
|
+
}
|
|
7815
7633
|
function requestSessionNavigation(navigation, discardDrafts = false) {
|
|
7816
7634
|
if (!props.onSessionNavigation) {
|
|
7817
7635
|
if (navigation !== 'home')
|
|
@@ -7858,10 +7676,6 @@ export function ConsoleAppV4(props) {
|
|
|
7858
7676
|
setObjectError(undefined);
|
|
7859
7677
|
setSourceDraft(undefined);
|
|
7860
7678
|
setBatchDraft(undefined);
|
|
7861
|
-
setCatalogInput('');
|
|
7862
|
-
setCatalogWorkspaceDraft({ ownerName: '', ownerUrl: '', displayName: '', catalogVersion: '0.1.0' });
|
|
7863
|
-
setCatalogPublishDraft({ targetKind: 'remote', target: '', branch: 'catalog' });
|
|
7864
|
-
setCatalogDevSourceId('');
|
|
7865
7679
|
}
|
|
7866
7680
|
function continueEditingFromSessionNavigation() {
|
|
7867
7681
|
if (props.pendingSessionNavigation)
|
|
@@ -7933,9 +7747,11 @@ export function ConsoleAppV4(props) {
|
|
|
7933
7747
|
}
|
|
7934
7748
|
return;
|
|
7935
7749
|
}
|
|
7936
|
-
if (tooSmall) {
|
|
7750
|
+
if (tooSmall && !overlay) {
|
|
7937
7751
|
if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
7938
|
-
|
|
7752
|
+
setOperationConfirmation(undefined);
|
|
7753
|
+
setSourceTransportOverlay(undefined);
|
|
7754
|
+
requestConfirmedExit();
|
|
7939
7755
|
}
|
|
7940
7756
|
return;
|
|
7941
7757
|
}
|
|
@@ -7950,14 +7766,8 @@ export function ConsoleAppV4(props) {
|
|
|
7950
7766
|
if (key.escape || input.toLowerCase() === 'b') {
|
|
7951
7767
|
closeConfirmation();
|
|
7952
7768
|
}
|
|
7953
|
-
else if (key.ctrl && input.toLowerCase() === 'c') {
|
|
7954
|
-
closeConfirmation
|
|
7955
|
-
requestExit({ code: 0, reason: 'user' });
|
|
7956
|
-
}
|
|
7957
|
-
else if (input.toLowerCase() === 'q') {
|
|
7958
|
-
closeConfirmation();
|
|
7959
|
-
setDiscardForExit(dirty);
|
|
7960
|
-
setOverlay(dirty ? 'discard' : 'exit');
|
|
7769
|
+
else if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
7770
|
+
requestConfirmedExit(closeConfirmation);
|
|
7961
7771
|
}
|
|
7962
7772
|
else if (props.onSessionNavigation && (input === 'h' || input === 'H')) {
|
|
7963
7773
|
const navigation = input === 'H' ? 'reload' : 'home';
|
|
@@ -7998,9 +7808,19 @@ export function ConsoleAppV4(props) {
|
|
|
7998
7808
|
return;
|
|
7999
7809
|
}
|
|
8000
7810
|
if (sourceTransportOverlay) {
|
|
8001
|
-
|
|
7811
|
+
const closeTransportOverlay = () => {
|
|
8002
7812
|
setSourceTransportOverlay(undefined);
|
|
8003
7813
|
setOverlayFocus(0);
|
|
7814
|
+
};
|
|
7815
|
+
if (key.escape || input.toLowerCase() === 'b') {
|
|
7816
|
+
closeTransportOverlay();
|
|
7817
|
+
}
|
|
7818
|
+
else if (input.toLowerCase() === 'q' || (key.ctrl && input.toLowerCase() === 'c')) {
|
|
7819
|
+
requestConfirmedExit(closeTransportOverlay);
|
|
7820
|
+
}
|
|
7821
|
+
else if (props.onSessionNavigation && (input === 'h' || input === 'H')) {
|
|
7822
|
+
closeTransportOverlay();
|
|
7823
|
+
requestSessionNavigation(input === 'H' ? 'reload' : 'home');
|
|
8004
7824
|
}
|
|
8005
7825
|
else if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {
|
|
8006
7826
|
setOverlayFocus((value) => moveIndex(2, value, key.upArrow || key.leftArrow ? -1 : 1));
|
|
@@ -8017,14 +7837,17 @@ export function ConsoleAppV4(props) {
|
|
|
8017
7837
|
setDirty(true);
|
|
8018
7838
|
props.controller.replace({ name: 'sourceEdit', sourceId: route.sourceId, owner: current.owner });
|
|
8019
7839
|
}
|
|
8020
|
-
|
|
8021
|
-
setOverlayFocus(0);
|
|
7840
|
+
closeTransportOverlay();
|
|
8022
7841
|
}
|
|
8023
7842
|
return;
|
|
8024
7843
|
}
|
|
8025
7844
|
if (overlay) {
|
|
8026
7845
|
if (key.ctrl && input.toLowerCase() === 'c') {
|
|
8027
|
-
|
|
7846
|
+
if (overlay === 'sessionNavigation')
|
|
7847
|
+
continueEditingFromSessionNavigation();
|
|
7848
|
+
setDiscardForSessionNavigation(undefined);
|
|
7849
|
+
setDiscardDraftConfirmation(undefined);
|
|
7850
|
+
requestConfirmedExit(overlay === 'help' ? () => setOverlay(undefined) : undefined);
|
|
8028
7851
|
return;
|
|
8029
7852
|
}
|
|
8030
7853
|
if (overlay === 'help' && input.toLowerCase() === 'o') {
|
|
@@ -8094,7 +7917,7 @@ export function ConsoleAppV4(props) {
|
|
|
8094
7917
|
return;
|
|
8095
7918
|
}
|
|
8096
7919
|
if (key.ctrl && input.toLowerCase() === 'c') {
|
|
8097
|
-
|
|
7920
|
+
requestConfirmedExit();
|
|
8098
7921
|
return;
|
|
8099
7922
|
}
|
|
8100
7923
|
if (route.name === 'operationReportPreview' && reportSaveMode) {
|
|
@@ -8131,8 +7954,17 @@ export function ConsoleAppV4(props) {
|
|
|
8131
7954
|
setReportSaveError(undefined);
|
|
8132
7955
|
return;
|
|
8133
7956
|
}
|
|
7957
|
+
if ((key.pageUp || key.pageDown) && route.name === 'pluginDetail'
|
|
7958
|
+
&& placementConclusionPagination) {
|
|
7959
|
+
const { total, pageRows } = placementConclusionPagination;
|
|
7960
|
+
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp ? -pageRows : pageRows))));
|
|
7961
|
+
return;
|
|
7962
|
+
}
|
|
8134
7963
|
if ((key.pageUp || key.pageDown)
|
|
8135
|
-
&& route.name === 'pluginDependencyNode'
|
|
7964
|
+
&& (route.name === 'pluginDependencyNode'
|
|
7965
|
+
&& (route.view === 'references' || route.view === 'details')
|
|
7966
|
+
|| route.name === 'configSave' && route.view === 'changes'
|
|
7967
|
+
|| route.name === 'sourceSave' && route.view === 'changes')
|
|
8136
7968
|
&& referenceDetailPagination) {
|
|
8137
7969
|
const { total, pageRows } = referenceDetailPagination;
|
|
8138
7970
|
setBatchTargetOffset((value) => Math.min(Math.max(0, total - 1), Math.max(0, value + (key.pageUp ? -pageRows : pageRows))));
|
|
@@ -8200,15 +8032,6 @@ export function ConsoleAppV4(props) {
|
|
|
8200
8032
|
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp ? -pageRows : pageRows))));
|
|
8201
8033
|
return;
|
|
8202
8034
|
}
|
|
8203
|
-
if ((key.pageUp || key.pageDown) && (route.name === 'catalogStore'
|
|
8204
|
-
|| route.name === 'catalogPublish' && route.step === 'overview')) {
|
|
8205
|
-
const total = route.name === 'catalogStore'
|
|
8206
|
-
? catalogStore?.entries.length ?? 0
|
|
8207
|
-
: catalogPublication?.records.length ?? 0;
|
|
8208
|
-
const pageRows = responsiveBudget(3, 7);
|
|
8209
|
-
setBatchTargetOffset((value) => Math.min(Math.max(0, total - pageRows), Math.max(0, value + (key.pageUp ? -pageRows : pageRows))));
|
|
8210
|
-
return;
|
|
8211
|
-
}
|
|
8212
8035
|
if ((key.pageUp || key.pageDown) && route.name === 'pluginDependencies' && plugin) {
|
|
8213
8036
|
const overview = dependencyOverview(plugin);
|
|
8214
8037
|
const dependents = route.view === 'removeBlocked' && route.platform && route.scope
|
|
@@ -8379,180 +8202,6 @@ export function ConsoleAppV4(props) {
|
|
|
8379
8202
|
setSourceInputError(undefined);
|
|
8380
8203
|
return;
|
|
8381
8204
|
}
|
|
8382
|
-
if (route.name === 'catalogWorkspace' && (route.view === 'select'
|
|
8383
|
-
|| route.view === 'create' || route.view === 'version' && route.step === 'catalogVersion')) {
|
|
8384
|
-
if (key.escape) {
|
|
8385
|
-
if (route.view === 'create') {
|
|
8386
|
-
const step = route.step ?? 'ownerName';
|
|
8387
|
-
const next = { ...catalogWorkspaceDraft, [step]: catalogInput };
|
|
8388
|
-
setCatalogWorkspaceDraft(next);
|
|
8389
|
-
const previous = { ownerUrl: 'ownerName', displayName: 'ownerUrl', catalogVersion: 'displayName' }[step];
|
|
8390
|
-
if (previous) {
|
|
8391
|
-
setCatalogInput(next[previous]);
|
|
8392
|
-
props.controller.replace({ ...route, step: previous });
|
|
8393
|
-
}
|
|
8394
|
-
else
|
|
8395
|
-
back();
|
|
8396
|
-
}
|
|
8397
|
-
else
|
|
8398
|
-
back();
|
|
8399
|
-
return;
|
|
8400
|
-
}
|
|
8401
|
-
if (key.return) {
|
|
8402
|
-
const value = catalogInput.trim();
|
|
8403
|
-
setCatalogInputError(undefined);
|
|
8404
|
-
if (route.view === 'select') {
|
|
8405
|
-
setCatalogLoading(true);
|
|
8406
|
-
void props.controller.selectCatalogWorkspace(value || undefined).then((workspace) => {
|
|
8407
|
-
setCatalogWorkspace(workspace);
|
|
8408
|
-
props.controller.replace({ name: 'catalogWorkspace', view: 'overview' });
|
|
8409
|
-
setFocus(0);
|
|
8410
|
-
setScrollOffset(0);
|
|
8411
|
-
setCatalogInput('');
|
|
8412
|
-
}).catch((error) => setCatalogInputError(sanitizeDiagnosticText(error instanceof Error ? error.message : String(error), [], [catalogInput]))).finally(() => setCatalogLoading(false));
|
|
8413
|
-
return;
|
|
8414
|
-
}
|
|
8415
|
-
if (route.view === 'version') {
|
|
8416
|
-
if (!/^\d+\.\d+\.\d+(?:-beta\.\d+)?$/u.test(value)) {
|
|
8417
|
-
setCatalogInputError('版本必须是 x.y.z 或精确 x.y.z-beta.N。');
|
|
8418
|
-
return;
|
|
8419
|
-
}
|
|
8420
|
-
beginReview({ kind: 'catalogManagement', action: 'workspaceVersion', version: value }, { name: 'catalogWorkspace', view: 'overview' });
|
|
8421
|
-
return;
|
|
8422
|
-
}
|
|
8423
|
-
const step = route.step ?? 'ownerName';
|
|
8424
|
-
if (!value) {
|
|
8425
|
-
setCatalogInputError('此字段不能为空。');
|
|
8426
|
-
return;
|
|
8427
|
-
}
|
|
8428
|
-
if (step === 'ownerUrl') {
|
|
8429
|
-
try {
|
|
8430
|
-
const url = new URL(value);
|
|
8431
|
-
if (url.protocol !== 'https:' && url.protocol !== 'http:')
|
|
8432
|
-
throw new Error();
|
|
8433
|
-
}
|
|
8434
|
-
catch {
|
|
8435
|
-
setCatalogInputError('请输入有效的 HTTP 或 HTTPS owner URL。');
|
|
8436
|
-
return;
|
|
8437
|
-
}
|
|
8438
|
-
}
|
|
8439
|
-
if (step === 'catalogVersion' && !/^\d+\.\d+\.\d+(?:-beta\.\d+)?$/u.test(value)) {
|
|
8440
|
-
setCatalogInputError('版本必须是 x.y.z 或精确 x.y.z-beta.N。');
|
|
8441
|
-
return;
|
|
8442
|
-
}
|
|
8443
|
-
const next = { ...catalogWorkspaceDraft, [step]: value };
|
|
8444
|
-
setCatalogWorkspaceDraft(next);
|
|
8445
|
-
setCatalogInput('');
|
|
8446
|
-
if (step === 'ownerName')
|
|
8447
|
-
props.controller.replace({ ...route, step: 'ownerUrl' });
|
|
8448
|
-
else if (step === 'ownerUrl')
|
|
8449
|
-
props.controller.replace({ ...route, step: 'displayName' });
|
|
8450
|
-
else if (step === 'displayName') {
|
|
8451
|
-
setCatalogInput('0.1.0');
|
|
8452
|
-
props.controller.replace({ ...route, step: 'catalogVersion' });
|
|
8453
|
-
}
|
|
8454
|
-
else
|
|
8455
|
-
beginReview({ kind: 'catalogManagement', action: 'workspaceInit', ...next }, { name: 'catalogWorkspace', view: 'overview' });
|
|
8456
|
-
return;
|
|
8457
|
-
}
|
|
8458
|
-
if (input === '\u0015' || (input.toLowerCase() === 'u' && key.ctrl))
|
|
8459
|
-
setCatalogInput('');
|
|
8460
|
-
else if (key.backspace || key.delete)
|
|
8461
|
-
setCatalogInput(removeLastGrapheme);
|
|
8462
|
-
else if (input && !key.ctrl && !key.meta && input >= ' ')
|
|
8463
|
-
setCatalogInput((value) => value + input);
|
|
8464
|
-
setCatalogInputError(undefined);
|
|
8465
|
-
return;
|
|
8466
|
-
}
|
|
8467
|
-
if (route.name === 'catalogDev' && route.step && route.step !== 'overview') {
|
|
8468
|
-
if (key.escape) {
|
|
8469
|
-
back();
|
|
8470
|
-
return;
|
|
8471
|
-
}
|
|
8472
|
-
if (key.return) {
|
|
8473
|
-
const value = catalogInput.trim();
|
|
8474
|
-
if (value && !CATALOG_SOURCE_ID_PATTERN.test(value)) {
|
|
8475
|
-
setCatalogInputError('格式必须是小写字母、数字或连字符,最多 32 字符。');
|
|
8476
|
-
return;
|
|
8477
|
-
}
|
|
8478
|
-
if (route.step === 'sourceId') {
|
|
8479
|
-
setCatalogDevSourceId(value);
|
|
8480
|
-
back();
|
|
8481
|
-
}
|
|
8482
|
-
else {
|
|
8483
|
-
if (!value) {
|
|
8484
|
-
setCatalogInputError('请输入替代主来源 ID。');
|
|
8485
|
-
return;
|
|
8486
|
-
}
|
|
8487
|
-
beginReview({ kind: 'catalogManagement', action: 'devDeactivate', replacementPrimary: value }, { name: 'catalogDev' });
|
|
8488
|
-
}
|
|
8489
|
-
return;
|
|
8490
|
-
}
|
|
8491
|
-
if (input === '\u0015' || (input.toLowerCase() === 'u' && key.ctrl))
|
|
8492
|
-
setCatalogInput('');
|
|
8493
|
-
else if (key.backspace || key.delete)
|
|
8494
|
-
setCatalogInput(removeLastGrapheme);
|
|
8495
|
-
else if (input && !key.ctrl && !key.meta && input >= ' ')
|
|
8496
|
-
setCatalogInput((value) => value + input);
|
|
8497
|
-
setCatalogInputError(undefined);
|
|
8498
|
-
return;
|
|
8499
|
-
}
|
|
8500
|
-
if (route.name === 'catalogPublish' && route.step !== 'overview') {
|
|
8501
|
-
if (key.escape) {
|
|
8502
|
-
if (route.step === 'branch') {
|
|
8503
|
-
setCatalogPublishDraft((draft) => ({ ...draft, branch: catalogInput.trim() || 'catalog' }));
|
|
8504
|
-
setCatalogInput(catalogPublishDraft.target);
|
|
8505
|
-
props.controller.replace({ name: 'catalogPublish', step: 'target' });
|
|
8506
|
-
}
|
|
8507
|
-
else {
|
|
8508
|
-
const value = catalogInput.trim();
|
|
8509
|
-
const targetKind = value.includes('://') || /^[^@\s]+@[^:\s]+:/u.test(value) || value.startsWith('/')
|
|
8510
|
-
? 'remoteUrl' : 'remote';
|
|
8511
|
-
setCatalogPublishDraft((draft) => ({ ...draft, targetKind, target: value }));
|
|
8512
|
-
back();
|
|
8513
|
-
}
|
|
8514
|
-
return;
|
|
8515
|
-
}
|
|
8516
|
-
if (key.return) {
|
|
8517
|
-
const value = catalogInput.trim();
|
|
8518
|
-
if (route.step === 'target') {
|
|
8519
|
-
if (/\s/u.test(value)) {
|
|
8520
|
-
setCatalogInputError('remote 名称或 URL 不能包含空白。');
|
|
8521
|
-
return;
|
|
8522
|
-
}
|
|
8523
|
-
const targetKind = value.includes('://') || /^[^@\s]+@[^:\s]+:/u.test(value) || value.startsWith('/')
|
|
8524
|
-
? 'remoteUrl' : 'remote';
|
|
8525
|
-
setCatalogPublishDraft((draft) => ({ ...draft, targetKind, target: value }));
|
|
8526
|
-
setCatalogInput(catalogPublishDraft.expectedPlanDigest ? catalogPublishDraft.branch : 'catalog');
|
|
8527
|
-
props.controller.replace({ name: 'catalogPublish', step: 'branch' });
|
|
8528
|
-
}
|
|
8529
|
-
else {
|
|
8530
|
-
const branch = value || 'catalog';
|
|
8531
|
-
if (/\s|\.\.|[~^:?*\[\\]/u.test(branch) || branch.startsWith('-') || branch.endsWith('/')) {
|
|
8532
|
-
setCatalogInputError('请输入安全的 Git branch 名称。');
|
|
8533
|
-
return;
|
|
8534
|
-
}
|
|
8535
|
-
const draft = { ...catalogPublishDraft, branch };
|
|
8536
|
-
setCatalogPublishDraft(draft);
|
|
8537
|
-
const target = draft.target
|
|
8538
|
-
? draft.targetKind === 'remote' ? { remote: draft.target } : { remoteUrl: draft.target }
|
|
8539
|
-
: {};
|
|
8540
|
-
beginReview(draft.expectedPlanDigest
|
|
8541
|
-
? { kind: 'catalogManagement', action: 'publishApply', expectedPlanDigest: draft.expectedPlanDigest,
|
|
8542
|
-
...target, branch }
|
|
8543
|
-
: { kind: 'catalogManagement', action: 'publishPlan', ...target, branch }, { name: 'catalogPublish', step: 'overview' });
|
|
8544
|
-
}
|
|
8545
|
-
return;
|
|
8546
|
-
}
|
|
8547
|
-
if (input === '\u0015' || (input.toLowerCase() === 'u' && key.ctrl))
|
|
8548
|
-
setCatalogInput('');
|
|
8549
|
-
else if (key.backspace || key.delete)
|
|
8550
|
-
setCatalogInput(removeLastGrapheme);
|
|
8551
|
-
else if (input && !key.ctrl && !key.meta && input >= ' ')
|
|
8552
|
-
setCatalogInput((value) => value + input);
|
|
8553
|
-
setCatalogInputError(undefined);
|
|
8554
|
-
return;
|
|
8555
|
-
}
|
|
8556
8205
|
if (route.name === 'configFieldEditor'
|
|
8557
8206
|
&& (route.editor === 'string' || route.editor === 'number')
|
|
8558
8207
|
&& ((activeField?.choices?.length ?? 0) === 0 || route.mode === 'custom')) {
|
|
@@ -8793,13 +8442,16 @@ export function ConsoleAppV4(props) {
|
|
|
8793
8442
|
setOverlay('help');
|
|
8794
8443
|
}
|
|
8795
8444
|
else if (globalAction === 'exit') {
|
|
8796
|
-
|
|
8797
|
-
setDiscardForExit(dirty);
|
|
8798
|
-
setOverlay(dirty ? 'discard' : 'exit');
|
|
8445
|
+
requestConfirmedExit();
|
|
8799
8446
|
}
|
|
8800
8447
|
else if (input.toLowerCase() === 'd' && supportsTechnicalDetails) {
|
|
8801
8448
|
toggleTechnical();
|
|
8802
8449
|
}
|
|
8450
|
+
else if (globalAction === 'back'
|
|
8451
|
+
&& (route.name === 'configSave' || route.name === 'sourceSave')
|
|
8452
|
+
&& route.view === 'changes') {
|
|
8453
|
+
back();
|
|
8454
|
+
}
|
|
8803
8455
|
else if (globalAction === 'back'
|
|
8804
8456
|
&& (route.name === 'configFieldEditor'
|
|
8805
8457
|
|| route.name === 'configObjectPropertyEditor'
|
|
@@ -8809,8 +8461,7 @@ export function ConsoleAppV4(props) {
|
|
|
8809
8461
|
else if (globalAction === 'back' && route.name === 'batchPlacement') {
|
|
8810
8462
|
if (batchDraft?.showPlacementTargets) {
|
|
8811
8463
|
setBatchDraft((current) => current ? { ...current, showPlacementTargets: false } : current);
|
|
8812
|
-
|
|
8813
|
-
setScrollOffset(0);
|
|
8464
|
+
restoreActionFocus('batch-placement-details');
|
|
8814
8465
|
}
|
|
8815
8466
|
else
|
|
8816
8467
|
back();
|
|
@@ -8884,23 +8535,7 @@ export function ConsoleAppV4(props) {
|
|
|
8884
8535
|
} : current);
|
|
8885
8536
|
}
|
|
8886
8537
|
else if (route.name === 'batchSelection' && batchDraft?.stage === 'select' && input.toLowerCase() === 'c') {
|
|
8887
|
-
|
|
8888
|
-
const invalid = invalidBatchSelection(batchDraft);
|
|
8889
|
-
if (invalid.length > 0) {
|
|
8890
|
-
setActionError(`${invalid.length} 个已选插件已不可用。请先在“查看全部已选”中取消选择。`);
|
|
8891
|
-
return;
|
|
8892
|
-
}
|
|
8893
|
-
if (batchDraft.mode === 'browse') {
|
|
8894
|
-
setBatchDraft((current) => current ? { ...current, action: 'install' } : current);
|
|
8895
|
-
props.controller.push({ name: 'batchPlacement' });
|
|
8896
|
-
setFocus(0);
|
|
8897
|
-
setScrollOffset(0);
|
|
8898
|
-
}
|
|
8899
|
-
else
|
|
8900
|
-
moveBatchStage('task');
|
|
8901
|
-
}
|
|
8902
|
-
else
|
|
8903
|
-
setActionError('请至少选择一个插件。');
|
|
8538
|
+
runAction(actions.find((action) => action.actionId === 'batch-selection-continue'));
|
|
8904
8539
|
}
|
|
8905
8540
|
else if (route.name === 'batchSelection' && batchDraft?.stage === 'select' && input === ' ') {
|
|
8906
8541
|
const action = actions[normalizedEffectiveFocus];
|
|
@@ -9068,7 +8703,7 @@ export function ConsoleAppV4(props) {
|
|
|
9068
8703
|
runAction(actions[normalizedEffectiveFocus]);
|
|
9069
8704
|
}
|
|
9070
8705
|
});
|
|
9071
|
-
if (tooSmall) {
|
|
8706
|
+
if (tooSmall && !overlay) {
|
|
9072
8707
|
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" }) }));
|
|
9073
8708
|
}
|
|
9074
8709
|
if (actionError)
|
|
@@ -9135,7 +8770,8 @@ export function ConsoleAppV4(props) {
|
|
|
9135
8770
|
: overlay === 'discard' || overlay === 'sessionNavigation' ? '放弃未保存修改?'
|
|
9136
8771
|
: '退出控制台?', children: [overlay === 'help'
|
|
9137
8772
|
? _jsx(_Fragment, { children: helpRows.map(([key, value]) => _jsx(StaticRow, { title: `${key} ${value}`, compact: true }, key)) })
|
|
9138
|
-
: _jsx(StaticRow, { title: overlay === 'discard'
|
|
8773
|
+
: _jsx(StaticRow, { title: overlay === 'discard'
|
|
8774
|
+
? discardForExit ? '放弃后将退出控制台。' : '放弃后将返回上一页。'
|
|
9139
8775
|
: overlay === 'sessionNavigation'
|
|
9140
8776
|
? `放弃后将${discardForSessionNavigation === 'reload' ? '重新读取本地状态' : '返回首页'}。`
|
|
9141
8777
|
: '进行中的写操作会先完成。', status: "muted" }), _jsx(SemanticRows, { actions: overlayActions, focus: overlayFocus, kind: "action", compact: true })] }) })] }));
|