Add a timer component to new query screen (#944)
This commit is contained in:
committed by
Jason Meller
parent
ed1fa22729
commit
3113ae4651
@@ -13,6 +13,7 @@ import queryInterface from 'interfaces/query';
|
||||
import SelectTargetsDropdown from 'components/forms/fields/SelectTargetsDropdown';
|
||||
import targetInterface from 'interfaces/target';
|
||||
import validateQuery from 'components/forms/validators/validate_query';
|
||||
import Timer from 'components/loaders/Timer';
|
||||
|
||||
const baseClass = 'query-form';
|
||||
|
||||
@@ -204,6 +205,8 @@ class QueryForm extends Component {
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}__button-wrap`}>
|
||||
{queryIsRunning && <Timer running={queryIsRunning} />}
|
||||
|
||||
<DropdownButton
|
||||
className={`${baseClass}__save`}
|
||||
options={dropdownBtnOptions}
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
.query-form__stop-query-btn {
|
||||
margin-left: $pad-xsmall;
|
||||
}
|
||||
}
|
||||
|
||||
&__btn-wrapper {
|
||||
margin-top: $base;
|
||||
text-align: right;
|
||||
.kolide-timer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&__save-query-btn,
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { convertSeconds } from './helpers';
|
||||
|
||||
const baseClass = 'kolide-timer';
|
||||
|
||||
class Timer extends Component {
|
||||
static propTypes = {
|
||||
running: PropTypes.bool,
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.state = { totalMilliseconds: 0 };
|
||||
}
|
||||
|
||||
componentWillReceiveProps ({ running }) {
|
||||
const { running: currentRunning } = this.props;
|
||||
|
||||
if (running) {
|
||||
if (!currentRunning) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.play();
|
||||
} else {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
|
||||
play = () => {
|
||||
const { interval, update } = this;
|
||||
|
||||
if (!interval) {
|
||||
this.interval = setInterval(update, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
pause = () => {
|
||||
const { interval } = this;
|
||||
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
this.interval = null;
|
||||
}
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
this.setState({ totalMilliseconds: 0 });
|
||||
}
|
||||
|
||||
update = () => {
|
||||
const { totalMilliseconds } = this.state;
|
||||
|
||||
this.setState({ totalMilliseconds: totalMilliseconds + 1000 });
|
||||
}
|
||||
|
||||
render () {
|
||||
const { totalMilliseconds } = this.state;
|
||||
|
||||
return (
|
||||
<span className={baseClass}>{convertSeconds(totalMilliseconds)}</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Timer;
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import expect, { spyOn, restoreSpies } from 'expect';
|
||||
|
||||
import Timer from './Timer';
|
||||
|
||||
describe('Timer - component', () => {
|
||||
afterEach(restoreSpies);
|
||||
|
||||
it('play() and pause() function', () => {
|
||||
const timer = mount(<Timer running={false} />);
|
||||
|
||||
expect(timer.node.interval).toNotExist();
|
||||
timer.setProps({ running: true });
|
||||
expect(timer.node.interval).toExist();
|
||||
timer.setProps({ running: false });
|
||||
expect(timer.node.interval).toNotExist();
|
||||
});
|
||||
|
||||
it('should reset after pause', () => {
|
||||
const timer = mount(<Timer running={false} />);
|
||||
const spy = spyOn(timer.node, 'reset').andCallThrough();
|
||||
|
||||
timer.setProps({ running: true });
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not reset when stopped', () => {
|
||||
const timer = mount(<Timer running />);
|
||||
const spy = spyOn(timer.node, 'reset').andCallThrough();
|
||||
|
||||
timer.setProps({ running: false });
|
||||
|
||||
expect(spy).toNotHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not reset when it continues', () => {
|
||||
const timer = mount(<Timer running />);
|
||||
const spy = spyOn(timer.node, 'reset').andCallThrough();
|
||||
|
||||
timer.setProps({ running: true });
|
||||
|
||||
expect(spy).toNotHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
.kolide-timer {
|
||||
font-size: 14px;
|
||||
color: $text-medium;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import moment from 'moment';
|
||||
|
||||
export const convertSeconds = (totalMilliSeconds) => {
|
||||
return moment.utc(totalMilliSeconds).format('HH:mm:ss');
|
||||
};
|
||||
|
||||
export default { convertSeconds };
|
||||
@@ -0,0 +1,12 @@
|
||||
import expect from 'expect';
|
||||
|
||||
import { convertSeconds } from './helpers';
|
||||
|
||||
describe('Timer convertSeconds helper', () => {
|
||||
it('converts seconds to hh:mm:ss', () => {
|
||||
expect(convertSeconds(3000)).toEqual('00:00:03');
|
||||
expect(convertSeconds(30000)).toEqual('00:00:30');
|
||||
expect(convertSeconds(300000)).toEqual('00:05:00');
|
||||
expect(convertSeconds(0)).toEqual('00:00:00');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
export default from './Timer';
|
||||
Reference in New Issue
Block a user