qw/timer (#23)

* Rename logo and add 32x32 version

* Set timer icon if a timer is running

* Do not query activities on initialization

* Show timer in bubble if timed activity exists

* Pass timed activity to App

* Code cleanup

* Show timer view and stop timer

* Make hours optional

* Use booked seconds instead of hours

* Add type submit to form button

* Define colors as sass variables⎄

* Style timer view

* Show start timer submit label

* Update view layouts and content

* Update version and changelog

* Dyanically set iframe height

* Reduce h1 font size

* Add svg webpack loader

* Parse empty string (TimeInputParser)

* Forward ref in Popup component

* Start time on current day only, format buttons

* Improve styling

* Set standard height as iframe default height, validate form

* Upgrade packages to supress react warning

* Show activity form in popup after timer was stoped

* Use stop-watch icon in timer view

* Fix empty description

* Close TimerView if timer stopped for current service

* Style timerview

* Improve timer view styling

* qw/setting-time-tracking-hh-mm (#24)

* Format duration depending on settingTimeTrackingHHMM

* Fix formatDuation without second argument

* Fix time format after updating bubble

* Add tests for formatDuration
This commit is contained in:
Manuel Bouza
2019-10-10 14:57:01 +02:00
committed by GitHub
parent 7023b4b482
commit 72626a6c42
38 changed files with 788 additions and 437 deletions

View File

@@ -1,13 +1,22 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
import Select from "components/Select"
import { formatDate } from "utils"
import cn from "classnames"
import StopWatch from "components/shared/StopWatch"
class Form extends Component {
static propTypes = {
changeset: PropTypes.shape({
project: PropTypes.object,
task: PropTypes.object,
assignment_id: PropTypes.number.isRequired,
billable: PropTypes.bool.isRequired,
date: PropTypes.string.isRequired,
task_id: PropTypes.number.isRequired,
description: PropTypes.string,
remote_id: PropTypes.string,
remote_service: PropTypes.string,
remote_url: PropTypes.string,
seconds: PropTypes.number,
hours: PropTypes.string,
}).isRequired,
errors: PropTypes.object,
@@ -20,9 +29,42 @@ class Form extends Component {
inline: true,
}
isValid = () => {
isValid() {
const { changeset } = this.props
return ["assignment_id", "task_id", "hours"].map(prop => changeset[prop]).every(Boolean)
return (
["assignment_id", "task_id"].map(prop => changeset[prop]).every(Boolean) &&
(changeset.date === formatDate(new Date()) || changeset.seconds > 0)
)
}
get isTimerStartable() {
const {
changeset: { seconds, date },
} = this.props
return date === formatDate(new Date()) && seconds === 0
}
buttonStyle() {
const styleMap = {
true: {
border: "none",
borderRadius: "50%",
width: "60px",
height: "60px",
marginTop: "22px",
transition: "all 0.2s ease-in-out",
},
false: {
border: "none",
width: "50px",
height: "36px",
marginTop: "35px",
transition: "all 0.2s ease-in-out",
},
}
return styleMap[this.isTimerStartable]
}
handleTextareaKeyDown = event => {
@@ -96,8 +138,13 @@ class Form extends Component {
) : null}
</div>
<button className="moco-bx-btn" disabled={!this.isValid()}>
OK
<button
type="submit"
className="moco-bx-btn"
disabled={!this.isValid()}
style={this.buttonStyle()}
>
{this.isTimerStartable ? <StopWatch /> : "OK"}
</button>
</form>
)