@@ -884,11 +884,13 @@ <h2 data-i18n="summary">切换摘要</h2>
884884 loadingConfig : "读取配置中" ,
885885 configureAccounts : "配置账号后切换" ,
886886 runSwitch : "一键切换" ,
887+ noChanges : "无变更" ,
887888 readonlyNote : "登录后才可执行切换。" ,
888889 publicReadonly : "登录后查看账号配置。" ,
889890 loadingConfigNote : "正在读取账号配置和当前状态。" ,
890891 missingConfigNote : "账号配置未加载,暂时不能执行。" ,
891892 readyNote : "点击后会触发 workflow,并同步目标平台服务。" ,
893+ noChangesNote : "当前选择与已读取配置一致。" ,
892894 invalidStrategyNote : "当前账号没有可执行策略,暂时不能切换。" ,
893895 noAccount : "没有账号选项" ,
894896 noStrategy : "没有支持的策略" ,
@@ -897,6 +899,7 @@ <h2 data-i18n="summary">切换摘要</h2>
897899 selectedMarket : "市场" ,
898900 reservedCashPolicy : "当前预留现金" ,
899901 pendingReservedCashPolicy : "待提交预留现金" ,
902+ pendingMode : "待提交模式" ,
900903 unchanged : "不变" ,
901904 copied : "已复制状态" ,
902905 dispatching : "正在触发 workflow..." ,
@@ -939,11 +942,13 @@ <h2 data-i18n="summary">切换摘要</h2>
939942 loadingConfig : "Loading config" ,
940943 configureAccounts : "Configure accounts" ,
941944 runSwitch : "Switch now" ,
945+ noChanges : "No changes" ,
942946 readonlyNote : "Sign in to switch." ,
943947 publicReadonly : "Sign in to view account config." ,
944948 loadingConfigNote : "Reading account config and current state." ,
945949 missingConfigNote : "Account config is not loaded, so switching is disabled." ,
946950 readyNote : "This dispatches the workflow and syncs the target platform service." ,
951+ noChangesNote : "The current selection matches the readable config." ,
947952 invalidStrategyNote : "This account has no runnable strategy, so switching is disabled." ,
948953 noAccount : "No accounts" ,
949954 noStrategy : "No supported strategies" ,
@@ -952,6 +957,7 @@ <h2 data-i18n="summary">切换摘要</h2>
952957 selectedMarket : "Market" ,
953958 reservedCashPolicy : "Current reserved cash" ,
954959 pendingReservedCashPolicy : "Pending reserved cash" ,
960+ pendingMode : "Pending mode" ,
955961 unchanged : "Unchanged" ,
956962 copied : "State copied" ,
957963 dispatching : "Dispatching workflow..." ,
@@ -1304,8 +1310,10 @@ <h2 data-i18n="summary">切换摘要</h2>
13041310 ] ) {
13051311 if ( account [ field ] ) inputs [ field ] = account [ field ] ;
13061312 }
1307- if ( form . reservedCashRatio ) inputs . reserved_cash_ratio = form . reservedCashRatio ;
1308- if ( form . minReservedCashUsd ) inputs . min_reserved_cash_usd = form . minReservedCashUsd ;
1313+ if ( form . reservedCashTouched ) {
1314+ if ( form . reservedCashRatio ) inputs . reserved_cash_ratio = form . reservedCashRatio ;
1315+ if ( form . minReservedCashUsd ) inputs . min_reserved_cash_usd = form . minReservedCashUsd ;
1316+ }
13091317 return inputs ;
13101318 }
13111319
@@ -1333,7 +1341,46 @@ <h2 data-i18n="summary">切换摘要</h2>
13331341 }
13341342
13351343 function pendingReservedCashPolicyText ( inputs , platform = state . selected , account = selectedAccount ( platform ) ) {
1336- return reservedCashPolicyText ( inputs , platform , account , t ( "unchanged" ) ) ;
1344+ return reservedCashPolicyText ( pendingReservePolicy ( inputs , platform , account ) . inputs , platform , account , t ( "unchanged" ) ) ;
1345+ }
1346+
1347+ function pendingReservePolicy ( inputs , platform = state . selected , account = selectedAccount ( platform ) ) {
1348+ const current = currentReservePolicyForAccount ( platform , account ) ;
1349+ const floorOverride = cleanDisplayNumber ( inputs . min_reserved_cash_usd ) ;
1350+ const ratioOverride = cleanDisplayRatio ( inputs . reserved_cash_ratio ) ;
1351+ const changed = Boolean (
1352+ ( floorOverride && floorOverride !== current . minReservedCashUsd ) ||
1353+ ( ratioOverride && ratioOverride !== current . reservedCashRatio ) ,
1354+ ) ;
1355+ return {
1356+ changed,
1357+ inputs : {
1358+ min_reserved_cash_usd : floorOverride || current . minReservedCashUsd ,
1359+ reserved_cash_ratio : ratioOverride || current . reservedCashRatio ,
1360+ } ,
1361+ } ;
1362+ }
1363+
1364+ function pendingChangeState ( inputs , platform = state . selected , account = selectedAccount ( platform ) ) {
1365+ const currentProfile = currentStrategyForAccount ( platform , account ) ;
1366+ const nextProfile = cleanStrategyProfile ( inputs . strategy_profile ) ;
1367+ const currentEntry = currentEntryForAccount ( platform , account ) ;
1368+ const currentMode = normalizeExecutionMode ( currentEntry ?. execution_mode , currentEntry ?. dry_run_only ) ;
1369+ const reserve = pendingReservePolicy ( inputs , platform , account ) ;
1370+ return {
1371+ currentProfile,
1372+ nextProfile,
1373+ currentMode,
1374+ strategyChanged : Boolean ( nextProfile && ( ! currentProfile || currentProfile !== nextProfile ) ) ,
1375+ modeChanged : Boolean ( currentMode && inputs . execution_mode && currentMode !== inputs . execution_mode ) ,
1376+ reserveCashChanged : reserve . changed ,
1377+ reserve,
1378+ } ;
1379+ }
1380+
1381+ function hasPendingChanges ( inputs , platform = state . selected , account = selectedAccount ( platform ) ) {
1382+ const changes = pendingChangeState ( inputs , platform , account ) ;
1383+ return Boolean ( changes . strategyChanged || changes . modeChanged || changes . reserveCashChanged ) ;
13371384 }
13381385
13391386 function formatRatioPercent ( value ) {
@@ -1344,20 +1391,23 @@ <h2 data-i18n="summary">切换摘要</h2>
13441391
13451392 function summaryRows ( inputs ) {
13461393 const account = selectedAccount ( ) ;
1347- const currentProfile = currentStrategyForAccount ( state . selected , account ) ;
1348- const nextProfile = cleanStrategyProfile ( inputs . strategy_profile ) ;
1349- const currentStrategyText = currentProfile ? strategyLabel ( currentProfile ) : t ( "notRead" ) ;
1350- const nextStrategyChanged = ! currentProfile || currentProfile !== nextProfile ;
1394+ const changes = pendingChangeState ( inputs , state . selected , account ) ;
1395+ const currentStrategyText = changes . currentProfile ? strategyLabel ( changes . currentProfile ) : t ( "notRead" ) ;
13511396 const rows = [
13521397 [ t ( "repository" ) , state . repositories [ state . selected ] || defaultRepositories [ state . selected ] ] ,
13531398 [ t ( "selectedAccount" ) , account . label ] ,
13541399 [ t ( "currentStrategy" ) , currentStrategyText ] ,
13551400 [ t ( "selectedMarket" ) , supportedDomainLabel ( state . selected , account ) ] ,
13561401 [ t ( "reservedCashPolicy" ) , currentReservedCashPolicyText ( state . selected , account ) ] ,
1357- [ t ( "pendingReservedCashPolicy" ) , pendingReservedCashPolicyText ( inputs , state . selected , account ) , "pending" ] ,
13581402 ] ;
1359- if ( nextStrategyChanged && nextProfile ) {
1360- rows . push ( [ t ( "nextStrategy" ) , strategyLabel ( nextProfile ) , "pending" ] ) ;
1403+ if ( changes . reserveCashChanged ) {
1404+ rows . push ( [ t ( "pendingReservedCashPolicy" ) , pendingReservedCashPolicyText ( inputs , state . selected , account ) , "pending" ] ) ;
1405+ }
1406+ if ( changes . modeChanged ) {
1407+ rows . push ( [ t ( "pendingMode" ) , modeLabel ( inputs . execution_mode ) , "pending" ] ) ;
1408+ }
1409+ if ( changes . strategyChanged && changes . nextProfile ) {
1410+ rows . push ( [ t ( "nextStrategy" ) , strategyLabel ( changes . nextProfile ) , "pending" ] ) ;
13611411 }
13621412 return rows ;
13631413 }
@@ -1519,17 +1569,25 @@ <h2 data-i18n="summary">切换摘要</h2>
15191569 const hasPrivateAccounts = state . configSource === "private" ;
15201570 const loadingConfig = state . configSource === "loading" ;
15211571 const hasValidStrategy = hasValidStrategySelection ( ) ;
1522- dispatch . disabled = ! state . auth . allowed || loadingConfig || ! hasPrivateAccounts || ! hasValidStrategy ;
1572+ const hasPendingChange = hasPrivateAccounts && hasValidStrategy && hasPendingChanges ( buildInputs ( ) ) ;
1573+ dispatch . disabled = ! state . auth . allowed || loadingConfig || ! hasPrivateAccounts || ! hasValidStrategy || ! hasPendingChange ;
15231574 dispatch . textContent = state . auth . allowed
1524- ? ( loadingConfig ? t ( "loadingConfig" ) : ( hasPrivateAccounts ? t ( "runSwitch" ) : t ( "configureAccounts" ) ) )
1575+ ? ( loadingConfig
1576+ ? t ( "loadingConfig" )
1577+ : ( hasPrivateAccounts ? ( hasValidStrategy ? ( hasPendingChange ? t ( "runSwitch" ) : t ( "noChanges" ) ) : t ( "configureAccounts" ) ) : t ( "configureAccounts" ) ) )
15251578 : t ( "loginToRun" ) ;
15261579 const note = el ( "action-note" ) ;
15271580 note . textContent = state . auth . allowed
15281581 ? ( loadingConfig
15291582 ? t ( "loadingConfigNote" )
1530- : ( hasPrivateAccounts ? ( hasValidStrategy ? t ( "readyNote" ) : t ( "invalidStrategyNote" ) ) : t ( "missingConfigNote" ) ) )
1583+ : ( hasPrivateAccounts
1584+ ? ( hasValidStrategy ? ( hasPendingChange ? t ( "readyNote" ) : t ( "noChangesNote" ) ) : t ( "invalidStrategyNote" ) )
1585+ : t ( "missingConfigNote" ) ) )
15311586 : t ( "readonlyNote" ) ;
1532- note . classList . toggle ( "warning" , state . auth . allowed && ! loadingConfig && ( ! hasPrivateAccounts || ! hasValidStrategy ) ) ;
1587+ note . classList . toggle (
1588+ "warning" ,
1589+ state . auth . allowed && ! loadingConfig && ( ! hasPrivateAccounts || ! hasValidStrategy || ! hasPendingChange ) ,
1590+ ) ;
15331591 }
15341592
15351593 function renderAppVisibility ( ) {
0 commit comments