|
| 1 | +import moment from 'moment'; |
1 | 2 | import React, { useCallback, useEffect, useMemo, useState } from 'react'; |
2 | 3 | import { useDispatch, useSelector } from 'react-redux'; |
3 | 4 |
|
|
8 | 9 | import { StatementExecutionDefaultResultSize } from 'const/queryResultLimit'; |
9 | 10 | import { useToggleState } from 'hooks/useToggleState'; |
10 | 11 | import { sanitizeAndExtraMarkdown } from 'lib/markdown'; |
| 12 | +import { formatDuration } from 'lib/utils/datetime'; |
11 | 13 | import { fetchResult } from 'redux/queryExecutions/action'; |
12 | 14 | import { IStoreState } from 'redux/store/types'; |
13 | 15 | import { Icon } from 'ui/Icon/Icon'; |
@@ -133,21 +135,51 @@ export const DataDocStatementExecution: React.FC<IProps> = ({ |
133 | 135 | <span className="statement-status-label">Initializing</span> |
134 | 136 | ); |
135 | 137 | } else if (status === StatementExecutionStatus.RUNNING) { |
136 | | - const percentComplete = statementExecution.percent_complete; |
137 | | - const statusLabel = |
138 | | - status === StatementExecutionStatus.RUNNING ? ( |
139 | | - <span className="statement-status-label">Running</span> |
140 | | - ) : null; |
141 | | - const progressBar = status === StatementExecutionStatus.RUNNING && ( |
142 | | - <div className="statement-execution-progress-wrapper"> |
| 138 | + const { created_at: createdAt } = statementExecution; |
| 139 | + const percentComplete = statementExecution.percent_complete ?? 0; |
| 140 | + |
| 141 | + const statusLabel = ( |
| 142 | + <span className="statement-status-label">Running</span> |
| 143 | + ); |
| 144 | + |
| 145 | + const estimatedTimeText = (() => { |
| 146 | + let progressMessage = `${Math.floor(percentComplete || 0)}%`; |
| 147 | + |
| 148 | + if ( |
| 149 | + percentComplete == null || |
| 150 | + percentComplete === 0 || |
| 151 | + percentComplete === 100 |
| 152 | + ) { |
| 153 | + return progressMessage; |
| 154 | + } |
| 155 | + |
| 156 | + const secondsPassedSinceStart = |
| 157 | + new Date().getTime() / 1000 - createdAt; |
| 158 | + const secondsRemainToComplete = |
| 159 | + secondsPassedSinceStart / (percentComplete / 100) - |
| 160 | + secondsPassedSinceStart; |
| 161 | + const durationToComplete = formatDuration( |
| 162 | + moment.duration(secondsRemainToComplete, 'seconds') |
| 163 | + ); |
| 164 | + |
| 165 | + progressMessage += ` (${durationToComplete} Remaining)`; |
| 166 | + |
| 167 | + return progressMessage; |
| 168 | + })(); |
| 169 | + |
| 170 | + const progressBar = ( |
| 171 | + <div className="statement-execution-progress-wrapper flex-row"> |
143 | 172 | <ProgressBar |
144 | 173 | value={percentComplete} |
145 | | - showValue |
146 | 174 | isSmall |
147 | 175 | type="success" |
148 | 176 | /> |
| 177 | + <AccentText className="progress-text"> |
| 178 | + {estimatedTimeText} |
| 179 | + </AccentText> |
149 | 180 | </div> |
150 | 181 | ); |
| 182 | + |
151 | 183 | contentDOM = ( |
152 | 184 | <div className="statement-execution-text-container"> |
153 | 185 | <div className="statement-execution-text-title"> |
|
0 commit comments