Skip to content

Commit 7a25679

Browse files
authored
feat: add estimated time for query execution (pinterest#1158)
* feat: add estimated time for query execution * resolved comments
1 parent dd35c4e commit 7a25679

2 files changed

Lines changed: 45 additions & 11 deletions

File tree

‎querybook/webapp/components/DataDocStatementExecution/DataDocStatementExecution.scss‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@
2828
.statement-execution-progress-wrapper {
2929
margin-bottom: 10px;
3030

31-
progress {
32-
width: 40%;
33-
display: inline-block;
31+
.ProgressBar {
32+
flex: 1;
33+
}
34+
.progress-text {
35+
flex: 1;
3436
}
3537
}
3638
}

‎querybook/webapp/components/DataDocStatementExecution/DataDocStatementExecution.tsx‎

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import moment from 'moment';
12
import React, { useCallback, useEffect, useMemo, useState } from 'react';
23
import { useDispatch, useSelector } from 'react-redux';
34

@@ -8,6 +9,7 @@ import {
89
import { StatementExecutionDefaultResultSize } from 'const/queryResultLimit';
910
import { useToggleState } from 'hooks/useToggleState';
1011
import { sanitizeAndExtraMarkdown } from 'lib/markdown';
12+
import { formatDuration } from 'lib/utils/datetime';
1113
import { fetchResult } from 'redux/queryExecutions/action';
1214
import { IStoreState } from 'redux/store/types';
1315
import { Icon } from 'ui/Icon/Icon';
@@ -133,21 +135,51 @@ export const DataDocStatementExecution: React.FC<IProps> = ({
133135
<span className="statement-status-label">Initializing</span>
134136
);
135137
} 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">
143172
<ProgressBar
144173
value={percentComplete}
145-
showValue
146174
isSmall
147175
type="success"
148176
/>
177+
<AccentText className="progress-text">
178+
{estimatedTimeText}
179+
</AccentText>
149180
</div>
150181
);
182+
151183
contentDOM = (
152184
<div className="statement-execution-text-container">
153185
<div className="statement-execution-text-title">

0 commit comments

Comments
 (0)