Add restart stage to app update process
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Introduced a new restart stage in the app update progress component, allowing for better handling of application restarts.
- Updated the status management to include restart states, enhancing user feedback during the update process.
- Modified installation completion messages to indicate that a restart will occur after installation.
- Adjusted prop types to accommodate the new restart stage in the UpdateStage component.
This commit is contained in:
Tom Butcher 2026-08-02 20:04:30 +01:00
parent 30f0ac1559
commit 9ef02304fe
3 changed files with 25 additions and 6 deletions

View File

@ -4,6 +4,7 @@ import { Button, Flex, Modal, Progress, Typography, theme, Divider } from 'antd'
import CloudIcon from '../../../Icons/CloudIcon' import CloudIcon from '../../../Icons/CloudIcon'
import HostIcon from '../../../Icons/HostIcon' import HostIcon from '../../../Icons/HostIcon'
import ReloadIcon from '../../../Icons/ReloadIcon'
import CheckCircleIcon from '../../../Icons/CheckCircleIcon' import CheckCircleIcon from '../../../Icons/CheckCircleIcon'
import XMarkCircleIcon from '../../../Icons/XMarkCircleIcon' import XMarkCircleIcon from '../../../Icons/XMarkCircleIcon'
@ -45,6 +46,15 @@ const STAGE_CONFIG = {
complete: 'Installed', complete: 'Installed',
error: 'Install failed' error: 'Install failed'
} }
},
restart: {
icon: ReloadIcon,
labels: {
pending: 'Restart',
active: 'Restarting...',
complete: 'Restarted',
error: 'Restart failed'
}
} }
} }
@ -69,7 +79,8 @@ const isInstallComplete = (phase, message) => {
return ( return (
normalized.includes('complete') || normalized.includes('complete') ||
normalized.includes('successful') normalized.includes('successful') ||
normalized.includes('restarting')
) )
} }
@ -80,6 +91,12 @@ const getInstallStageStatus = (phase, isError, message) => {
return 'pending' return 'pending'
} }
const getRestartStageStatus = (phase, isError, message) => {
if (isError && isInstallComplete(phase, message)) return 'error'
if (isInstallComplete(phase, message)) return 'active'
return 'pending'
}
const getProgressStatus = (stageStatus) => { const getProgressStatus = (stageStatus) => {
if (stageStatus === 'error') return 'exception' if (stageStatus === 'error') return 'exception'
if (stageStatus === 'complete') return 'success' if (stageStatus === 'complete') return 'success'
@ -95,7 +112,7 @@ const UpdateStage = ({ stage, status, percent, detail }) => {
const resolvedStatus = const resolvedStatus =
status !== 'error' && resolvedPercent === 100 ? 'complete' : status status !== 'error' && resolvedPercent === 100 ? 'complete' : status
const color = getStageColor(resolvedStatus, token) const color = getStageColor(resolvedStatus, token)
const showProgress = resolvedStatus === 'active' const showProgress = resolvedStatus === 'active' && stage !== 'restart'
const StatusIcon = const StatusIcon =
resolvedStatus === 'complete' resolvedStatus === 'complete'
@ -126,7 +143,7 @@ const UpdateStage = ({ stage, status, percent, detail }) => {
} }
UpdateStage.propTypes = { UpdateStage.propTypes = {
stage: PropTypes.oneOf(['download', 'install']).isRequired, stage: PropTypes.oneOf(['download', 'install', 'restart']).isRequired,
status: PropTypes.oneOf(['pending', 'active', 'complete', 'error']) status: PropTypes.oneOf(['pending', 'active', 'complete', 'error'])
.isRequired, .isRequired,
percent: PropTypes.number, percent: PropTypes.number,
@ -148,6 +165,7 @@ const AppUpdateProgress = ({ progress, update, onClose }) => {
const downloadStatus = getDownloadStageStatus(phase, isError) const downloadStatus = getDownloadStageStatus(phase, isError)
const installStatus = getInstallStageStatus(phase, isError, message) const installStatus = getInstallStageStatus(phase, isError, message)
const restartStatus = getRestartStageStatus(phase, isError, message)
const downloadPercent = const downloadPercent =
downloadStatus === 'active' ? (phase === 'preparing' ? 0 : percent) : null downloadStatus === 'active' ? (phase === 'preparing' ? 0 : percent) : null
@ -184,6 +202,7 @@ const AppUpdateProgress = ({ progress, update, onClose }) => {
percent={installPercent} percent={installPercent}
detail={installDetail} detail={installDetail}
/> />
<UpdateStage stage='restart' status={restartStatus} />
</Flex> </Flex>
<Modal <Modal

View File

@ -158,7 +158,7 @@ export const launchMacInstaller = (
sendProgress( { sendProgress( {
phase: 'installing', phase: 'installing',
percent: percent ?? 100, percent: percent ?? 100,
message: message || 'Installation complete.' message: message || 'Installation complete. Restarting Farm Control...'
}) })
resolve() resolve()

View File

@ -95,7 +95,7 @@ const parseWindowsInstallerProgress = (output) => {
if (/Installation success or error status:\s*0\b/.test(line)) { if (/Installation success or error status:\s*0\b/.test(line)) {
percent = 100 percent = 100
message = 'Installation complete.' message = 'Installation complete. Restarting Farm Control...'
matchedLines.push('install-success') matchedLines.push('install-success')
} }
} }
@ -427,7 +427,7 @@ export const launchWindowsInstaller = async (
sendProgress( { sendProgress( {
phase: 'installing', phase: 'installing',
percent: percent ?? 100, percent: percent ?? 100,
message: message || 'Installation complete.' message: message || 'Installation complete. Restarting Farm Control...'
}) })
debugLog('installer completed successfully') debugLog('installer completed successfully')