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

@@ -3,6 +3,7 @@ import PropTypes from "prop-types"
import Spinner from "components/Spinner"
import Form from "components/Form"
import Calendar from "components/Calendar"
import TimerView from "components/App/TimerView"
import { observable, computed } from "mobx"
import { Observer, observer } from "mobx-react"
import { Spring, animated, config } from "react-spring/renderprops"
@@ -41,9 +42,15 @@ class App extends Component {
activities: PropTypes.array,
schedules: PropTypes.array,
projects: PropTypes.array,
timedActivity: PropTypes.shape({
customer_name: PropTypes.string.isRequired,
assignment_name: PropTypes.string.isRequired,
task_name: PropTypes.string.isRequired,
timer_started_at: PropTypes.string.isRequired,
seconds: PropTypes.number.isRequired,
}),
lastProjectId: PropTypes.number,
lastTaskId: PropTypes.number,
roundTimeEntries: PropTypes.bool,
fromDate: PropTypes.string,
toDate: PropTypes.string,
errorType: PropTypes.string,
@@ -54,7 +61,6 @@ class App extends Component {
activities: [],
schedules: [],
projects: [],
roundTimeEntries: false,
}
@observable changeset = {}
@@ -94,8 +100,8 @@ class App extends Component {
task_id: this.task?.value,
billable: this.billable,
hours: "",
seconds: this.changeset.hours && new TimeInputParser(this.changeset.hours).parseSeconds(),
description: service?.description,
seconds: new TimeInputParser(this.changeset.hours).parseSeconds(),
description: service?.description || "",
tag: "",
}
@@ -104,6 +110,7 @@ class App extends Component {
componentDidMount() {
window.addEventListener("keydown", this.handleKeyDown)
parent.postMessage({ __mocoBX: { iFrameHeight: window.document.body.scrollHeight } }, "*")
chrome.runtime.onMessage.addListener(this.handleSetFormErrors)
}
@@ -130,6 +137,15 @@ class App extends Component {
this.changeset.date = formatDate(date)
}
handleStopTimer = timedActivity => {
const { service } = this.props
chrome.runtime.sendMessage({
type: "stopTimer",
payload: { timedActivity, service },
})
}
handleSubmit = event => {
event.preventDefault()
const { service } = this.props
@@ -161,6 +177,7 @@ class App extends Component {
loading,
subdomain,
projects,
timedActivity,
activities,
schedules,
fromDate,
@@ -191,25 +208,29 @@ class App extends Component {
<animated.div className="moco-bx-app-container" style={props}>
<Header subdomain={subdomain} />
<Observer>
{() => (
<>
<Calendar
fromDate={parseISO(fromDate)}
toDate={parseISO(toDate)}
activities={activities}
schedules={schedules}
selectedDate={new Date(this.changesetWithDefaults.date)}
onChange={this.handleSelectDate}
/>
<Form
changeset={this.changesetWithDefaults}
projects={projects}
errors={this.formErrors}
onChange={this.handleChange}
onSubmit={this.handleSubmit}
/>
</>
)}
{() =>
timedActivity ? (
<TimerView timedActivity={timedActivity} onStopTimer={this.handleStopTimer} />
) : (
<>
<Calendar
fromDate={parseISO(fromDate)}
toDate={parseISO(toDate)}
activities={activities}
schedules={schedules}
selectedDate={new Date(this.changesetWithDefaults.date)}
onChange={this.handleSelectDate}
/>
<Form
changeset={this.changesetWithDefaults}
projects={projects}
errors={this.formErrors}
onChange={this.handleChange}
onSubmit={this.handleSubmit}
/>
</>
)
}
</Observer>
</animated.div>
)}