mirror of
https://github.com/rickbarrette/stopwatch.git
synced 2026-04-02 17:51:59 -04:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 60dfa7ae4a | |||
| 490fbd476d | |||
|
|
527f72f93b | ||
|
|
8e34eb627c | ||
|
|
3c709b1329 | ||
|
|
776c0cd823 |
7
.github/workflows/redmine.yml
vendored
7
.github/workflows/redmine.yml
vendored
@@ -14,11 +14,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
redmine:
|
||||
- '5.0'
|
||||
- '5.1'
|
||||
- '6.0'
|
||||
- '6.1'
|
||||
ruby:
|
||||
- '3.0'
|
||||
- '3.1'
|
||||
- '3.3'
|
||||
database:
|
||||
- postgresql
|
||||
- mysql
|
||||
|
||||
@@ -2,3 +2,8 @@
|
||||
<label for="settings_default_activity"><%= t '.label_default_activity' %> </label>
|
||||
<%= select_tag 'settings[default_activity]', options_from_collection_for_select( [['always_ask', t('.label_always_ask')], ['system', t('.label_system')]] + TimeEntryActivity.system.active.to_a.pluck(:id, :name), :first, :last, Stopwatch.settings['default_activity'] ) %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label for="settings_highlighted_links"><%= t '.label_highlighted_links' %> </label>
|
||||
<%= check_box_tag 'settings[highlighted_links]', 1, Setting.plugin_stopwatch[:highlighted_links] %>
|
||||
</p>
|
||||
@@ -1,2 +1,3 @@
|
||||
<%= javascript_include_tag "stopwatch", plugin: "stopwatch" %>
|
||||
<%= stylesheet_link_tag "stopwatch", plugin: "stopwatch" %>
|
||||
<%= stylesheet_link_tag "highlighted_links", plugin: "stopwatch" if Stopwatch.highlighted_links %>
|
||||
@@ -2,9 +2,9 @@
|
||||
<% time_entry = @time_entries.first %>
|
||||
<li>
|
||||
<% if User.current.is_running_timer? time_entry %>
|
||||
<%= context_menu_link l(:label_stopwatch_stop), stop_stopwatch_timer_path(time_entry, context: '1'), class: 'icon icon-time', remote: true, method: :put %>
|
||||
<%= context_menu_link sprite_icon(:time, l(:label_stopwatch_stop)), stop_stopwatch_timer_path(time_entry, context: '1'), class: 'icon', remote: true, method: :put %>
|
||||
<% else %>
|
||||
<%= context_menu_link l(:label_stopwatch_start), start_stopwatch_timer_path(time_entry, context: '1'), class: 'icon icon-time', remote: true, method: :put %>
|
||||
<%= context_menu_link sprite_icon(:time, l(:label_stopwatch_start)), start_stopwatch_timer_path(time_entry, context: '1'), class: 'icon', remote: true, method: :put %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
contextMenuHide();
|
||||
window.stopwatch.updateStartStopLink(
|
||||
'#stopwatch_stop_timer_<%= @issue.id %>',
|
||||
'<%= j Stopwatch::IssueLinks.new(@issue).start_timer %>'
|
||||
'<%= j Stopwatch::IssueLinks.new(@issue, self).start_timer %>'
|
||||
);
|
||||
window.stopwatch.timerStopped();
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
<td class="hours"><%= html_hours(format_hours(entry.hours)) %></td>
|
||||
<td class="buttons">
|
||||
<% if running %>
|
||||
<%= link_to t(:label_stopwatch_stop), stop_stopwatch_timer_path(entry), remote: true, class: "icon-only icon-time", method: :put %>
|
||||
<%= link_to sprite_icon(:time, t(:label_stopwatch_stop)), stop_stopwatch_timer_path(entry), remote: true, class: "icon-only", method: :put %>
|
||||
<% else %>
|
||||
<%= link_to t(:label_stopwatch_start), start_stopwatch_timer_path(entry), remote: true, class: "icon-only icon-time", method: :put %>
|
||||
<%= link_to sprite_icon(:time, t(:label_stopwatch_start)), start_stopwatch_timer_path(entry), remote: true, class: "icon-only", method: :put %>
|
||||
<% end %>
|
||||
<%= link_to l(:button_edit), edit_stopwatch_timer_path(entry), remote: true, class: "icon-only icon-edit" if entry.editable_by? User.current %>
|
||||
<%= link_to sprite_icon(:edit, l(:button_edit)), edit_stopwatch_timer_path(entry), remote: true, class: "icon-only" if entry.editable_by? User.current %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end -%>
|
||||
|
||||
@@ -74,7 +74,7 @@ window.initStopwatch = function(config){
|
||||
$('a.stopwatch_issue_timer').each(function(){
|
||||
var a = $(this);
|
||||
a.attr('href', a.attr('href').replace(/stop$/, 'start'));
|
||||
a.text(locales.startTimer);
|
||||
a.find('span').text(locales.startTimer);
|
||||
});
|
||||
},
|
||||
timerStarted: function(data){
|
||||
@@ -94,10 +94,10 @@ window.initStopwatch = function(config){
|
||||
if(data.issue_id) {
|
||||
if(a.data('issueId') == data.issue_id) {
|
||||
a.attr('href', href.replace(/start$/, 'stop'));
|
||||
a.text(locales.stopTimer);
|
||||
a.find('span').text(locales.stopTimer);
|
||||
} else {
|
||||
a.attr('href', href.replace(/stop$/, 'start'));
|
||||
a.text(locales.startTimer);
|
||||
a.find('span').text(locales.startTimer);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
22
assets/stylesheets/highlighted_links.css
Normal file
22
assets/stylesheets/highlighted_links.css
Normal file
@@ -0,0 +1,22 @@
|
||||
a.stopwatch_issue_timer[href*="stop"] {
|
||||
color: red;
|
||||
}
|
||||
|
||||
a.stopwatch_issue_timer[href*="start"] {
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
/* Mobile only */
|
||||
@media (max-width: 899px) {
|
||||
a.stopwatch_issue_timer[href*="stop"] {
|
||||
color: red;
|
||||
background-color: #ffe5e5;
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
a.stopwatch_issue_timer[href*="start"] {
|
||||
color: limegreen;
|
||||
background-color: #eaffea;
|
||||
border: 1px solid limegreen;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ en:
|
||||
settings:
|
||||
label_always_ask: 'Always ask'
|
||||
label_default_activity: 'Default activity for "Start tracking"'
|
||||
label_highlighted_links: "Color-code Start/Stop"
|
||||
label_system: 'Use system default'
|
||||
stopwatch_timers:
|
||||
entries_list:
|
||||
|
||||
4
init.rb
4
init.rb
@@ -3,9 +3,9 @@ Redmine::Plugin.register :stopwatch do
|
||||
author 'Jens Krämer'
|
||||
author_url 'https://jkraemer.net/'
|
||||
description "Start/stop timer and quick access to today's time bookings for Redmine"
|
||||
version '1.0.0'
|
||||
version '1.1.0'
|
||||
|
||||
requires_redmine version_or_higher: '5.0.0'
|
||||
requires_redmine version_or_higher: '6.0.0'
|
||||
settings default: {
|
||||
'default_activity' => 'always_ask',
|
||||
}, partial: 'stopwatch/settings'
|
||||
|
||||
@@ -9,7 +9,6 @@ module Stopwatch
|
||||
Stopwatch::Hooks # just load it
|
||||
end
|
||||
|
||||
|
||||
def self.settings
|
||||
Setting.plugin_stopwatch
|
||||
end
|
||||
@@ -42,4 +41,8 @@ module Stopwatch
|
||||
return activities.detect{ |a| a == default || a.parent == default }
|
||||
end
|
||||
end
|
||||
|
||||
def self.highlighted_links
|
||||
settings[:highlighted_links]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,9 +10,9 @@ module Stopwatch
|
||||
User.current.allowed_to?(:log_time, issue.project)
|
||||
t = Stopwatch::IssueTimer.new(issue: issue)
|
||||
if t.running?
|
||||
link << IssueLinks.new(issue).stop_timer
|
||||
link << IssueLinks.new(issue, self).stop_timer
|
||||
else
|
||||
link << IssueLinks.new(issue).start_timer
|
||||
link << IssueLinks.new(issue, self).start_timer
|
||||
end
|
||||
end
|
||||
super + content_tag(:li, link.html_safe)
|
||||
@@ -26,4 +26,3 @@ module Stopwatch
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
module Stopwatch
|
||||
class IssueLinks < Struct.new(:issue)
|
||||
include ActionView::Helpers::UrlHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
|
||||
class IssueLinks < Struct.new(:issue, :context)
|
||||
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')
|
||||
context.link_to(
|
||||
context.sprite_icon(:time, I18n.t(:label_stopwatch_start)),
|
||||
context.start_issue_timer_path(issue),
|
||||
class: 'icon 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')
|
||||
|
||||
context.link_to(
|
||||
context.sprite_icon(:time, I18n.t(:label_stopwatch_stop)),
|
||||
context.stop_issue_timer_path(issue),
|
||||
class: 'icon stopwatch_issue_timer',
|
||||
data: { issue_id: issue.id },
|
||||
remote: true,
|
||||
method: 'post'
|
||||
)
|
||||
end
|
||||
|
||||
# to make route helpers happy
|
||||
|
||||
@@ -8,9 +8,9 @@ module Stopwatch
|
||||
if User.current.allowed_to?(:log_time, issue.project)
|
||||
t = Stopwatch::IssueTimer.new(issue: issue)
|
||||
if t.running?
|
||||
link << IssueLinks.new(issue).stop_timer
|
||||
link << IssueLinks.new(issue, self).stop_timer
|
||||
else
|
||||
link << IssueLinks.new(issue).start_timer
|
||||
link << IssueLinks.new(issue, self).start_timer
|
||||
end
|
||||
end
|
||||
link.html_safe + super
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
require File.expand_path('../test_helper', __dir__)
|
||||
|
||||
class TicketTimerTest < Redmine::IntegrationTest
|
||||
include ActiveJob::TestHelper
|
||||
@@ -30,6 +30,7 @@ class TicketTimerTest < Redmine::IntegrationTest
|
||||
assert_not_running
|
||||
|
||||
get "/issues/1"
|
||||
assert_response :success
|
||||
assert_select "div.contextual a", text: /start tracking/i
|
||||
assert_no_difference ->{TimeEntry.count} do
|
||||
post "/issues/1/timer/start", xhr: true
|
||||
@@ -77,7 +78,7 @@ class TicketTimerTest < Redmine::IntegrationTest
|
||||
TimeEntry.delete_all
|
||||
assert_no_difference ->{TimeEntry.count} do
|
||||
post "/issues/1/timer/start", xhr: true
|
||||
assert_response 200
|
||||
assert_response :ok
|
||||
end
|
||||
end
|
||||
|
||||
@@ -86,7 +87,7 @@ class TicketTimerTest < Redmine::IntegrationTest
|
||||
TimeEntry.delete_all
|
||||
with_settings plugin_stopwatch: { 'default_activity' => 'system'} do
|
||||
post "/issues/1/timer/start", xhr: true
|
||||
assert_response 201
|
||||
assert_response :created
|
||||
end
|
||||
assert te = TimeEntry.last
|
||||
assert_equal 1, te.issue_id
|
||||
@@ -98,18 +99,17 @@ class TicketTimerTest < Redmine::IntegrationTest
|
||||
TimeEntry.delete_all
|
||||
with_settings plugin_stopwatch: { 'default_activity' => '9'} do
|
||||
post "/issues/1/timer/start", xhr: true
|
||||
assert_response 201
|
||||
assert_response :created
|
||||
end
|
||||
assert te = TimeEntry.last
|
||||
assert_equal 1, te.issue_id
|
||||
assert_equal 9, te.activity_id
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def assert_not_running
|
||||
refute Stopwatch::Timer.new(User.find(@user.id)).running?
|
||||
assert_not Stopwatch::Timer.new(User.find(@user.id)).running?
|
||||
end
|
||||
|
||||
def assert_running
|
||||
|
||||
Reference in New Issue
Block a user