'Start/Stop tracking' on issues#show

This commit is contained in:
Jens Kraemer
2021-10-05 05:27:35 +08:00
parent bd6711a59f
commit 033e1739d2
22 changed files with 375 additions and 28 deletions

View File

@@ -0,0 +1,29 @@
module Stopwatch
class IssueLinks < Struct.new(:issue)
include ActionView::Helpers::UrlHelper
include Rails.application.routes.url_helpers
def start_timer
link_to(I18n.t(:label_stopwatch_start),
start_issue_timer_path(issue),
class: 'icon icon-time stopwatch_issue_timer',
data: { issue_id: issue.id },
remote: true,
method: 'post')
end
def stop_timer
link_to(I18n.t(:label_stopwatch_stop),
stop_issue_timer_path(issue),
class: 'icon icon-time stopwatch_issue_timer',
data: { issue_id: issue.id },
remote: true,
method: 'post')
end
# to make route helpers happy
def controller; nil end
end
end

View File

@@ -0,0 +1,18 @@
module Stopwatch
class IssueTimer
def initialize(issue:, user: User.current)
@issue = issue
@user = user
end
def running?
running_time_entry.present?
end
def running_time_entry
@running_time_entry ||= @issue.time_entries.find_by_id(@user.running_time_entry_id)
end
end
end

View File

@@ -0,0 +1,26 @@
# frozen_string_literal: true
module Stopwatch
module IssuesControllerPatch
module Helper
def watcher_link(issue, user)
link = +''
if User.current.allowed_to?(:log_time, issue.project)
t = Stopwatch::IssueTimer.new(issue: issue)
if t.running?
link << IssueLinks.new(issue).stop_timer
else
link << IssueLinks.new(issue).start_timer
end
end
link.html_safe + super
end
end
def self.apply
IssuesController.class_eval do
helper Helper
end
end
end
end

View File

@@ -1,7 +1,7 @@
module Stopwatch
class StartTimer
Result = ImmutableStruct.new(:success?, :error)
Result = ImmutableStruct.new(:success?, :error, :started)
def initialize(time_entry, user: User.current)
@time_entry = time_entry
@@ -13,7 +13,6 @@ module Stopwatch
return Result.new(error: :unauthorized)
end
StopTimer.new(user: @user).call
@time_entry.hours = 0 if @time_entry.hours.nil?
# we want to start tracking time if this is an existing time entry, or a
@@ -21,9 +20,13 @@ module Stopwatch
# new entries with hours > 0 are just saved as is.
start_timer = !@time_entry.new_record? || @time_entry.hours == 0
# stop currently running timer, but only when there is a chance for us
# to succeed creating the new one.
StopTimer.new(user: @user).call if @time_entry.valid?
if @time_entry.save
start_new_timer if start_timer
return Result.new(success: true)
return Result.new(success: true, started: start_timer)
else
Rails.logger.error("could not save time entry: \n#{@time_entry.errors.inspect}")
return Result.new(error: :invalid)

View File

@@ -65,7 +65,8 @@ module Stopwatch
time_entry_id: time_entry_id,
time_spent: formatter.format_hours,
html_time_spent: formatter.html_hours,
running: running?
running: running?,
issue_id: time_entry&.issue_id
}.to_json
end

View File

@@ -17,5 +17,10 @@ module Stopwatch
timer = Stopwatch::Timer.new(self)
timer.time_entry_id if timer.running?
end
def todays_time_entry_for(issue)
TimeEntry.order(created_on: :desc).
find_or_initialize_by(user: self, issue: issue, spent_on: today)
end
end
end