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:
@@ -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>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user