azure-devops-ui
Version:
React components for building web UI in Azure DevOps
88 lines (87 loc) • 3.84 kB
JavaScript
import "../../CommonImports";
import "../../Core/core.css";
import "./ProgressBar.css";
import * as React from "react";
import { ObservableLike } from '../../Core/Observable';
import { TimerManagement } from '../../Core/TimerManagement';
import { Observer } from '../../Observer';
import { css } from '../../Util';
export class IndeterminateProgressBar extends React.PureComponent {
constructor(props) {
super(props);
this.timerManagement = new TimerManagement();
this.transitionDurations = 350;
// Creates a randomize function that takes in a number and spits out a number +/- the percent passed into the function
this.randomize25 = (amount) => 0.25 * (Math.random() * amount * 2 + (1 - amount));
this.randomize75 = (amount) => 0.75 * (Math.random() * amount * 2 + (1 - amount));
// We never want to hit 100%
this.asymptoticApproach = (x) => 1 - 1 / Math.sqrt(x + 1);
this.done = () => {
this.state.progress !== Infinity && this.setState({ progress: Infinity });
};
this.increment = () => {
this.state.progress !== Infinity && this.setState({ progress: this.state.progress + this.randomize25(1) });
};
this.reset = () => {
this.state.progress !== 0 && this.setState({ progress: 0 });
};
this.shouldRun = () => {
// If we have a value start the progress.
return this.props.loading != undefined;
};
this.updateProgress = (restart) => {
if (restart) {
this.reset();
}
else {
this.done();
}
};
this.state = { progress: 0 };
}
get transitionDuration() {
return this.state.progress ? this.transitionDurations : 0;
}
render() {
return (React.createElement(Observer, { loading: { observableValue: this.props.loading, filter: this.updateProgress } }, () => {
return (React.createElement("span", { className: css(this.props.className, "bolt-progress-bar-container flex-row flex-noshrink flex-grow scroll-hidden") },
React.createElement("span", { className: css(this.props.progressBarClassName, "bolt-progress-bar-bar", this.state.progress === Infinity && "complete"), style: {
transform: `scaleX(${this.asymptoticApproach(this.state.progress)})`
} })));
}));
}
componentDidMount() {
if (this.shouldRun()) {
this.scheduleUpdate(this.increment, 0, false);
}
}
componentDidUpdate(prevProps) {
if (this.shouldRun()) {
if (this.state.progress == Infinity) {
if (this.props.loadingAnimationComplete) {
this.timerManagement.setTimeout(() => {
this.props.loadingAnimationComplete && this.props.loadingAnimationComplete();
}, this.transitionDuration);
}
}
else {
this.scheduleUpdate(this.increment, this.transitionDuration, false);
}
}
// Reset progress if the loading is undefined, otherwise complete the progress bar if loading is false.
if (this.props.loading === undefined) {
this.reset();
}
else if ((prevProps.loading === undefined || ObservableLike.getValue(prevProps.loading)) && !ObservableLike.getValue(this.props.loading)) {
this.done();
}
}
componentWillUnmount() {
this.timerManagement.dispose();
}
scheduleUpdate(updateFn, delay, required) {
this.timerManagement.setTimeout(() => {
updateFn();
}, delay);
}
}