├── app
├── helpers
│ └── worktimelog_helper.rb
├── views
│ ├── worktimelog
│ │ ├── _widget_timer.html.erb
│ │ ├── index.html.erb
│ │ ├── snapup.html.erb
│ │ ├── intercept.html.erb
│ │ ├── take_over.html.erb
│ │ ├── archive.html.erb
│ │ ├── summary.html.erb
│ │ ├── worklog.html.erb
│ │ ├── _sentinel.html.erb
│ │ ├── _widget_issue_toolbar.html.erb
│ │ ├── issue_summary.html.erb
│ │ ├── user_summary.html.erb
│ │ └── project_summary.html.erb
│ ├── stopwatch
│ │ ├── timer.html.erb
│ │ ├── timer.json.erb
│ │ └── _widget_timer.html.erb
│ └── settings
│ │ ├── _worktime_license.html.erb
│ │ ├── _worktime.html.erb
│ │ ├── _worktime_credits.html.erb
│ │ ├── _worktime_about.html.erb
│ │ └── _worktime_general.html.erb
├── models
│ └── worktimelog.rb
└── controllers
│ ├── stopwatch_controller.rb
│ └── worktimelog_controller.rb
├── assets
├── scss
│ ├── _settings.scss
│ ├── redmine_worktime_log.scss
│ ├── _mixins.scss
│ ├── _table.scss
│ ├── _main.scss
│ ├── _widget.scss
│ └── vendor
│ │ └── chosen.scss
├── images
│ ├── chosen-sprite.png
│ └── chosen-sprite@2x.png
├── javascripts
│ ├── timer.js
│ └── vendor
│ │ └── jquery
│ │ ├── jquery.stopwatch.js
│ │ └── jquery.chosen.js
└── stylesheets
│ ├── redmine_worktime_log.css.map
│ └── redmine_worktime_log.css
├── test
├── test_helper.rb
├── unit
│ └── worklog_test.rb
└── functional
│ └── worklog_controller_test.rb
├── lib
├── redmine_worktime
│ ├── hooks
│ │ ├── view_layout_hook.rb
│ │ ├── view_issue_hook.rb
│ │ └── view_sidebar_hook.rb
│ ├── helpers
│ │ └── worktime_helper.rb
│ └── patches
│ │ └── view_sidebar_patch.rb
└── redmine_worktime.rb
├── db
└── migrate
│ └── 001_create_worktimelogs.rb
├── config
├── routes.rb
└── locales
│ ├── en.yml
│ ├── uk.yml
│ ├── fr.yml
│ └── ru.yml
├── init.rb
├── README.rdoc
└── README.md
/app/helpers/worktimelog_helper.rb:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/scss/_settings.scss:
--------------------------------------------------------------------------------
1 | $span-margin: 1.2rem;
--------------------------------------------------------------------------------
/app/views/worktimelog/_widget_timer.html.erb:
--------------------------------------------------------------------------------
1 | SILENCE IS GOLD
--------------------------------------------------------------------------------
/app/views/worktimelog/index.html.erb:
--------------------------------------------------------------------------------
1 |
Silence is gold
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/snapup.html.erb:
--------------------------------------------------------------------------------
1 | Silence is gold
2 |
--------------------------------------------------------------------------------
/app/views/stopwatch/timer.html.erb:
--------------------------------------------------------------------------------
1 | WorklogController#timer
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/intercept.html.erb:
--------------------------------------------------------------------------------
1 | Silence is gold
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/take_over.html.erb:
--------------------------------------------------------------------------------
1 | Silence is gold
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/archive.html.erb:
--------------------------------------------------------------------------------
1 | WorklogController#archive
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/summary.html.erb:
--------------------------------------------------------------------------------
1 | WorklogController#summary
2 |
--------------------------------------------------------------------------------
/app/views/worktimelog/worklog.html.erb:
--------------------------------------------------------------------------------
1 | WorklogController#worklog
2 |
--------------------------------------------------------------------------------
/app/views/stopwatch/timer.json.erb:
--------------------------------------------------------------------------------
1 | {success: <%= @success %>, params: '<%= params %>'}
--------------------------------------------------------------------------------
/assets/images/chosen-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/themondays/redmine_worktime_log/HEAD/assets/images/chosen-sprite.png
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Load the Redmine helper
2 | require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper')
3 |
--------------------------------------------------------------------------------
/assets/images/chosen-sprite@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/themondays/redmine_worktime_log/HEAD/assets/images/chosen-sprite@2x.png
--------------------------------------------------------------------------------
/app/views/worktimelog/_sentinel.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :header_tags do %>
2 | <%= javascript_include_tag 'vendor/jquery/jquery.chosen.js', 'vendor/jquery/jquery.stopwatch.js', 'timer', :plugin => 'redmine_worktime_log' %>
3 | <% end %>
4 |
--------------------------------------------------------------------------------
/test/unit/worklog_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../test_helper', __FILE__)
2 |
3 | class WorklogTest < ActiveSupport::TestCase
4 |
5 | # Replace this with your real tests.
6 | def test_truth
7 | assert true
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/redmine_worktime/hooks/view_layout_hook.rb:
--------------------------------------------------------------------------------
1 | module RedmineWorktime
2 | module Hooks
3 | class ViewLayoutHook < Redmine::Hook::ViewListener
4 | render_on :view_layouts_base_html_head, :partial => "worktimelog/sentinel"
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/functional/worklog_controller_test.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../../test_helper', __FILE__)
2 |
3 | class WorklogControllerTest < ActionController::TestCase
4 | # Replace this with your real tests.
5 | def test_truth
6 | assert true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/assets/scss/redmine_worktime_log.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Redmine Worktime Log Plugin
3 | * @author: Jared Denison
4 | */
5 |
6 | @import "_settings";
7 | @import "_mixins";
8 | @import "_widget";
9 | @import "_main";
10 | @import "_table";
11 | @import "vendor/chosen.scss";
--------------------------------------------------------------------------------
/db/migrate/001_create_worktimelogs.rb:
--------------------------------------------------------------------------------
1 | class CreateWorktimelogs < ActiveRecord::Migration
2 | def change
3 | create_table :worktimelogs do |t|
4 | t.integer :issue_id
5 | t.integer :user_id
6 | t.timestamp :started
7 | t.timestamp :finished
8 | t.integer :total
9 | t.integer :flag
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/app/views/settings/_worktime_license.html.erb:
--------------------------------------------------------------------------------
1 | <% html_title l(:label_worktime_license) %>
2 | <%= l(:label_worktime_license) %>
3 |
4 | This plugin is available under
CC-BY 3.0
5 |
6 |
7 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
8 |
--------------------------------------------------------------------------------
/lib/redmine_worktime/helpers/worktime_helper.rb:
--------------------------------------------------------------------------------
1 | module RedmineWorktime
2 | module Helper
3 | def time_to_sec(t)
4 | s = t.split(":").map{|s| s.to_i}
5 | return (s[0]*3600) + (s[1]*60) + s[2]
6 | end
7 | # helper_method :to_time
8 | def to_time(t)
9 | seconds = t % 60
10 | minutes = (t / 60) % 60
11 | hours = t / (60 * 60)
12 | return format("%02d:%02d:%02d", hours, minutes, seconds)
13 | end
14 | end
15 | end
16 |
17 | ActionView::Base.send :include, RedmineWorktime::Helper
--------------------------------------------------------------------------------
/app/views/settings/_worktime.html.erb:
--------------------------------------------------------------------------------
1 | <% worktime_tabs = [
2 | {:name => 'general', :partial => 'settings/worktime_general', :label => :label_worktime_general},
3 | {:name => 'about', :partial => 'settings/worktime_about', :label => :label_worktime_about},
4 | {:name => 'credits', :partial => 'settings/worktime_credits', :label => :label_worktime_credits},
5 | {:name => 'license', :partial => 'settings/worktime_license', :label => :label_worktime_license}
6 | ] %>
7 |
8 | <%= render_tabs worktime_tabs %>
9 |
10 | <% html_title l(:label_worktime) %>
11 |
12 |
--------------------------------------------------------------------------------
/app/views/settings/_worktime_credits.html.erb:
--------------------------------------------------------------------------------
1 | <% html_title l(:label_worktime_credits) %>
2 | <%= l(:label_worktime_credits) %>
3 | Additional thanks to:
4 |
5 | Stopwatch timer originally from CakePHP app called project-manager - https://github.com/websightdesigns/project-manager/blob/master/README.md
6 | jQuery.choosen - http://harvesthq.github.io/chosen/ by Harvest (http://www.getharvest.com/)
7 |
8 |
9 |
10 | If you found something unappropriate or I forgot mention someone please touch me and we fix it.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/assets/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | @mixin universe($property,$value) {
2 | -webkit-#{$property}: #{$value};
3 | -moz-#{$property}: #{$value};
4 | -ms-#{$property}: #{$value};
5 | -o-#{$property}: #{$value};
6 | #{$property}: #{$value};
7 | }
8 | @mixin box-shadow($str) {
9 | @include universe(box-shadow, $str);
10 | }
11 | @mixin box-sizing($str) {
12 | @include universe(box-sizing, $str);
13 | }
14 | @mixin _border-box() {
15 | @include box-sizing(border-box);
16 | }
17 | @mixin -content-box {
18 | background:#fff;
19 | margin: 0;
20 | border: none;
21 | margin-bottom: $span-margin;
22 | padding: $span-margin;
23 | }
--------------------------------------------------------------------------------
/app/models/worktimelog.rb:
--------------------------------------------------------------------------------
1 | class Worktimelog < ActiveRecord::Base
2 | unloadable
3 | has_one :issue
4 | belongs_to :issue
5 | belongs_to :project
6 | belongs_to :user
7 | end
8 | class Issue < ActiveRecord::Base
9 | has_one :project
10 | belongs_to :project
11 | end
12 |
13 | class Project < ActiveRecord::Base
14 | belongs_to :issue
15 | end
16 |
17 | class ContactsIssue < ActiveRecord::Base
18 | self.primary_key = "issue_id"
19 | self.inheritance_column = "issue_id"
20 | has_one :issue
21 | belongs_to :contact
22 | end
23 |
24 | class Contacts < ActiveRecord::Base
25 | belongs_to :contacts_issue
26 | end
27 |
--------------------------------------------------------------------------------
/assets/scss/_table.scss:
--------------------------------------------------------------------------------
1 | table.worktime-log-table {
2 | th .day-total {
3 | font-weight: 300;
4 | font-size: 12px;
5 | border-radius: 3px;
6 | background-color: #ecf0f1;
7 | color: #7f8c8d;
8 | padding: 2px 3px;
9 | position: relative;
10 | display: inline-block;
11 | }
12 | th .day-total::before {
13 | content: '';
14 | border: 5px transparent solid;
15 | width: 0;
16 | height: 0;
17 | display: block;
18 | padding: 0;
19 | margin: 0;
20 | top: -9px;
21 | margin-left: -5px;
22 | z-index: 2;
23 | left: 50%;
24 | line-height: 0;
25 | position: absolute;
26 | background-color: transparent;
27 | border-bottom-color: #ecf0f1;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/redmine_worktime.rb:
--------------------------------------------------------------------------------
1 | # Redmine Worktime Log Hooks
2 | # require 'redmine_worktime/patches/project_patch'
3 | require 'redmine_worktime/helpers/worktime_helper'
4 | require 'redmine_worktime/hooks/view_layout_hook'
5 | require 'redmine_worktime/hooks/view_sidebar_hook'
6 | if !!Setting.plugin_redmine_worktime_log[:show_toolbar_in_issue]
7 | require 'redmine_worktime/hooks/view_issue_hook'
8 | end
9 |
10 | module RedmineWorktime
11 | module Hooks
12 | class ViewLayoutsBaseHook < Redmine::Hook::ViewListener
13 | #<%= javascript_include_tag 'jquery.stopwatch.js', 'timer', :plugin => 'redmine_worktime_log' %>
14 | render_on :view_layouts_base_html_head, :inline => "<%= stylesheet_link_tag :redmine_worktime_log, :plugin => 'redmine_worktime_log' %>"
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | # Plugin"s routes
2 | get "worktime/stopwatch", :to => "stopwatch#timer"
3 | get "worktime/stopwatch/:id", :to => "stopwatch#timer"
4 | post "worktime/stopwatch/:id", :to => "stopwatch#timer"
5 | get "worktime/stopwatch/snapup/:id", :to => "stopwatch#snapup"
6 | get "users/:id/worktime", :to => "worktimelog#user_summary"
7 |
8 | match "users/:id/worktime" => "worktimelog#user_summary"
9 | match "issues/:issue_id/worktime" => "worktimelog#issue_summary"
10 | match "projects/:project_id/worktime" => "worktimelog#project_summary"
11 |
12 |
13 | resources :projects do
14 | resources :worktimelog, :only => [:project_summary]
15 | end
16 |
17 | resources :issues do
18 | resources :worktimelog, :only => [:issue_summary,:snapup]
19 | end
20 |
21 | resources :users do
22 | resources :worktimelog, :only => [:user_summary]
23 | end
24 |
25 |
--------------------------------------------------------------------------------
/assets/scss/_main.scss:
--------------------------------------------------------------------------------
1 | .widget {
2 | &.worklog {
3 | .timer-container {
4 | .stopwatch {
5 | padding-left: 8px;
6 | font-size: 0.7rem;
7 | }
8 | }
9 | }
10 | h3 {
11 | .my-summary {
12 | float: right;
13 | &.small {
14 | font-size: 0.575em;
15 | }
16 | }
17 | }
18 | }
19 |
20 | .worktime-log.issue-toolbar {
21 | background-color: #F7F6EE;
22 | padding: 10px;
23 | }
24 |
25 | .worktimelog, .worktime-log {
26 | .issue-btn {
27 | display: inline-block;
28 | margin: 0 1px;
29 | height: 21px;
30 | line-height: 16px;
31 | border-radius: 2px;
32 | left: 0;
33 | padding: 0 10px;
34 | margin-left: 0;
35 | border: none;
36 | box-shadow: none;
37 | text-shadow: none;
38 | background: #179e7f;
39 | color: #fff;
40 | text-decoration: none;
41 | border: inset 0 -2px 0 0 rgba(0,0,0,.2);
42 | outline: none;
43 | line-height: 21px;
44 | }
45 | .issue-btn.nice {
46 | background-color: #CC5E2E;
47 | }
48 | }
--------------------------------------------------------------------------------
/app/views/settings/_worktime_about.html.erb:
--------------------------------------------------------------------------------
1 | <% html_title l(:label_worktime_about) %>
2 |
3 | <%= l(:label_worktime_inception) %>
4 |
5 |
6 | Hey there. Worktime Log built about 3 month ago and today I completely added missing things and prepare first release.
7 |
8 |
9 |
10 | Plugin built especially for internal and tested with PostgreSQL configuration ONLY and with base RoR knowledges, so suggestions welcomed. Feel free to make forks and touch me in case if you have some fixes and suggestions.
11 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/app/views/settings/_worktime_general.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:fieldset_widget_title) %>
2 |
3 | <%= l(:label_show_stopwatch_in_projects) %>
4 | <%= hidden_field_tag 'settings[show_in_projects]', 0, :id => nil %>
5 | <%= check_box_tag 'settings[show_in_projects]', 1, @settings[:show_in_projects] %>
6 |
7 |
8 |
9 | <%= l(:label_show_stopwatch_in_issues) %>
10 | <%= hidden_field_tag 'settings[show_in_issues]', 0, :id => nil %>
11 | <%= check_box_tag 'settings[show_in_issues]', 1, @settings[:show_in_issues] %>
12 |
13 |
14 |
15 | <%= l(:label_show_stopwatch_in_welcome) %>
16 | <%= hidden_field_tag 'settings[show_in_welcome]', 0, :id => nil %>
17 | <%= check_box_tag 'settings[show_in_welcome]', 1, @settings[:show_in_welcome] %>
18 |
19 |
20 | <%= l(:fieldset_smart_toolbar) %>
21 |
22 | <%= l(:label_show_smart_toolbar_issue) %>
23 | <%= hidden_field_tag 'settings[show_toolbar_in_issue]', 0, :id => nil %>
24 | <%= check_box_tag 'settings[show_inshow_toolbar_in_issue_welcome]', 1, @settings[:show_toolbar_in_issue] %>
25 |
26 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | require 'redmine'
2 | Redmine::Plugin.register :redmine_worktime_log do
3 | name 'Redmine Worktime Log'
4 | author 'Jared Denisov'
5 | description 'Worktime log will help arange spent time and prepare logs for each user.'
6 | version '0.0.3'
7 | url 'http://themondays.ca/redmine/plugins/worklog.git'
8 | author_url 'http://themondays.ca'
9 |
10 | requires_redmine :version_or_higher => '2.1.2'
11 |
12 | settings :default => {
13 | 'show_in_projects' => true,
14 | 'show_in_issues' => true,
15 | 'show_in_welcome' => false,
16 | 'show_toolbar_in_issue' => true,
17 | }, :partial => 'settings/worktime'
18 |
19 | permission :worktime, { :worktimelog => [:user_summary] }, :public => false
20 |
21 | project_module :worktime do
22 | permission :view_issue_summary, :worktimelog => :issue_summary
23 | permission :view_project_sumary, :worktimelog => :project_summary
24 | permission :view_user_sumary, :worktimelog => :user_summary
25 | permission :stopwatch_timer, :stopwatch => :timer
26 | end
27 | menu :project_menu, :worktime_log, {:controller => 'worktimelog', :action => 'project_summary'}, :caption => :label_worktime_project_nav, :param => :project_id
28 | end
29 |
30 | ActionDispatch::Callbacks.to_prepare do
31 | require 'redmine_worktime'
32 | end
33 |
--------------------------------------------------------------------------------
/lib/redmine_worktime/hooks/view_issue_hook.rb:
--------------------------------------------------------------------------------
1 | module RedmineWorktime
2 | module Hooks
3 | class ViewIssueHook < Redmine::Hook::ViewListener
4 | def get_user_total(id)
5 | Worktimelog.where("user_id = #{User.current.id} AND issue_id = #{id} AND flag = 1").select("COUNT(id), SUM(total) as user_time").to_a
6 | end
7 | def get_issue_total(id)
8 | Worktimelog.where({:issue_id => id, :flag => 1}).select("COUNT(id), SUM(total) as issue_time").to_a
9 | end
10 | def running_issue
11 | Worktimelog.where({:user_id => User.current.id, :flag => 0}).limit(1).to_a
12 | end
13 | def running_array
14 | Worktimelog.where({:user_id => User.current.id, :flag => 0}).limit(1).pluck(:issue_id)
15 | end
16 | def view_issues_show_details_bottom(context)
17 | context[:user_total] = get_user_total(context[:issue].id)
18 | context[:issue_total] = get_issue_total(context[:issue].id)
19 | context[:running] = running_issue
20 | context[:me] = User.current.id
21 | context[:running_array] = running_array
22 | context[:controller].send(:render_to_string, {
23 | :partial => "worktimelog/widget_issue_toolbar",
24 | :locals => context
25 | })
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/redmine_worktime/patches/view_sidebar_patch.rb:
--------------------------------------------------------------------------------
1 | module RedmineWorktime
2 | module Patches
3 | class ViewSidebarHook < Redmine::Hook::ViewListener
4 | include MyHelper
5 |
6 | require_dependency 'projects_helper'
7 | def projects_list
8 | Project.
9 | limit(10).
10 | to_a
11 | end
12 | def issues_list
13 | Issue.visible.open.
14 | select("id,subject,project_id,p.name as project_name").
15 | where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
16 | includes(:status, :project, :tracker, :priority).
17 | order("#{Issue.table_name}.project_id ASC, #{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
18 | to_a
19 | end
20 | def running_issue
21 | Worktimelog.where({:user_id => User.current.id, :flag => 0}).limit(1).to_a
22 | end
23 | def _widget(context)
24 | context[:iss] = issues_list
25 | context[:running] = running_issue
26 | context[:controller].send(:render_to_string, {
27 | :partial =>'stopwatch/widget_timer',
28 | :locals => context
29 | })
30 | return context
31 | end
32 | def view_issues_sidebar_planning_bottom(context)
33 | #view_issues_sidebar_planning_bottom
34 | _widget(context)
35 | end
36 | def view_project_sidebar_planning_bottom(context)
37 | #view_issues_sidebar_planning_bottom
38 | _widget(context)
39 | end
40 | # def view_layouts_base_sidebar(context)
41 | # #view_issues_sidebar_planning_bottom
42 | # _widget(context)
43 | # end
44 | end
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # English strings go here for Rails i18n
2 | en:
3 | label_worktime: "Worktime Stopwatch"
4 | label_worktime_project_nav: "Work Time"
5 | label_worktime_general: "General"
6 | label_worktime_about: "About Plugin"
7 | label_worktime_credits: "Credit"
8 | label_worktime_license: "License"
9 | label_worktime_my_summary: "My Summary"
10 | fieldset_widget_title: "Widget Options"
11 | label_show_stopwatch_in_projects: "Show stopwatch widget in projects sidebar"
12 | label_show_stopwatch_in_issues: "Show stopwatch widget in issues sidebar"
13 | label_show_stopwatch_in_welcome: "Show stopwatch widget in welcome screen"
14 | fieldset_smart_toolbar: "Smart Toolbar Options"
15 | label_show_smart_toolbar_issue: "Show extra toolbar on issue page"
16 | label_worktime_start: "Start"
17 | label_worktime_stop: "Stop"
18 | label_worktime_switch: "Switch"
19 | label_worktime_snapup: "Snap Up"
20 | label_worktime_you_spent: "You spent"
21 | label_worktime_total_spent: "total"
22 | label_worktime_spent: "Spent"
23 | label_worktime_project_summary: "Project Worktime Summary"
24 | label_worktime_issue_summary: "Issue Worktime Summary"
25 | label_worktime_user_summary: "User Worktime Summary"
26 | label_worktime_summary: "Worktime Summary"
27 | label_worktime_filter: "Filter"
28 | label_worktime_filter_from: "From"
29 | label_worktime_filter_to: "To"
30 | label_worktime_filter_apply: "Apply"
31 | label_worktime_th_username: "User"
32 | label_worktime_th_project: "Project"
33 | label_worktime_th_issue: "Issue"
34 | label_worktime_th_id: "ID"
35 | label_worktime_th_start: "Started"
36 | label_worktime_th_end: "Finished"
37 | label_worktime_th_total: "Total"
38 | label_worktime_inception: "Inception"
39 |
--------------------------------------------------------------------------------
/config/locales/uk.yml:
--------------------------------------------------------------------------------
1 | # Ukrainian strings go here for Rails i18n
2 | uk:
3 | label_worktime: "Час роботи"
4 | label_worktime_project_nav: "Час роботи"
5 | label_worktime_general: "Загальні"
6 | label_worktime_about: "Про додаток"
7 | label_worktime_credits: "Пошана"
8 | label_worktime_license: "Ліцензія"
9 | label_worktime_my_summary: "Моє резюме"
10 | fieldset_widget_title: "Опції Віджета"
11 | label_show_stopwatch_in_projects: "Показати секундомір у бічній панелі проектів"
12 | label_show_stopwatch_in_issues: "Показати секундомір у бічній панелі завдань"
13 | label_show_stopwatch_in_welcome: "Показати секундомір на екрані вітання"
14 | fieldset_smart_toolbar: "Додаткові інструменти"
15 | label_show_smart_toolbar_issue: "Показати додаткові інструменти на сторінці завдання"
16 | label_worktime_start: "Пуск"
17 | label_worktime_stop: "Стоп"
18 | label_worktime_switch: "Перехід"
19 | label_worktime_snapup: "Підхопити"
20 | label_worktime_you_spent: "Ви витратили"
21 | label_worktime_total_spent: "загально"
22 | label_worktime_spent: "витрачено"
23 | label_worktime_project_summary: "Часовий Підсумок Проекту"
24 | label_worktime_issue_summary: "Часовий Підсумок Завдання"
25 | label_worktime_user_summary: "Часовий Підсумок Користувача"
26 | label_worktime_summary: "Підсумок"
27 | label_worktime_filter: "Фільтр"
28 | label_worktime_filter_from: "Від"
29 | label_worktime_filter_to: "По"
30 | label_worktime_filter_apply: "Застосувати"
31 | label_worktime_th_username: "Користувач"
32 | label_worktime_th_project: "Проект"
33 | label_worktime_th_issue: "Завдання"
34 | label_worktime_th_id: "ID"
35 | label_worktime_th_start: "Початок"
36 | label_worktime_th_end: "Кінець"
37 | label_worktime_th_total: "Усього"
38 | label_worktime_inception: "Початок"
--------------------------------------------------------------------------------
/config/locales/fr.yml:
--------------------------------------------------------------------------------
1 | # French strings go here for Rails i18n
2 | fr:
3 | label_worktime: "Chronomètre"
4 | label_worktime_project_nav: "Temps de travail"
5 | label_worktime_general: "Général"
6 | label_worktime_about: "A propos de Plugin"
7 | label_worktime_credits: "Crédit"
8 | label_worktime_license: "Licence"
9 | label_worktime_my_summary: "Mon résumé"
10 | fieldset_widget_title: "Widget Parametres"
11 | label_show_stopwatch_in_projects: "Montrer widget chronomètre dans des projets encadré"
12 | label_show_stopwatch_in_issues: "Montrer widget chronomètre questions encadré"
13 | label_show_stopwatch_in_welcome: "Show widget chronomètre écran de bienvenue"
14 | fieldset_smart_toolbar: "Options de barre d'outils intelligente"
15 | label_show_smart_toolbar_issue: "Afficher la barre supplémentaire à le billet page"
16 | label_worktime_start: "Démarrer"
17 | label_worktime_stop: "Stop"
18 | label_worktime_switch: "Switch"
19 | label_worktime_snapup: "Accepter"
20 | label_worktime_you_spent: "Vous avez passé"
21 | label_worktime_total_spent: "total"
22 | label_worktime_spent: "Passé"
23 | label_worktime_project_summary: "Résumé du Projet"
24 | label_worktime_issue_summary: "Résumé du Billet"
25 | label_worktime_user_summary: "Résumé du Utilisateur"
26 | label_worktime_summary: "Résumé du temps"
27 | label_worktime_filter: "Filtre"
28 | label_worktime_filter_from: "De"
29 | label_worktime_filter_to: "Pour"
30 | label_worktime_filter_apply: "Appliquer"
31 | label_worktime_th_username: "Utilisateur"
32 | label_worktime_th_project: "Projet"
33 | label_worktime_th_issue: "Billet"
34 | label_worktime_th_id: "ID"
35 | label_worktime_th_start: "Démarré"
36 | label_worktime_th_end: "Fini"
37 | label_worktime_th_total: "Total"
38 | label_worktime_inception: "La Introduction"
--------------------------------------------------------------------------------
/config/locales/ru.yml:
--------------------------------------------------------------------------------
1 | # Russian strings go here for Rails i18n
2 | ru:
3 | label_worktime: "Рабочее Время"
4 | label_worktime_project_nav: "Рабочее Время"
5 | label_worktime_general: "Общие"
6 | label_worktime_about: "О плагине"
7 | label_worktime_credits: "Признательность"
8 | label_worktime_license: "Лицензия"
9 | label_worktime_my_summary: "Мое резюме"
10 | fieldset_widget_title: "Настройки виджета"
11 | label_show_stopwatch_in_projects: "Показывать секундомер в боковой панеле проекта"
12 | label_show_stopwatch_in_issues: "Показывать секундомер в боковой панеле задачи"
13 | label_show_stopwatch_in_welcome: "Показывать секундомер на главной странице"
14 | fieldset_smart_toolbar: "Дополнительные инструменты"
15 | label_show_smart_toolbar_issue: "Показывать дополнительные инструменты на странице задачи"
16 | label_worktime_start: "Пуск"
17 | label_worktime_stop: "Стоп"
18 | label_worktime_switch: "Переход"
19 | label_worktime_snapup: "Подхватить"
20 | label_worktime_you_spent: "Потрачено вами"
21 | label_worktime_total_spent: "всего"
22 | label_worktime_spent: "потрачено"
23 | label_worktime_project_summary: "Временная сводка проекта"
24 | label_worktime_issue_summary: "Временная сводка задачи"
25 | label_worktime_user_summary: "Временная сводка пользователя"
26 | label_worktime_summary: "Сводка"
27 | label_worktime_filter: "Фильтр"
28 | label_worktime_filter_from: "С"
29 | label_worktime_filter_to: "По"
30 | label_worktime_filter_apply: "Применить"
31 | label_worktime_th_username: "Пользователь"
32 | label_worktime_th_project: "Проект"
33 | label_worktime_th_issue: "Задача"
34 | label_worktime_th_id: "ID задачи"
35 | label_worktime_th_start: "Начало"
36 | label_worktime_th_end: "Конец"
37 | label_worktime_th_total: "Всего"
38 | label_worktime_inception: "Начало"
--------------------------------------------------------------------------------
/app/views/worktimelog/_widget_issue_toolbar.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if user_total != nil %>
3 | <% user_total.each do |my| %>
4 | <% if my.user_time != nil %>
5 | <% spent = to_time(my.user_time.to_f) %>
6 | <% else %>
7 | <% spent = '00:00:00' %>
8 | <% end %>
9 | <%= l(:label_worktime_you_spent) %>: <%= spent %>
10 | <% end %>
11 | <% end %>
12 |
13 | <% if issue_total != nil %>
14 | <% issue_total.each do |all| %>
15 | <% if all.issue_time != nil %>
16 | <%= l(:label_worktime_total_spent) %>: <%= to_time(all.issue_time.to_f) %>
17 | <% end %>
18 | <% end %>
19 | <% end %>
20 | <% if running_array[0] != nil %>
21 | <% running.each do |r| %>
22 | <% if r.issue_id == @issue.id %>
23 | <%= link_to(l(:label_worktime_stop), { controller: "stopwatch", action: "timer", id: issue.id, state: "stop", back: true}, class: "worktimelog issue-btn") %>
24 |
25 | <% elsif r.issue_id != @issue.id && r.issue_id != nil %>
26 | <%= link_to(l(:label_worktime_switch), { controller: "stopwatch", action: "timer", id: issue.id, state: "start", back: true}, class: "worktimelog issue-btn") %>
27 | <% else %>
28 | <%= link_to(l(:label_worktime_start), { controller: "stopwatch", action: "timer", id: issue.id, state: "start", back: true}, class: "worktimelog issue-btn") %>
29 | <% end %>
30 | <% end %>
31 | <% else %>
32 | <%= link_to(l(:label_worktime_start), { controller: "stopwatch", action: "timer", id: issue.id, state: "start", back: true}, class: "worktimelog issue-btn") %>
33 | <% end %>
34 | <% if @issue.assigned_to_id != me %>
35 | <%= link_to(l(:label_worktime_snapup), {controller: 'stopwatch', action: 'snapup', id: issue.id, back: "true"}, class: 'worktimelog issue-btn nice') %>
36 | <% end %>
37 |
--------------------------------------------------------------------------------
/lib/redmine_worktime/hooks/view_sidebar_hook.rb:
--------------------------------------------------------------------------------
1 | module RedmineWorktime
2 | module Hooks
3 | class ViewSidebarHook < Redmine::Hook::ViewListener
4 | include MyHelper
5 |
6 | require_dependency 'projects_helper'
7 | def projects_list
8 | Project.
9 | limit(10).
10 | to_a
11 | end
12 | def issues_list
13 | Issue.visible.open.
14 | select("id,subject,project_id,p.name as project_name").
15 | where(:assigned_to_id => ([User.current.id] + User.current.group_ids)).
16 | includes(:status, :project, :tracker, :priority).
17 | order("#{Issue.table_name}.project_id ASC, #{IssuePriority.table_name}.position DESC, #{Issue.table_name}.updated_on DESC").
18 | to_a
19 | end
20 | def running_issue
21 | Worktimelog.where({:user_id => User.current.id, :flag => 0}).limit(1).to_a
22 | end
23 | def _widget(context)
24 | context[:iss] = issues_list
25 | context[:running] = running_issue
26 | context[:me] = User.current.id
27 | context[:controller].send(:render_to_string, {
28 | :partial =>'stopwatch/widget_timer',
29 | :locals => context
30 | })
31 | end
32 |
33 | # Rendering widget to specified areas
34 |
35 | def view_welcome_index_left(context)
36 | if !!Setting.plugin_redmine_worktime_log[:show_in_welcome]
37 | _widget(context)
38 | end
39 | end
40 |
41 | def view_issues_sidebar_planning_bottom(context)
42 | if !!Setting.plugin_redmine_worktime_log[:show_in_issues]
43 | _widget(context)
44 | end
45 | end
46 |
47 | def view_projects_show_sidebar_bottom(context)
48 | if !!Setting.plugin_redmine_worktime_log[:show_in_projects]
49 | _widget(context)
50 | end
51 | end
52 |
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/README.rdoc:
--------------------------------------------------------------------------------
1 | = Redmine Worktime Log Plugin
2 |
3 | Release Candidate: 0.0.1
4 |
5 | == Inception
6 | Stopwatch plugin with extended projects / users / issues summary will help you track your time without editing issue details.
7 |
8 | Hey there. Worktime Log built about 3 month ago and today I completely added missing things and prepare first release.
9 |
10 | Plugin built especially for internal and tested with PostgreSQL configuration ONLY and with base RoR knowledges, so suggestions welcomed. Feel free to make forks and touch me in case if you have some fixes and suggestions.
11 |
12 | == How it works?
13 | Push START button and continue working and don't forget to press STOP when you going on lunch :)
14 |
15 | == Installation
16 | * bundle install --without development test RAILS_ENV=production
17 | * Copy plugin files to ```/redmine/plugins``` and you will get something like that: ```redmine/plugins/redmine_worktime_log/init.rb```
18 | * Run ```rake redmine:plugins NAME=redmine_worktime_log RAILS_ENV=production```
19 |
20 |
21 | == Additional thanks to:
22 | * Stopwatch timer originally from CakePHP app called [project-manager] by [websightdesigns]
23 | * [jQuery.Chosen] - by [Harvest]
24 |
25 | == Project locations
26 | * [Project page on GitHub]
27 | * [Project page]
28 | * [Bring me a coffee]
29 |
30 | In case ff you found something unappropriate or I forgot mention someone please touch me and we fix it.
31 | Developed by [Jared Denison] in 2014.
32 |
33 | [Project page on GitHub]:https://github.com/themondays/redmine_worktime_log
34 | [Project page]:http://themondays.ca/redmine/plugins/worktimelog/
35 | [Bring me a coffee]:http://themondays.ca/coffee/
36 | [Jared Denison]:http://themondays.ca
37 | [project-manager]:https://github.com/websightdesigns/project-manager/blob/master/README.md
38 | [websightdesigns]:https://github.com/websightdesigns/project-manager/blob/master/README.md
39 | [jQuery.Chosen]:http://harvesthq.github.io/chosen/
40 | [Harvest]:http://www.getharvest.com/
41 |
42 |
--------------------------------------------------------------------------------
/app/views/stopwatch/_widget_timer.html.erb:
--------------------------------------------------------------------------------
1 | <% runtime = 0 %>
2 | <% ac = "false" %>
3 | <% running_issue_id = "" %>
4 | <% running_issue = "" %>
5 | <% if running.count > 0 %>
6 | <% running.each do |r| %>
7 | <% if r.finished %>
8 | <% runtime = runtime+(r.finished - r.started) %>
9 | <% else %>
10 | <% runtime = runtime+(Time.now.getutc - r.started) %>
11 | <% ac = true %>
12 | <% running_issue_id = r.issue_id %>
13 | <% end %>
14 | <% end %>
15 | <% end %>
16 |
17 |
49 |
--------------------------------------------------------------------------------
/app/views/worktimelog/issue_summary.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:label_worktime_issue_summary) %>
2 |
3 |
12 | <% daytotal = 0 %>
13 | <% subtotal = 0 %>
14 | <% date_listed = 0 %>
15 |
--------------------------------------------------------------------------------
/app/views/worktimelog/user_summary.html.erb:
--------------------------------------------------------------------------------
1 | <%= @user %> <%= l(:label_worktime_summary) %>
2 |
3 |
12 |
13 | <% daytotal = 0 %>
14 | <% subtotal = 0 %>
15 | <% date_listed = 0 %>
16 |
--------------------------------------------------------------------------------
/app/controllers/stopwatch_controller.rb:
--------------------------------------------------------------------------------
1 | class StopwatchController < ApplicationController
2 |
3 | unloadable
4 |
5 | # before_filter :authorize
6 |
7 | respond_to :html, :js
8 |
9 | def get_started
10 | #Hope God will excuse me for using map this way
11 | Worktimelog.where({:user_id => User.current.id, :flag => 0}).limit(1).map { |w| {started: w.started, issue_id: w.issue_id} }
12 | end
13 |
14 | def get_old_started
15 | Worktimelog.where({:user_id => User.current.id, :flag => 0})
16 | end
17 |
18 | def update_time_entry(t,id)
19 | now = Time.now.in_time_zone(User.current.time_zone).getutc
20 | project = Issue.where(:id => id).pluck(:project_id)
21 | te = TimeEntry.new(
22 | :project_id => project[0],
23 | :user_id => User.current.id,
24 | :issue_id => id,
25 | :hours => t.to_i/3600,
26 | :comments => 'Captured time',
27 | :activity_id => 1,
28 | :spent_on => User.current.today,
29 | :tyear => now.strftime('%Y'),
30 | :tmonth => now.strftime('%M'),
31 | :tweek => now.strftime('%U'),
32 | :created_on => now,
33 | :updated_on => now
34 | )
35 | te.save
36 | end
37 |
38 | def time_to_sec(t)
39 | s = t.split(":").map{|s| s.to_i}
40 | return (s[0]*3600) + (s[1]*60) + s[2]
41 | end
42 |
43 | def _start
44 | query = {
45 | :issue_id => params[:id],
46 | :user_id => User.current.id,
47 | :started => Time.now.in_time_zone(User.current.time_zone).getutc,
48 | :flag => 0
49 | }
50 | Worktimelog.create(query)
51 | end
52 | def _stop
53 | target = get_started[0]
54 | if target[:issue_id]
55 | now = Time.now.in_time_zone(User.current.time_zone).getutc
56 | started = time_to_sec(Time.at(now-Time.parse(target[:started].to_s)).strftime('%H:%M:%S'))
57 | @worklog = Worktimelog.where({:user_id => User.current.id, :flag => 0})
58 | spent_time = time_to_sec(Time.at(now-Time.at(Time.parse(target[:started].to_s))).utc.strftime('%R:%S'))
59 | @worklog.update_all("finished = '#{now}', total = '#{spent_time}', flag = 1")
60 | if target[:issue_id]
61 | update_time_entry(spent_time,target[:issue_id])
62 | end
63 | end
64 | end
65 |
66 | def timer
67 | @success = false
68 | if params[:state] == "start" && params[:id]
69 | @success = true
70 | _start
71 | if params[:back] == "true"
72 | redirect_to :back
73 | end
74 |
75 | end
76 |
77 | if params[:state] == "stop"
78 | @success = true
79 | _stop
80 | if params[:back] == "true"
81 | redirect_to :back
82 | end
83 | end
84 | end
85 | def snapup
86 | _stop
87 | _start
88 |
89 | issue = Issue.find(params[:id])
90 | issue.assigned_to_id = User.current.id
91 | issue.save
92 |
93 | if params[:back] == 'true'
94 | redirect_to :back
95 | end
96 | end
97 |
98 | end
99 |
--------------------------------------------------------------------------------
/app/views/worktimelog/project_summary.html.erb:
--------------------------------------------------------------------------------
1 | <%= l(:label_worktime_project_summary) %>
2 |
3 |
12 | <% daytotal = 0 %>
13 | <% subtotal = 0 %>
14 | <% date_listed = 0 %>
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Redmine Worktime Log Plugin
2 | Release Candidate: 0.0.2
3 |
4 | ### Inception
5 | Hey folks.
6 |
7 | If describe this plugin in couple words - Worktime Log is just a Stopwatch plugin with extended projects / users / issues summary. I'm pretty sure that plugin will help you track your team load without any additional inconvenience editing issue details and billion clicks.
8 |
9 | Worktime Log built about 3 month ago for internal use and today I decided to share firs public RC with you.
10 |
11 | In general plugin created and tested with Redmine 2.6 under PostgreSQL, by this reason some queries should be reviewed before push to production with MySQL database.
12 |
13 | Feel free to make forks and touch me in case if you have some fixes and suggestions.
14 |
15 | ### How it works?
16 | 1. Enable Worktime Log module in your project
17 | 2. Add couple tickets assigned to you
18 | 3. Push START button and continue working
19 | 4. Don't forget press STOP when you going on lunch :)
20 |
21 | 
22 |
23 | ### Extra Issue Toolbar
24 | To make life easier I have added additional toolbar to issue overview. In case if you don't need this tool you may change toolbar visibility inside plugin settings.
25 |
26 | 
27 |
28 | ### Installation
29 | 1. Copy plugin files to ```/redmine/plugins``` and you will get something like that: ```redmine/plugins/redmine_worktime_log/init.rb```
30 | 2. Run ```rake redmine:plugins NAME=redmine_worktime_log RAILS_ENV=production```
31 |
32 | ### Settings
33 | Inside plugin settings you may change widgets visibility as well.
34 |
35 | ### Additional thanks to:
36 | * Stopwatch timer originally from CakePHP app called [project-manager] by [websightdesigns]
37 | * [jQuery.Chosen] - by [Harvest]
38 |
39 | ### License
40 | This plugin is available under [CC-BY 3.0]
41 |
42 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
43 |
44 | ### Project locations
45 | * [Project page on GitHub]
46 | * [Project page]
47 | * [Bring me a coffee]
48 |
49 | In case ff you found something unappropriate or I forgot mention someone please touch me and we fix it.
50 |
51 | Developed by [Jared Denison] in 2014.
52 |
53 | [Project page on GitHub]:https://github.com/themondays/redmine_worktime_log
54 | [Project page]:http://themondays.ca/redmine/plugins/worktimelog/
55 | [Bring me a coffee]:http://themondays.ca/coffee/
56 | [Jared Denison]:http://themondays.ca
57 | [project-manager]:https://github.com/websightdesigns/project-manager/blob/master/README.md
58 | [websightdesigns]:https://github.com/websightdesigns/project-manager/blob/master/README.md
59 | [jQuery.Chosen]:http://harvesthq.github.io/chosen/
60 | [Harvest]:http://www.getharvest.com/
61 | [CC-BY 3.0]:http://creativecommons.org/licenses/by/3.0/
62 |
63 | ### Changelog
64 |
65 | #### Rev. 0.0.3
66 | * Added time helper
67 | * Fixed issue totals
68 | * Fixed summary totals
69 |
70 | #### Rev. 0.0.2
71 | * Fixed toolbar stylesheet
72 | * Fixed toolbar snap up button appearance
73 | * Added 3 new languages
74 |
--------------------------------------------------------------------------------
/assets/javascripts/timer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Worktime Log Stopwatch
3 | * @version 0.1
4 | */
5 | $(document).ready(function() {
6 | var RedmineWorktimeLog = {
7 | opts: {
8 | time: 0,
9 | active: false,
10 | elapsed: 0,
11 | running_issue: 0,
12 | formWidget: '',
13 | timer: null
14 | },
15 | query: function(url,settings) {
16 | $.ajax({
17 | url: url,
18 | type: "POST",
19 | data: settings,
20 | dataType: "json",
21 | beforeSend: function(){
22 | },
23 |
24 | complete: function(){
25 | },
26 |
27 | success: function( response ){
28 | return true;
29 | },
30 | error: function(){
31 | return false;
32 | }
33 | });
34 | },
35 | widget: function() {
36 | var _this = this,
37 | btn = $("button", _this.opts.formWidget),
38 | Timer = _this.opts.timer.stopwatch({
39 | startTime: _this.opts.runtime,
40 | format: '{HH}:{MM}:{SS}'
41 | });
42 | _this.opts.runtime = _this.opts.timer.data('runtime')*1;
43 | if (this.opts.runtime > 1) {
44 | Timer.stopwatch({active: true,startTime: _this.opts.runtime}).stopwatch('start');
45 | _this.opts.active = true;
46 | btn.text(btn.data("stop")).attr('value','stop');
47 | }
48 | $("#stopwatch-ui select.dropdown").chosen({width:"80%",no_results_text: "Not found: "});
49 |
50 | //.bind(callback,this)
51 | },
52 | events: (function() {
53 | var _this = this;
54 | $(".widget.worklog #stopwatch-ui .dropdown").on('change',function(event){
55 | var el = $(this),
56 | btn = $("button", el);
57 | // Fix it
58 | if ( _this.opts.running_issue > 0 && _this.opts.active === true && _this.opts.running_issue !== el.val() ) {
59 | btn.parent().text(btn.data("switch"));
60 | } else {
61 | btn.parent().text(btn.data("stop"));
62 | }
63 | });
64 | }),
65 | launch: function(){
66 | var _this = this;
67 | this.opts.formWidget.submit(function(event){
68 | event.preventDefault();
69 | var el = $(this),
70 | btn = $("button",el),
71 | params = {
72 | state: $('[name="state"]',el).val(),
73 | issue_id: $('[name="issue_id"]',el).val()
74 | };
75 | url='/worktime/stopwatch/' + params.issue_id;
76 | _this.query(url,params);
77 | //var stopwatch = timer.stopwatch({startTime: time});
78 | if ( _this.opts.active !== true ) {
79 | _this.opts.active = true;
80 | _this.opts.timer.
81 | stopwatch('start');
82 | btn.text(btn.data("stop")).attr('value','stop');
83 | _this.opts.running_issue = $(".dropdown",el).val();
84 | } else {
85 | _this.opts.elapsed = _this.opts.timer.stopwatch('getTime');
86 | _this.opts.timer.
87 | stopwatch('stop').stopwatch('reset');
88 | _this.opts.timer.data('suntime',1);
89 | _this.opts.active = false;
90 | _this.opts.running_issue = 0;
91 | btn.text(btn.data("start")).attr('value','start');
92 | }
93 | return false;
94 | });
95 |
96 | },
97 | init: function() {
98 | this.events();
99 | this.widget();
100 | this.launch();
101 | }
102 |
103 | };
104 |
105 | RedmineWorktimeLog.opts.formWidget = $(".widget.worklog #stopwatch-ui");
106 | RedmineWorktimeLog.opts.timer = $('#timer');
107 | RedmineWorktimeLog.opts.runtime = RedmineWorktimeLog.opts.timer.data('runtime')*1;
108 |
109 | RedmineWorktimeLog.init();
110 |
111 | RedmineWorktimeLog.opts.timer.stopwatch({
112 | startTime: RedmineWorktimeLog.opts.runtime,
113 | format: '{HH}:{MM}:{SS}'
114 | });
115 | });
116 |
117 | /**
118 | * To do:
119 | * - add bindings
120 | * - callback
121 | * - rewrite stopwatch
122 | * - cleanup
123 | */
--------------------------------------------------------------------------------
/assets/scss/_widget.scss:
--------------------------------------------------------------------------------
1 | $span-margin: 1.2rem;
2 | #sidebar, .splitcontentleft, .splitcontentright {
3 | .chosen-container {
4 | .chosen-single {
5 | border-radius: 0;
6 | @include box-shadow(none);
7 | }
8 | .chosen-drop {
9 | border-radius: 0;
10 | @include box-shadow(none);
11 | }
12 | }
13 |
14 | .widget.worklog {
15 | box-sizing: border-box;
16 | margin-top: $span-margin;
17 | background: #fafaf5;
18 | padding: $span-margin;
19 | h3 {
20 | margin: 0;
21 | padding: 0;
22 | border: none;
23 | }
24 | .chosen-container {
25 | &.chosen-container-active {
26 | .chosen-single {
27 | b {
28 | background-position: 3px 8px;
29 | }
30 | }
31 |
32 | }
33 | .chosen-search {
34 | input {
35 | box-shadow: none;
36 | border-color: #eee;
37 | }
38 | }
39 | .chosen-drop {
40 | border-color: #eee;
41 | }
42 | .chosen-results {
43 | color: #444;
44 | position: relative;
45 | overflow-x: hidden;
46 | overflow-y: auto;
47 | margin: 0 4px 4px 0;
48 | padding: 0 0 0 4px;
49 | max-height: 240px;
50 | -webkit-overflow-scrolling: touch;
51 | li {
52 | display: none;
53 | margin: 0;
54 | padding: 5px 6px;
55 | list-style: none;
56 | line-height: 15px;
57 | word-wrap: break-word;
58 | -webkit-touch-callout: none;
59 | &.active-result {
60 | display: list-item;
61 | cursor: pointer;
62 | }
63 | &.disabled-result {
64 | display: list-item;
65 | color: #ccc;
66 | cursor: default;
67 | }
68 | &.highlighted {
69 | background-color: #3875d7;
70 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
71 | background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
72 | background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
73 | background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
74 | background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
75 | color: #fff;
76 | }
77 | &.no-results {
78 | color: #777;
79 | display: list-item;
80 | background: #f4f4f4;
81 | }
82 | &.group-result {
83 | display: list-item;
84 | font-weight: bold;
85 | cursor: default;
86 | }
87 | &.group-option {
88 | padding-left: 15px;
89 | }
90 | .smart-link {
91 | clear: right;
92 | float: right;
93 | font-size: 9px;
94 | padding: 2px 4px;
95 | background-color: #4D85BD;
96 | color: #fff;
97 | line-height: 9px;
98 | border-radius: 2px;
99 | }
100 | em {
101 | font-style: normal;
102 | text-decoration: underline;
103 | }
104 | }
105 | }
106 | }
107 |
108 | }
109 | .widget.worklog .dropdown {
110 | width:80%;
111 | margin-bottom:10px;
112 | }
113 | .widget.worklog a.chosen-single {
114 | display: block;
115 | padding: 6px 10px;
116 | border-color: #eee;
117 | height: 36px;
118 | background: white;
119 | b {
120 | background-position: -15px 8px;
121 | }
122 | }
123 | .widget.worklog button.run {
124 | width: 20%;
125 | margin: 0;
126 | float: right;
127 | height: 36px;
128 | line-height: 16px;
129 | border-radius: 0 2px 2px 0;
130 | left: 0;
131 | padding: 6px 0;
132 | margin-left: 0;
133 | border: none;
134 | // border-color: #eee;
135 | box-shadow: none;
136 | text-shadow: none;
137 | &[value="start"] {
138 | background: #5dade2;
139 | color: #fff;
140 | }
141 | &[value="stop"] {
142 | background: #2ecc71;
143 | color: #fff;
144 | }
145 | outline: none;
146 |
147 | }
148 | .widget.worklog .stopwatch {
149 | }
150 | }
--------------------------------------------------------------------------------
/app/controllers/worktimelog_controller.rb:
--------------------------------------------------------------------------------
1 | class WorktimelogController < ApplicationController
2 |
3 | unloadable
4 |
5 | layout 'base'
6 |
7 | before_filter :find_project, :authorize, :only => :project_summary
8 |
9 | respond_to :html, :js
10 |
11 | helper :issue_relations
12 | include IssueRelationsHelper
13 | include IssuesHelper
14 |
15 | def find_project
16 | @project = Project.find(params[:project_id])
17 | end
18 |
19 | def find_issue
20 | @project = Issue.find(params[:id])
21 | end
22 |
23 | def find_user
24 | @project = User.find(params[:user_id])
25 | end
26 |
27 | def new
28 | @worklog = Worktimelog.new
29 | end
30 |
31 | def index
32 | end
33 |
34 | def worklog
35 | end
36 |
37 | def timer
38 | @success = false
39 | if params[:state] == "start" && params[:id]
40 | @success = true
41 | @lv = {
42 | :issue_id => params[:id],
43 | :user_id => User.current.id,
44 | :started => Time.now.getutc,
45 | :flag => 0
46 | }
47 | logger.debug(@lv)
48 | @worklog = Worktimelog.create(@lv)
49 | end
50 |
51 | if params[:state] == "stop"
52 | @success = true
53 | @worklog = Worktimelog.where({:user_id => User.current.id, :flag => 0})
54 | @worklog.update_all(:finished => Time.now.getutc, :flag => 1)
55 | end
56 | end
57 |
58 | def get_worktime(query)
59 | end
60 |
61 | def issue_summary
62 | @date = Time.now
63 |
64 | where_query = "issue_id = #{params[:issue_id]} AND flag = 1"
65 |
66 | if (params[:started] && params[:finished])
67 | where_query += "AND (started, finished) OVERLAPS ('#{params[:started]}'::DATE, '#{params[:finished]}'::DATE)"
68 | end
69 |
70 | @summary = Worktimelog.joins([{issue: :project},:user]).select('
71 | issue_id,
72 | user_id,
73 | started,
74 | finished,
75 | total,
76 | flag,
77 | issues.project_id as project_id,
78 | issues.subject as subject,
79 | users.firstname as firstname,
80 | users.lastname as lastname
81 | ').
82 | where(where_query).
83 | order("
84 | finished DESC
85 | ")
86 | if ( params[:started] || params[:finished] )
87 | if ( params[:started] )
88 | @summary.where("started::text LIKE '#{params[:started]}%'")
89 | end
90 | if ( params[:finished] )
91 | @summary.where("finished::text LIKE '#{params[:finished]}%'")
92 | end
93 | else
94 | @summary.limit(100)
95 | end
96 | end
97 |
98 | def project_summary
99 | @date = Time.now
100 |
101 | where_query = "projects.identifier = '#{params[:project_id]}' AND flag = 1"
102 |
103 | if (params[:started] && params[:finished])
104 | where_query += "AND (started, finished) OVERLAPS ('#{params[:started]}'::DATE, '#{params[:finished]}'::DATE)"
105 | end
106 |
107 | @summary = Worktimelog.joins([{issue: :project},:user]).select('
108 | issue_id,
109 | user_id,
110 | started,
111 | finished,
112 | total,
113 | flag,
114 | issues.project_id as project_id,
115 | issues.subject as subject,
116 | users.firstname as firstname,
117 | users.lastname as lastname
118 | ').
119 | where(where_query).
120 | order("
121 | finished DESC
122 | ")
123 | if ( params[:started] || params[:finished] )
124 | if ( params[:started] )
125 | @summary.where("started::text LIKE '#{params[:started]}%'")
126 | end
127 | if ( params[:finished] )
128 | @summary.where("finished::text LIKE '#{params[:finished]}%'")
129 | end
130 | else
131 | @summary.limit(100)
132 | end end
133 |
134 | def user_summary
135 | @date = Time.now
136 | @where_query = "user_id = #{params[:id]} AND flag = 1"
137 | @user = User.find(params[:id])
138 | if (params[:started] && params[:finished])
139 | @where_query += "AND (started, finished) OVERLAPS ('#{params[:started]}'::DATE, '#{params[:finished]}'::DATE)"
140 | end
141 | @summary = Worktimelog.joins(issue: :project).select('
142 | issue_id,
143 | user_id,
144 | started,
145 | finished,
146 | total,
147 | flag,
148 | issues.project_id as project_id,
149 | issues.subject as subject,
150 | projects.name as project_name,
151 | projects.identifier as project_identifier
152 | ').where(@where_query).
153 | order("
154 | finished DESC
155 | ")
156 | if ( params[:started] || params[:finished] )
157 | if ( params[:started] )
158 | @summary.where("started::text LIKE '#{params[:started]}%'")
159 | end
160 | if ( params[:finished] )
161 | @summary.where("finished::text LIKE '#{params[:finished]}%'")
162 | end
163 | else
164 | @summary.limit(100)
165 | end
166 | end
167 |
168 | def ranks
169 | end
170 |
171 | def time_to_sec(t)
172 | s = t.split(":").map{|s| s.to_i}
173 | return (s[0]*3600) + (s[1]*60) + s[2]
174 | end
175 |
176 | private
177 | def worklog_params
178 | params.require(:worklog).permit(:issue_id)
179 | end
180 |
181 | end
182 |
--------------------------------------------------------------------------------
/assets/javascripts/vendor/jquery/jquery.stopwatch.js:
--------------------------------------------------------------------------------
1 | // Originally from: git https://bitbucket.org/websightdesigns/project-manager.git
2 | (function( $ ){
3 |
4 | function incrementer(ct, increment) {
5 | return function() { ct+=increment; return ct; };
6 | }
7 |
8 | function pad2(number) {
9 | return (number < 10 ? '0' : '') + number;
10 | }
11 |
12 | function defaultFormatMilliseconds(millis) {
13 | var x, seconds, minutes, hours;
14 | x = millis / 1000;
15 | seconds = Math.floor(x % 60);
16 | x /= 60;
17 | minutes = Math.floor(x % 60);
18 | x /= 60;
19 | hours = Math.floor(x % 24);
20 | // x /= 24;
21 | // days = Math.floor(x);
22 | return [pad2(hours), pad2(minutes), pad2(seconds)].join(':');
23 | }
24 |
25 | function formatMilliseconds(millis, data) {
26 | var formatter;
27 | if (typeof jintervals == 'function') {
28 | formatter = function(millis, data){return jintervals(millis/1000, data.format);};
29 | } else {
30 | formatter = defaultFormatMilliseconds;
31 | }
32 | formatMilliseconds = function(millis, data) {
33 | return formatter(millis, data);
34 | };
35 | return formatMilliseconds(millis, data);
36 | }
37 |
38 | var methods = {
39 |
40 | init: function(options) {
41 | var defaults = {
42 | updateInterval: 1000,
43 | startTime: 0,
44 | format: '{HH}:{MM}:{SS}',
45 | formatter: formatMilliseconds
46 | };
47 |
48 | // if (options) { $.extend(settings, options); }
49 |
50 | return this.each(function() {
51 | var $this = $(this),
52 | data = $this.data('stopwatch');
53 |
54 | // If the plugin hasn't been initialized yet
55 | if (!data) {
56 | // Setup the stopwatch data
57 | var settings = $.extend({}, defaults, options);
58 | data = settings;
59 | data.active = false;
60 | data.target = $this;
61 | data.elapsed = settings.startTime;
62 | // create counter
63 | data.incrementer = incrementer(data.startTime, data.updateInterval);
64 | data.tick_function = function() {
65 | var millis = data.incrementer();
66 | data.elapsed = millis;
67 | data.target.trigger('tick.stopwatch', [millis]);
68 | data.target.stopwatch('render');
69 | };
70 | $this.data('stopwatch', data);
71 | }
72 |
73 | });
74 | },
75 |
76 | start: function() {
77 | return this.each(function() {
78 | var $this = $(this),
79 | data = $this.data('stopwatch');
80 | // Mark as active
81 | data.active = true;
82 | data.timerID = setInterval(data.tick_function, data.updateInterval);
83 | $this.data('stopwatch', data);
84 | });
85 | },
86 |
87 | stop: function() {
88 | return this.each(function() {
89 | var $this = $(this),
90 | data = $this.data('stopwatch');
91 | clearInterval(data.timerID);
92 | data.active = false;
93 | $this.data('stopwatch', data);
94 | });
95 | },
96 |
97 | destroy: function() {
98 | return this.each(function(){
99 | var $this = $(this),
100 | data = $this.data('stopwatch');
101 | $this.stopwatch('stop').unbind('.stopwatch').removeData('stopwatch');
102 | });
103 | },
104 |
105 | render: function() {
106 | var $this = $(this),
107 | data = $this.data('stopwatch');
108 | $this.html(data.formatter(data.elapsed, data));
109 | },
110 |
111 | getTime: function() {
112 | var $this = $(this),
113 | data = $this.data('stopwatch');
114 | return data.elapsed;
115 | },
116 |
117 | toggle: function() {
118 | return this.each(function() {
119 | var $this = $(this);
120 | var data = $this.data('stopwatch');
121 | if (data.active) {
122 | $this.stopwatch('stop');
123 | } else {
124 | $this.stopwatch('start');
125 | }
126 | });
127 | },
128 |
129 | reset: function() {
130 | return this.each(function() {
131 | var $this = $(this);
132 | data = $this.data('stopwatch');
133 | data.incrementer = incrementer(data.startTime, data.updateInterval);
134 | data.elapsed = data.startTime;
135 | $this.data('stopwatch', data);
136 | });
137 | }
138 | };
139 | $.fn.stopwatch = function( method ) {
140 | if (methods[method]) {
141 | return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
142 | } else if (typeof method === 'object' || !method) {
143 | return methods.init.apply(this, arguments);
144 | } else {
145 | $.error( 'Method ' + method + ' does not exist on jQuery.stopwatch' );
146 | }
147 | };
148 | })( jQuery );
--------------------------------------------------------------------------------
/assets/stylesheets/redmine_worktime_log.css.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "mappings": "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",
4 | "sources": ["../scss/_widget.scss","../scss/_mixins.scss","../scss/_main.scss","../scss/_table.scss","../scss/vendor/chosen.scss"],
5 | "names": [],
6 | "file": "redmine_worktime_log.css"
7 | }
8 |
--------------------------------------------------------------------------------
/assets/scss/vendor/chosen.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | Chosen, a Select Box Enhancer for jQuery and Prototype
3 | by Patrick Filler for Harvest, http://getharvest.com
4 |
5 | Version 1.3.0
6 | Full source at https://github.com/harvesthq/chosen
7 | Copyright (c) 2011-2014 Harvest http://getharvest.com
8 |
9 | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10 | This file is generated by `grunt build`, do not edit it by hand.
11 | */
12 |
13 | /* @group Base */
14 |
15 | .chosen-container {
16 | position: relative;
17 | display: inline-block;
18 | vertical-align: middle;
19 | font-size: 13px;
20 | zoom: 1;
21 | *display: inline;
22 | -webkit-user-select: none;
23 | -moz-user-select: none;
24 | user-select: none;
25 | * {
26 | -webkit-box-sizing: border-box;
27 | -moz-box-sizing: border-box;
28 | box-sizing: border-box;
29 | }
30 | .chosen-drop {
31 | position: absolute;
32 | top: 100%;
33 | left: -9999px;
34 | z-index: 1010;
35 | width: 100%;
36 | border: 1px solid #aaa;
37 | border-top: 0;
38 | background: #fff;
39 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
40 | }
41 | &.chosen-with-drop .chosen-drop {
42 | left: 0;
43 | }
44 | a {
45 | cursor: pointer;
46 | }
47 | }
48 |
49 | /* @end */
50 | /* @group Single Chosen */
51 |
52 | .chosen-container-single {
53 | .chosen-single {
54 | position: relative;
55 | display: block;
56 | overflow: hidden;
57 | padding: 0 0 0 8px;
58 | height: 25px;
59 | border: 1px solid #aaa;
60 | border-radius: 5px;
61 | background-color: #fff;
62 | background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
63 | background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
64 | background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
65 | background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
66 | background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
67 | background-clip: padding-box;
68 | box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
69 | color: #444;
70 | text-decoration: none;
71 | white-space: nowrap;
72 | line-height: 24px;
73 | }
74 | .chosen-default {
75 | color: #999;
76 | }
77 | .chosen-single span {
78 | display: block;
79 | overflow: hidden;
80 | margin-right: 26px;
81 | text-overflow: ellipsis;
82 | white-space: nowrap;
83 | }
84 | .chosen-single-with-deselect span {
85 | margin-right: 38px;
86 | }
87 | .chosen-single abbr {
88 | position: absolute;
89 | top: 6px;
90 | right: 26px;
91 | display: block;
92 | width: 12px;
93 | height: 12px;
94 | background: url('../images/chosen-sprite.png') -42px 1px no-repeat;
95 | font-size: 1px;
96 | &:hover {
97 | background-position: -42px -10px;
98 | }
99 | }
100 | &.chosen-disabled .chosen-single abbr:hover {
101 | background-position: -42px -10px;
102 | }
103 | .chosen-single div {
104 | position: absolute;
105 | top: 0;
106 | right: 0;
107 | display: block;
108 | width: 18px;
109 | height: 100%;
110 | b {
111 | display: block;
112 | width: 100%;
113 | height: 100%;
114 | background: url('../images/chosen-sprite.png') no-repeat 0px 2px;
115 | }
116 | }
117 | .chosen-search {
118 | position: relative;
119 | z-index: 1010;
120 | margin: 0;
121 | padding: 3px 4px;
122 | white-space: nowrap;
123 | input[type="text"] {
124 | margin: 1px 0;
125 | padding: 4px 20px 4px 5px;
126 | width: 100%;
127 | height: auto;
128 | outline: 0;
129 | border: 1px solid #aaa;
130 | background: white url('../images/chosen-sprite.png') no-repeat 100% -20px;
131 | background: url('../images/chosen-sprite.png') no-repeat 100% -20px;
132 | font-size: 1em;
133 | font-family: sans-serif;
134 | line-height: normal;
135 | border-radius: 0;
136 | }
137 | }
138 | .chosen-drop {
139 | margin-top: -1px;
140 | border-radius: 0 0 4px 4px;
141 | background-clip: padding-box;
142 | }
143 | &.chosen-container-single-nosearch .chosen-search {
144 | position: absolute;
145 | left: -9999px;
146 | }
147 | }
148 |
149 | /* @end */
150 | /* @group Results */
151 |
152 | .chosen-container .chosen-results {
153 | color: #444;
154 | position: relative;
155 | overflow-x: hidden;
156 | overflow-y: auto;
157 | margin: 0 4px 4px 0;
158 | padding: 0 0 0 4px;
159 | max-height: 240px;
160 | -webkit-overflow-scrolling: touch;
161 | li {
162 | display: none;
163 | margin: 0;
164 | padding: 5px 6px;
165 | list-style: none;
166 | line-height: 15px;
167 | word-wrap: break-word;
168 | -webkit-touch-callout: none;
169 | &.active-result {
170 | display: list-item;
171 | cursor: pointer;
172 | .smart-link {
173 | z-index: 10;
174 | clear: right;
175 | float: right;
176 | font-size: 9px;
177 | padding: 2px 4px;
178 | background-color: #4D85BD;
179 | color: #fff;
180 | line-height: 9px;
181 | border-radius: 2px;
182 | }
183 | }
184 | &.disabled-result {
185 | display: list-item;
186 | color: #ccc;
187 | cursor: default;
188 | }
189 | &.highlighted {
190 | background-color: #3875d7;
191 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
192 | background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
193 | background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
194 | background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
195 | background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
196 | color: #fff;
197 | }
198 | &.no-results {
199 | color: #777;
200 | display: list-item;
201 | background: #f4f4f4;
202 | }
203 | &.group-result {
204 | display: list-item;
205 | font-weight: bold;
206 | cursor: default;
207 | }
208 | &.group-option {
209 | padding-left: 15px;
210 | }
211 | em {
212 | font-style: normal;
213 | text-decoration: underline;
214 | }
215 | }
216 | }
217 |
218 | /* @end */
219 | /* @group Multi Chosen */
220 |
221 | .chosen-container-multi {
222 | .chosen-choices {
223 | position: relative;
224 | overflow: hidden;
225 | margin: 0;
226 | padding: 0 5px;
227 | width: 100%;
228 | height: auto !important;
229 | height: 1%;
230 | border: 1px solid #aaa;
231 | background-color: #fff;
232 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
233 | background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
234 | background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
235 | background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
236 | background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
237 | cursor: text;
238 | li {
239 | float: left;
240 | list-style: none;
241 | &.search-field {
242 | margin: 0;
243 | padding: 0;
244 | white-space: nowrap;
245 | input[type="text"] {
246 | margin: 1px 0;
247 | padding: 0;
248 | height: 25px;
249 | outline: 0;
250 | border: 0 !important;
251 | background: transparent !important;
252 | box-shadow: none;
253 | color: #999;
254 | font-size: 100%;
255 | font-family: sans-serif;
256 | line-height: normal;
257 | border-radius: 0;
258 | }
259 | }
260 | &.search-choice {
261 | position: relative;
262 | margin: 3px 5px 3px 0;
263 | padding: 3px 20px 3px 5px;
264 | border: 1px solid #aaa;
265 | max-width: 100%;
266 | border-radius: 3px;
267 | background-color: #eeeeee;
268 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
269 | background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
270 | background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
271 | background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
272 | background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
273 | background-size: 100% 19px;
274 | background-repeat: repeat-x;
275 | background-clip: padding-box;
276 | box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
277 | color: #333;
278 | line-height: 13px;
279 | cursor: default;
280 | span {
281 | word-wrap: break-word;
282 | }
283 | .search-choice-close {
284 | position: absolute;
285 | top: 4px;
286 | right: 3px;
287 | display: block;
288 | width: 12px;
289 | height: 12px;
290 | background: url('../images/chosen-sprite.png') -42px 1px no-repeat;
291 | font-size: 1px;
292 | &:hover {
293 | background-position: -42px -10px;
294 | }
295 | }
296 | }
297 | &.search-choice-disabled {
298 | padding-right: 5px;
299 | border: 1px solid #ccc;
300 | background-color: #e4e4e4;
301 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
302 | background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
303 | background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
304 | background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
305 | background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
306 | color: #666;
307 | }
308 | &.search-choice-focus {
309 | background: #d4d4d4;
310 | .search-choice-close {
311 | background-position: -42px -10px;
312 | }
313 | }
314 | }
315 | }
316 | .chosen-results {
317 | margin: 0;
318 | padding: 0;
319 | }
320 | .chosen-drop .result-selected {
321 | display: list-item;
322 | color: #ccc;
323 | cursor: default;
324 | }
325 | }
326 |
327 | /* @end */
328 | /* @group Active */
329 |
330 | .chosen-container-active {
331 | .chosen-single {
332 | border: 1px solid #5897fb;
333 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
334 | }
335 | &.chosen-with-drop .chosen-single {
336 | border: 1px solid #aaa;
337 | -moz-border-radius-bottomright: 0;
338 | border-bottom-right-radius: 0;
339 | -moz-border-radius-bottomleft: 0;
340 | border-bottom-left-radius: 0;
341 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
342 | background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
343 | background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
344 | background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
345 | background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
346 | box-shadow: 0 1px 0 #fff inset;
347 | div {
348 | border-left: none;
349 | background: transparent;
350 | b {
351 | background-position: -18px 2px;
352 | }
353 | }
354 | }
355 | .chosen-choices {
356 | border: 1px solid #5897fb;
357 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
358 | li.search-field input[type="text"] {
359 | color: #222 !important;
360 | }
361 | }
362 | }
363 |
364 | /* @end */
365 | /* @group Disabled Support */
366 |
367 | .chosen-disabled {
368 | opacity: 0.5 !important;
369 | cursor: default;
370 | .chosen-single, .chosen-choices .search-choice .search-choice-close {
371 | cursor: default;
372 | }
373 | }
374 |
375 | /* @end */
376 | /* @group Right to Left */
377 |
378 | .chosen-rtl {
379 | text-align: right;
380 | .chosen-single {
381 | overflow: visible;
382 | padding: 0 8px 0 0;
383 | span {
384 | margin-right: 0;
385 | margin-left: 26px;
386 | direction: rtl;
387 | }
388 | }
389 | .chosen-single-with-deselect span {
390 | margin-left: 38px;
391 | }
392 | .chosen-single {
393 | div {
394 | right: auto;
395 | left: 3px;
396 | }
397 | abbr {
398 | right: auto;
399 | left: 26px;
400 | }
401 | }
402 | .chosen-choices li {
403 | float: right;
404 | &.search-field input[type="text"] {
405 | direction: rtl;
406 | }
407 | &.search-choice {
408 | margin: 3px 5px 3px 0;
409 | padding: 3px 5px 3px 19px;
410 | .search-choice-close {
411 | right: auto;
412 | left: 4px;
413 | }
414 | }
415 | }
416 | &.chosen-container-single-nosearch .chosen-search, .chosen-drop {
417 | left: 9999px;
418 | }
419 | &.chosen-container-single .chosen-results {
420 | margin: 0 0 4px 4px;
421 | padding: 0 4px 0 0;
422 | }
423 | .chosen-results li.group-option {
424 | padding-right: 15px;
425 | padding-left: 0;
426 | }
427 | &.chosen-container-active.chosen-with-drop .chosen-single div {
428 | border-right: none;
429 | }
430 | .chosen-search input[type="text"] {
431 | padding: 4px 5px 4px 20px;
432 | background: white url('../images/chosen-sprite.png') no-repeat -30px -20px;
433 | background: url('../images/chosen-sprite.png') no-repeat -30px -20px;
434 | direction: rtl;
435 | }
436 | &.chosen-container-single {
437 | .chosen-single div b {
438 | background-position: 6px 2px;
439 | }
440 | &.chosen-with-drop .chosen-single div b {
441 | background-position: -12px 2px;
442 | }
443 | }
444 | }
445 |
446 | /* @end */
447 | /* @group Retina compatibility */
448 | @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
449 | .chosen-rtl .chosen-search input[type="text"] {
450 | background-image: url('../images/chosen-sprite@2x.png') !important;
451 | background-size: 52px 37px !important;
452 | background-repeat: no-repeat !important;
453 | }
454 | .chosen-container-single {
455 | .chosen-single {
456 | abbr, div b {
457 | background-image: url('../images/chosen-sprite@2x.png') !important;
458 | background-size: 52px 37px !important;
459 | background-repeat: no-repeat !important;
460 | }
461 | }
462 | .chosen-search input[type="text"] {
463 | background-image: url('../images/chosen-sprite@2x.png') !important;
464 | background-size: 52px 37px !important;
465 | background-repeat: no-repeat !important;
466 | }
467 | }
468 | .chosen-container-multi .chosen-choices .search-choice .search-choice-close {
469 | background-image: url('../images/chosen-sprite@2x.png') !important;
470 | background-size: 52px 37px !important;
471 | background-repeat: no-repeat !important;
472 | }
473 | .chosen-container {
474 | .chosen-results-scroll-down span, .chosen-results-scroll-up span {
475 | background-image: url('../images/chosen-sprite@2x.png') !important;
476 | background-size: 52px 37px !important;
477 | background-repeat: no-repeat !important;
478 | }
479 | }
480 | }
481 |
482 | /* @end */
483 |
--------------------------------------------------------------------------------
/assets/stylesheets/redmine_worktime_log.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Redmine Worktime Log Plugin
3 | * @author: Jared Denison
4 | */
5 | #sidebar .chosen-container .chosen-single, .splitcontentleft .chosen-container .chosen-single, .splitcontentright .chosen-container .chosen-single {
6 | border-radius: 0;
7 | -webkit-box-shadow: none;
8 | -moz-box-shadow: none;
9 | -ms-box-shadow: none;
10 | -o-box-shadow: none;
11 | box-shadow: none; }
12 | #sidebar .chosen-container .chosen-drop, .splitcontentleft .chosen-container .chosen-drop, .splitcontentright .chosen-container .chosen-drop {
13 | border-radius: 0;
14 | -webkit-box-shadow: none;
15 | -moz-box-shadow: none;
16 | -ms-box-shadow: none;
17 | -o-box-shadow: none;
18 | box-shadow: none; }
19 | #sidebar .widget.worklog, .splitcontentleft .widget.worklog, .splitcontentright .widget.worklog {
20 | box-sizing: border-box;
21 | margin-top: 1.2rem;
22 | background: #fafaf5;
23 | padding: 1.2rem; }
24 | #sidebar .widget.worklog h3, .splitcontentleft .widget.worklog h3, .splitcontentright .widget.worklog h3 {
25 | margin: 0;
26 | padding: 0;
27 | border: none; }
28 | #sidebar .widget.worklog .chosen-container.chosen-container-active .chosen-single b, .splitcontentleft .widget.worklog .chosen-container.chosen-container-active .chosen-single b, .splitcontentright .widget.worklog .chosen-container.chosen-container-active .chosen-single b {
29 | background-position: 3px 8px; }
30 | #sidebar .widget.worklog .chosen-container .chosen-search input, .splitcontentleft .widget.worklog .chosen-container .chosen-search input, .splitcontentright .widget.worklog .chosen-container .chosen-search input {
31 | box-shadow: none;
32 | border-color: #eee; }
33 | #sidebar .widget.worklog .chosen-container .chosen-drop, .splitcontentleft .widget.worklog .chosen-container .chosen-drop, .splitcontentright .widget.worklog .chosen-container .chosen-drop {
34 | border-color: #eee; }
35 | #sidebar .widget.worklog .chosen-container .chosen-results, .splitcontentleft .widget.worklog .chosen-container .chosen-results, .splitcontentright .widget.worklog .chosen-container .chosen-results {
36 | color: #444;
37 | position: relative;
38 | overflow-x: hidden;
39 | overflow-y: auto;
40 | margin: 0 4px 4px 0;
41 | padding: 0 0 0 4px;
42 | max-height: 240px;
43 | -webkit-overflow-scrolling: touch; }
44 | #sidebar .widget.worklog .chosen-container .chosen-results li, .splitcontentleft .widget.worklog .chosen-container .chosen-results li, .splitcontentright .widget.worklog .chosen-container .chosen-results li {
45 | display: none;
46 | margin: 0;
47 | padding: 5px 6px;
48 | list-style: none;
49 | line-height: 15px;
50 | word-wrap: break-word;
51 | -webkit-touch-callout: none; }
52 | #sidebar .widget.worklog .chosen-container .chosen-results li.active-result, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.active-result, .splitcontentright .widget.worklog .chosen-container .chosen-results li.active-result {
53 | display: list-item;
54 | cursor: pointer; }
55 | #sidebar .widget.worklog .chosen-container .chosen-results li.disabled-result, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.disabled-result, .splitcontentright .widget.worklog .chosen-container .chosen-results li.disabled-result {
56 | display: list-item;
57 | color: #ccc;
58 | cursor: default; }
59 | #sidebar .widget.worklog .chosen-container .chosen-results li.highlighted, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.highlighted, .splitcontentright .widget.worklog .chosen-container .chosen-results li.highlighted {
60 | background-color: #3875d7;
61 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
62 | background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
63 | background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
64 | background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
65 | background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
66 | color: #fff; }
67 | #sidebar .widget.worklog .chosen-container .chosen-results li.no-results, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.no-results, .splitcontentright .widget.worklog .chosen-container .chosen-results li.no-results {
68 | color: #777;
69 | display: list-item;
70 | background: #f4f4f4; }
71 | #sidebar .widget.worklog .chosen-container .chosen-results li.group-result, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.group-result, .splitcontentright .widget.worklog .chosen-container .chosen-results li.group-result {
72 | display: list-item;
73 | font-weight: bold;
74 | cursor: default; }
75 | #sidebar .widget.worklog .chosen-container .chosen-results li.group-option, .splitcontentleft .widget.worklog .chosen-container .chosen-results li.group-option, .splitcontentright .widget.worklog .chosen-container .chosen-results li.group-option {
76 | padding-left: 15px; }
77 | #sidebar .widget.worklog .chosen-container .chosen-results li .smart-link, .splitcontentleft .widget.worklog .chosen-container .chosen-results li .smart-link, .splitcontentright .widget.worklog .chosen-container .chosen-results li .smart-link {
78 | clear: right;
79 | float: right;
80 | font-size: 9px;
81 | padding: 2px 4px;
82 | background-color: #4D85BD;
83 | color: #fff;
84 | line-height: 9px;
85 | border-radius: 2px; }
86 | #sidebar .widget.worklog .chosen-container .chosen-results li em, .splitcontentleft .widget.worklog .chosen-container .chosen-results li em, .splitcontentright .widget.worklog .chosen-container .chosen-results li em {
87 | font-style: normal;
88 | text-decoration: underline; }
89 | #sidebar .widget.worklog .dropdown, .splitcontentleft .widget.worklog .dropdown, .splitcontentright .widget.worklog .dropdown {
90 | width: 80%;
91 | margin-bottom: 10px; }
92 | #sidebar .widget.worklog a.chosen-single, .splitcontentleft .widget.worklog a.chosen-single, .splitcontentright .widget.worklog a.chosen-single {
93 | display: block;
94 | padding: 6px 10px;
95 | border-color: #eee;
96 | height: 36px;
97 | background: white; }
98 | #sidebar .widget.worklog a.chosen-single b, .splitcontentleft .widget.worklog a.chosen-single b, .splitcontentright .widget.worklog a.chosen-single b {
99 | background-position: -15px 8px; }
100 | #sidebar .widget.worklog button.run, .splitcontentleft .widget.worklog button.run, .splitcontentright .widget.worklog button.run {
101 | width: 20%;
102 | margin: 0;
103 | float: right;
104 | height: 36px;
105 | line-height: 16px;
106 | border-radius: 0 2px 2px 0;
107 | left: 0;
108 | padding: 6px 0;
109 | margin-left: 0;
110 | border: none;
111 | box-shadow: none;
112 | text-shadow: none;
113 | outline: none; }
114 | #sidebar .widget.worklog button.run[value="start"], .splitcontentleft .widget.worklog button.run[value="start"], .splitcontentright .widget.worklog button.run[value="start"] {
115 | background: #5dade2;
116 | color: #fff; }
117 | #sidebar .widget.worklog button.run[value="stop"], .splitcontentleft .widget.worklog button.run[value="stop"], .splitcontentright .widget.worklog button.run[value="stop"] {
118 | background: #2ecc71;
119 | color: #fff; }
120 |
121 | .widget.worklog .timer-container .stopwatch {
122 | padding-left: 8px;
123 | font-size: 0.7rem; }
124 | .widget h3 .my-summary {
125 | float: right; }
126 | .widget h3 .my-summary.small {
127 | font-size: 0.575em; }
128 |
129 | .worktime-log.issue-toolbar {
130 | background-color: #F7F6EE;
131 | padding: 10px; }
132 |
133 | .worktimelog .issue-btn, .worktime-log .issue-btn {
134 | display: inline-block;
135 | margin: 0 1px;
136 | height: 21px;
137 | line-height: 16px;
138 | border-radius: 2px;
139 | left: 0;
140 | padding: 0 10px;
141 | margin-left: 0;
142 | border: none;
143 | box-shadow: none;
144 | text-shadow: none;
145 | background: #179e7f;
146 | color: #fff;
147 | text-decoration: none;
148 | border: inset 0 -2px 0 0 rgba(0, 0, 0, 0.2);
149 | outline: none;
150 | line-height: 21px; }
151 | .worktimelog .issue-btn.nice, .worktime-log .issue-btn.nice {
152 | background-color: #CC5E2E; }
153 |
154 | table.worktime-log-table th .day-total {
155 | font-weight: 300;
156 | font-size: 12px;
157 | border-radius: 3px;
158 | background-color: #ecf0f1;
159 | color: #7f8c8d;
160 | padding: 2px 3px;
161 | position: relative;
162 | display: inline-block; }
163 | table.worktime-log-table th .day-total::before {
164 | content: '';
165 | border: 5px transparent solid;
166 | width: 0;
167 | height: 0;
168 | display: block;
169 | padding: 0;
170 | margin: 0;
171 | top: -9px;
172 | margin-left: -5px;
173 | z-index: 2;
174 | left: 50%;
175 | line-height: 0;
176 | position: absolute;
177 | background-color: transparent;
178 | border-bottom-color: #ecf0f1; }
179 |
180 | /*!
181 | Chosen, a Select Box Enhancer for jQuery and Prototype
182 | by Patrick Filler for Harvest, http://getharvest.com
183 |
184 | Version 1.3.0
185 | Full source at https://github.com/harvesthq/chosen
186 | Copyright (c) 2011-2014 Harvest http://getharvest.com
187 |
188 | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
189 | This file is generated by `grunt build`, do not edit it by hand.
190 | */
191 | /* @group Base */
192 | .chosen-container {
193 | position: relative;
194 | display: inline-block;
195 | vertical-align: middle;
196 | font-size: 13px;
197 | zoom: 1;
198 | *display: inline;
199 | -webkit-user-select: none;
200 | -moz-user-select: none;
201 | user-select: none; }
202 | .chosen-container * {
203 | -webkit-box-sizing: border-box;
204 | -moz-box-sizing: border-box;
205 | box-sizing: border-box; }
206 | .chosen-container .chosen-drop {
207 | position: absolute;
208 | top: 100%;
209 | left: -9999px;
210 | z-index: 1010;
211 | width: 100%;
212 | border: 1px solid #aaa;
213 | border-top: 0;
214 | background: #fff;
215 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); }
216 | .chosen-container.chosen-with-drop .chosen-drop {
217 | left: 0; }
218 | .chosen-container a {
219 | cursor: pointer; }
220 |
221 | /* @end */
222 | /* @group Single Chosen */
223 | .chosen-container-single .chosen-single {
224 | position: relative;
225 | display: block;
226 | overflow: hidden;
227 | padding: 0 0 0 8px;
228 | height: 25px;
229 | border: 1px solid #aaa;
230 | border-radius: 5px;
231 | background-color: #fff;
232 | background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
233 | background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
234 | background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
235 | background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
236 | background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
237 | background-clip: padding-box;
238 | box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
239 | color: #444;
240 | text-decoration: none;
241 | white-space: nowrap;
242 | line-height: 24px; }
243 | .chosen-container-single .chosen-default {
244 | color: #999; }
245 | .chosen-container-single .chosen-single span {
246 | display: block;
247 | overflow: hidden;
248 | margin-right: 26px;
249 | text-overflow: ellipsis;
250 | white-space: nowrap; }
251 | .chosen-container-single .chosen-single-with-deselect span {
252 | margin-right: 38px; }
253 | .chosen-container-single .chosen-single abbr {
254 | position: absolute;
255 | top: 6px;
256 | right: 26px;
257 | display: block;
258 | width: 12px;
259 | height: 12px;
260 | background: url("../images/chosen-sprite.png") -42px 1px no-repeat;
261 | font-size: 1px; }
262 | .chosen-container-single .chosen-single abbr:hover {
263 | background-position: -42px -10px; }
264 | .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
265 | background-position: -42px -10px; }
266 | .chosen-container-single .chosen-single div {
267 | position: absolute;
268 | top: 0;
269 | right: 0;
270 | display: block;
271 | width: 18px;
272 | height: 100%; }
273 | .chosen-container-single .chosen-single div b {
274 | display: block;
275 | width: 100%;
276 | height: 100%;
277 | background: url("../images/chosen-sprite.png") no-repeat 0px 2px; }
278 | .chosen-container-single .chosen-search {
279 | position: relative;
280 | z-index: 1010;
281 | margin: 0;
282 | padding: 3px 4px;
283 | white-space: nowrap; }
284 | .chosen-container-single .chosen-search input[type="text"] {
285 | margin: 1px 0;
286 | padding: 4px 20px 4px 5px;
287 | width: 100%;
288 | height: auto;
289 | outline: 0;
290 | border: 1px solid #aaa;
291 | background: white url("../images/chosen-sprite.png") no-repeat 100% -20px;
292 | background: url("../images/chosen-sprite.png") no-repeat 100% -20px;
293 | font-size: 1em;
294 | font-family: sans-serif;
295 | line-height: normal;
296 | border-radius: 0; }
297 | .chosen-container-single .chosen-drop {
298 | margin-top: -1px;
299 | border-radius: 0 0 4px 4px;
300 | background-clip: padding-box; }
301 | .chosen-container-single.chosen-container-single-nosearch .chosen-search {
302 | position: absolute;
303 | left: -9999px; }
304 |
305 | /* @end */
306 | /* @group Results */
307 | .chosen-container .chosen-results {
308 | color: #444;
309 | position: relative;
310 | overflow-x: hidden;
311 | overflow-y: auto;
312 | margin: 0 4px 4px 0;
313 | padding: 0 0 0 4px;
314 | max-height: 240px;
315 | -webkit-overflow-scrolling: touch; }
316 | .chosen-container .chosen-results li {
317 | display: none;
318 | margin: 0;
319 | padding: 5px 6px;
320 | list-style: none;
321 | line-height: 15px;
322 | word-wrap: break-word;
323 | -webkit-touch-callout: none; }
324 | .chosen-container .chosen-results li.active-result {
325 | display: list-item;
326 | cursor: pointer; }
327 | .chosen-container .chosen-results li.active-result .smart-link {
328 | z-index: 10;
329 | clear: right;
330 | float: right;
331 | font-size: 9px;
332 | padding: 2px 4px;
333 | background-color: #4D85BD;
334 | color: #fff;
335 | line-height: 9px;
336 | border-radius: 2px; }
337 | .chosen-container .chosen-results li.disabled-result {
338 | display: list-item;
339 | color: #ccc;
340 | cursor: default; }
341 | .chosen-container .chosen-results li.highlighted {
342 | background-color: #3875d7;
343 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
344 | background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
345 | background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
346 | background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
347 | background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
348 | color: #fff; }
349 | .chosen-container .chosen-results li.no-results {
350 | color: #777;
351 | display: list-item;
352 | background: #f4f4f4; }
353 | .chosen-container .chosen-results li.group-result {
354 | display: list-item;
355 | font-weight: bold;
356 | cursor: default; }
357 | .chosen-container .chosen-results li.group-option {
358 | padding-left: 15px; }
359 | .chosen-container .chosen-results li em {
360 | font-style: normal;
361 | text-decoration: underline; }
362 |
363 | /* @end */
364 | /* @group Multi Chosen */
365 | .chosen-container-multi .chosen-choices {
366 | position: relative;
367 | overflow: hidden;
368 | margin: 0;
369 | padding: 0 5px;
370 | width: 100%;
371 | height: auto !important;
372 | height: 1%;
373 | border: 1px solid #aaa;
374 | background-color: #fff;
375 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
376 | background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
377 | background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
378 | background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
379 | background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
380 | cursor: text; }
381 | .chosen-container-multi .chosen-choices li {
382 | float: left;
383 | list-style: none; }
384 | .chosen-container-multi .chosen-choices li.search-field {
385 | margin: 0;
386 | padding: 0;
387 | white-space: nowrap; }
388 | .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
389 | margin: 1px 0;
390 | padding: 0;
391 | height: 25px;
392 | outline: 0;
393 | border: 0 !important;
394 | background: transparent !important;
395 | box-shadow: none;
396 | color: #999;
397 | font-size: 100%;
398 | font-family: sans-serif;
399 | line-height: normal;
400 | border-radius: 0; }
401 | .chosen-container-multi .chosen-choices li.search-choice {
402 | position: relative;
403 | margin: 3px 5px 3px 0;
404 | padding: 3px 20px 3px 5px;
405 | border: 1px solid #aaa;
406 | max-width: 100%;
407 | border-radius: 3px;
408 | background-color: #eeeeee;
409 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
410 | background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
411 | background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
412 | background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
413 | background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
414 | background-size: 100% 19px;
415 | background-repeat: repeat-x;
416 | background-clip: padding-box;
417 | box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
418 | color: #333;
419 | line-height: 13px;
420 | cursor: default; }
421 | .chosen-container-multi .chosen-choices li.search-choice span {
422 | word-wrap: break-word; }
423 | .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
424 | position: absolute;
425 | top: 4px;
426 | right: 3px;
427 | display: block;
428 | width: 12px;
429 | height: 12px;
430 | background: url("../images/chosen-sprite.png") -42px 1px no-repeat;
431 | font-size: 1px; }
432 | .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
433 | background-position: -42px -10px; }
434 | .chosen-container-multi .chosen-choices li.search-choice-disabled {
435 | padding-right: 5px;
436 | border: 1px solid #ccc;
437 | background-color: #e4e4e4;
438 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
439 | background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
440 | background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
441 | background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
442 | background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
443 | color: #666; }
444 | .chosen-container-multi .chosen-choices li.search-choice-focus {
445 | background: #d4d4d4; }
446 | .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
447 | background-position: -42px -10px; }
448 | .chosen-container-multi .chosen-results {
449 | margin: 0;
450 | padding: 0; }
451 | .chosen-container-multi .chosen-drop .result-selected {
452 | display: list-item;
453 | color: #ccc;
454 | cursor: default; }
455 |
456 | /* @end */
457 | /* @group Active */
458 | .chosen-container-active .chosen-single {
459 | border: 1px solid #5897fb;
460 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }
461 | .chosen-container-active.chosen-with-drop .chosen-single {
462 | border: 1px solid #aaa;
463 | -moz-border-radius-bottomright: 0;
464 | border-bottom-right-radius: 0;
465 | -moz-border-radius-bottomleft: 0;
466 | border-bottom-left-radius: 0;
467 | background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
468 | background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
469 | background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
470 | background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
471 | background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
472 | box-shadow: 0 1px 0 #fff inset; }
473 | .chosen-container-active.chosen-with-drop .chosen-single div {
474 | border-left: none;
475 | background: transparent; }
476 | .chosen-container-active.chosen-with-drop .chosen-single div b {
477 | background-position: -18px 2px; }
478 | .chosen-container-active .chosen-choices {
479 | border: 1px solid #5897fb;
480 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }
481 | .chosen-container-active .chosen-choices li.search-field input[type="text"] {
482 | color: #222 !important; }
483 |
484 | /* @end */
485 | /* @group Disabled Support */
486 | .chosen-disabled {
487 | opacity: 0.5 !important;
488 | cursor: default; }
489 | .chosen-disabled .chosen-single, .chosen-disabled .chosen-choices .search-choice .search-choice-close {
490 | cursor: default; }
491 |
492 | /* @end */
493 | /* @group Right to Left */
494 | .chosen-rtl {
495 | text-align: right; }
496 | .chosen-rtl .chosen-single {
497 | overflow: visible;
498 | padding: 0 8px 0 0; }
499 | .chosen-rtl .chosen-single span {
500 | margin-right: 0;
501 | margin-left: 26px;
502 | direction: rtl; }
503 | .chosen-rtl .chosen-single-with-deselect span {
504 | margin-left: 38px; }
505 | .chosen-rtl .chosen-single div {
506 | right: auto;
507 | left: 3px; }
508 | .chosen-rtl .chosen-single abbr {
509 | right: auto;
510 | left: 26px; }
511 | .chosen-rtl .chosen-choices li {
512 | float: right; }
513 | .chosen-rtl .chosen-choices li.search-field input[type="text"] {
514 | direction: rtl; }
515 | .chosen-rtl .chosen-choices li.search-choice {
516 | margin: 3px 5px 3px 0;
517 | padding: 3px 5px 3px 19px; }
518 | .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
519 | right: auto;
520 | left: 4px; }
521 | .chosen-rtl.chosen-container-single-nosearch .chosen-search, .chosen-rtl .chosen-drop {
522 | left: 9999px; }
523 | .chosen-rtl.chosen-container-single .chosen-results {
524 | margin: 0 0 4px 4px;
525 | padding: 0 4px 0 0; }
526 | .chosen-rtl .chosen-results li.group-option {
527 | padding-right: 15px;
528 | padding-left: 0; }
529 | .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
530 | border-right: none; }
531 | .chosen-rtl .chosen-search input[type="text"] {
532 | padding: 4px 5px 4px 20px;
533 | background: white url("../images/chosen-sprite.png") no-repeat -30px -20px;
534 | background: url("../images/chosen-sprite.png") no-repeat -30px -20px;
535 | direction: rtl; }
536 | .chosen-rtl.chosen-container-single .chosen-single div b {
537 | background-position: 6px 2px; }
538 | .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
539 | background-position: -12px 2px; }
540 |
541 | /* @end */
542 | /* @group Retina compatibility */
543 | @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
544 | .chosen-rtl .chosen-search input[type="text"] {
545 | background-image: url("../images/chosen-sprite@2x.png") !important;
546 | background-size: 52px 37px !important;
547 | background-repeat: no-repeat !important; }
548 |
549 | .chosen-container-single .chosen-single abbr, .chosen-container-single .chosen-single div b {
550 | background-image: url("../images/chosen-sprite@2x.png") !important;
551 | background-size: 52px 37px !important;
552 | background-repeat: no-repeat !important; }
553 | .chosen-container-single .chosen-search input[type="text"] {
554 | background-image: url("../images/chosen-sprite@2x.png") !important;
555 | background-size: 52px 37px !important;
556 | background-repeat: no-repeat !important; }
557 |
558 | .chosen-container-multi .chosen-choices .search-choice .search-choice-close {
559 | background-image: url("../images/chosen-sprite@2x.png") !important;
560 | background-size: 52px 37px !important;
561 | background-repeat: no-repeat !important; }
562 |
563 | .chosen-container .chosen-results-scroll-down span, .chosen-container .chosen-results-scroll-up span {
564 | background-image: url("../images/chosen-sprite@2x.png") !important;
565 | background-size: 52px 37px !important;
566 | background-repeat: no-repeat !important; } }
567 | /* @end */
568 |
569 | /*# sourceMappingURL=redmine_worktime_log.css.map */
570 |
--------------------------------------------------------------------------------
/assets/javascripts/vendor/jquery/jquery.chosen.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Chosen, a Select Box Enhancer for jQuery and Prototype
3 | by Patrick Filler for Harvest, http://getharvest.com
4 |
5 | Version 1.3.0
6 | Full source at https://github.com/harvesthq/chosen
7 | Copyright (c) 2011-2014 Harvest http://getharvest.com
8 |
9 | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10 | This file is generated by `grunt build`, do not edit it by hand.
11 | */
12 |
13 | (function() {
14 | var $, AbstractChosen, Chosen, SelectParser, _ref,
15 | __hasProp = {}.hasOwnProperty,
16 | __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17 |
18 | SelectParser = (function() {
19 | function SelectParser() {
20 | this.options_index = 0;
21 | this.parsed = [];
22 | }
23 |
24 | SelectParser.prototype.add_node = function(child) {
25 | if (child.nodeName.toUpperCase() === "OPTGROUP") {
26 | return this.add_group(child);
27 | } else {
28 | return this.add_option(child);
29 | }
30 | };
31 |
32 | SelectParser.prototype.add_group = function(group) {
33 | var group_position, option, _i, _len, _ref, _results;
34 | group_position = this.parsed.length;
35 | this.parsed.push({
36 | array_index: group_position,
37 | group: true,
38 | label: this.escapeExpression(group.label),
39 | children: 0,
40 | disabled: group.disabled,
41 | classes: group.className
42 | });
43 | _ref = group.childNodes;
44 | _results = [];
45 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
46 | option = _ref[_i];
47 | _results.push(this.add_option(option, group_position, group.disabled));
48 | }
49 | return _results;
50 | };
51 |
52 | SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
53 | if (option.nodeName.toUpperCase() === "OPTION") {
54 | if (option.text !== "") {
55 | if (group_position != null) {
56 | this.parsed[group_position].children += 1;
57 | }
58 | this.parsed.push({
59 | array_index: this.parsed.length,
60 | options_index: this.options_index,
61 | value: option.value,
62 | text: option.text,
63 | html: option.innerHTML,
64 | selected: option.selected,
65 | disabled: group_disabled === true ? group_disabled : option.disabled,
66 | group_array_index: group_position,
67 | classes: option.className,
68 | style: option.style.cssText
69 | });
70 | } else {
71 | this.parsed.push({
72 | array_index: this.parsed.length,
73 | options_index: this.options_index,
74 | empty: true
75 | });
76 | }
77 | return this.options_index += 1;
78 | }
79 | };
80 |
81 | SelectParser.prototype.escapeExpression = function(text) {
82 | var map, unsafe_chars;
83 | if ((text == null) || text === false) {
84 | return "";
85 | }
86 | if (!/[\&\<\>\"\'\`]/.test(text)) {
87 | return text;
88 | }
89 | map = {
90 | "<": "<",
91 | ">": ">",
92 | '"': """,
93 | "'": "'",
94 | "`": "`"
95 | };
96 | unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
97 | return text.replace(unsafe_chars, function(chr) {
98 | return map[chr] || "&";
99 | });
100 | };
101 |
102 | return SelectParser;
103 |
104 | })();
105 |
106 | SelectParser.select_to_array = function(select) {
107 | var child, parser, _i, _len, _ref;
108 | parser = new SelectParser();
109 | _ref = select.childNodes;
110 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
111 | child = _ref[_i];
112 | parser.add_node(child);
113 | }
114 | return parser.parsed;
115 | };
116 |
117 | AbstractChosen = (function() {
118 | function AbstractChosen(form_field, options) {
119 | this.form_field = form_field;
120 | this.options = options != null ? options : {};
121 | if (!AbstractChosen.browser_is_supported()) {
122 | return;
123 | }
124 | this.is_multiple = this.form_field.multiple;
125 | this.set_default_text();
126 | this.set_default_values();
127 | this.setup();
128 | this.set_up_html();
129 | this.register_observers();
130 | this.on_ready();
131 | }
132 |
133 | AbstractChosen.prototype.set_default_values = function() {
134 | var _this = this;
135 | this.click_test_action = function(evt) {
136 | return _this.test_active_click(evt);
137 | };
138 | this.activate_action = function(evt) {
139 | return _this.activate_field(evt);
140 | };
141 | this.active_field = false;
142 | this.mouse_on_container = false;
143 | this.results_showing = false;
144 | this.result_highlighted = null;
145 | this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
146 | this.disable_search_threshold = this.options.disable_search_threshold || 0;
147 | this.disable_search = this.options.disable_search || false;
148 | this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
149 | this.group_search = this.options.group_search != null ? this.options.group_search : true;
150 | this.search_contains = this.options.search_contains || false;
151 | this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
152 | this.max_selected_options = this.options.max_selected_options || Infinity;
153 | this.inherit_select_classes = this.options.inherit_select_classes || false;
154 | this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
155 | return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
156 | };
157 |
158 | AbstractChosen.prototype.set_default_text = function() {
159 | if (this.form_field.getAttribute("data-placeholder")) {
160 | this.default_text = this.form_field.getAttribute("data-placeholder");
161 | } else if (this.is_multiple) {
162 | this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
163 | } else {
164 | this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
165 | }
166 | return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
167 | };
168 |
169 | AbstractChosen.prototype.mouse_enter = function() {
170 | return this.mouse_on_container = true;
171 | };
172 |
173 | AbstractChosen.prototype.mouse_leave = function() {
174 | return this.mouse_on_container = false;
175 | };
176 |
177 | AbstractChosen.prototype.input_focus = function(evt) {
178 | var _this = this;
179 | if (this.is_multiple) {
180 | if (!this.active_field) {
181 | return setTimeout((function() {
182 | return _this.container_mousedown();
183 | }), 50);
184 | }
185 | } else {
186 | if (!this.active_field) {
187 | return this.activate_field();
188 | }
189 | }
190 | };
191 |
192 | AbstractChosen.prototype.input_blur = function(evt) {
193 | var _this = this;
194 | if (!this.mouse_on_container) {
195 | this.active_field = false;
196 | return setTimeout((function() {
197 | return _this.blur_test();
198 | }), 100);
199 | }
200 | };
201 |
202 | AbstractChosen.prototype.results_option_build = function(options) {
203 | var content, data, _i, _len, _ref;
204 | content = '';
205 | _ref = this.results_data;
206 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
207 | data = _ref[_i];
208 | if (data.group) {
209 | content += this.result_add_group(data);
210 | } else {
211 | content += this.result_add_option(data);
212 | }
213 | if (options != null ? options.first : void 0) {
214 | if (data.selected && this.is_multiple) {
215 | this.choice_build(data);
216 | } else if (data.selected && !this.is_multiple) {
217 | this.single_set_selected_text(data.text);
218 | }
219 | }
220 | }
221 | return content;
222 | };
223 |
224 | AbstractChosen.prototype.result_add_option = function(option) {
225 | var classes, option_el;
226 | if (!option.search_match) {
227 | return '';
228 | }
229 | if (!this.include_option_in_results(option)) {
230 | return '';
231 | }
232 | classes = [];
233 | if (!option.disabled && !(option.selected && this.is_multiple)) {
234 | classes.push("active-result");
235 | }
236 | if (option.disabled && !(option.selected && this.is_multiple)) {
237 | classes.push("disabled-result");
238 | }
239 | if (option.selected) {
240 | classes.push("result-selected");
241 | }
242 | if (option.group_array_index != null) {
243 | classes.push("group-option");
244 | }
245 | if (option.classes !== "") {
246 | classes.push(option.classes);
247 | }
248 | var option_obj = this.form_field.options[option.array_index];
249 | option_el = document.createElement("li");
250 | option_el.className = classes.join(" ");
251 | option_el.style.cssText = option.style;
252 | option_el.setAttribute("data-option-array-index", option.array_index);
253 | option_el.innerHTML = option.search_text;
254 | if ($(option_obj).data('href')) {
255 | link_el = document.createElement("a");
256 | link_el.className = "smart-link";
257 | link_el.href = $(option_obj).data('href');
258 | link_el.innerHTML = "L";
259 | link_el.onclick = function(event){
260 | event.stopPropagation();
261 | return window.location.href = $(option_obj).data('href');
262 | };
263 |
264 | option_el.appendChild(link_el);
265 | }
266 | return this.outerHTML(option_el);
267 | };
268 |
269 | AbstractChosen.prototype.result_add_group = function(group) {
270 | var classes, group_el;
271 | if (!(group.search_match || group.group_match)) {
272 | return '';
273 | }
274 | if (!(group.active_options > 0)) {
275 | return '';
276 | }
277 | classes = [];
278 | classes.push("group-result");
279 | if (group.classes) {
280 | classes.push(group.classes);
281 | }
282 | group_el = document.createElement("li");
283 | group_el.className = classes.join(" ");
284 | group_el.innerHTML = group.search_text;
285 | return this.outerHTML(group_el);
286 | };
287 |
288 | AbstractChosen.prototype.results_update_field = function() {
289 | this.set_default_text();
290 | if (!this.is_multiple) {
291 | this.results_reset_cleanup();
292 | }
293 | this.result_clear_highlight();
294 | this.results_build();
295 | if (this.results_showing) {
296 | return this.winnow_results();
297 | }
298 | };
299 |
300 | AbstractChosen.prototype.reset_single_select_options = function() {
301 | var result, _i, _len, _ref, _results;
302 | _ref = this.results_data;
303 | _results = [];
304 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
305 | result = _ref[_i];
306 | if (result.selected) {
307 | _results.push(result.selected = false);
308 | } else {
309 | _results.push(void 0);
310 | }
311 | }
312 | return _results;
313 | };
314 |
315 | AbstractChosen.prototype.results_toggle = function() {
316 | if (this.results_showing) {
317 | return this.results_hide();
318 | } else {
319 | return this.results_show();
320 | }
321 | };
322 |
323 | AbstractChosen.prototype.results_search = function(evt) {
324 | if (this.results_showing) {
325 | return this.winnow_results();
326 | } else {
327 | return this.results_show();
328 | }
329 | };
330 |
331 | AbstractChosen.prototype.winnow_results = function() {
332 | var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
333 | this.no_results_clear();
334 | results = 0;
335 | searchText = this.get_search_text();
336 | escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
337 | zregex = new RegExp(escapedSearchText, 'i');
338 | regex = this.get_search_regex(escapedSearchText);
339 | _ref = this.results_data;
340 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
341 | option = _ref[_i];
342 | option.search_match = false;
343 | results_group = null;
344 | if (this.include_option_in_results(option)) {
345 | if (option.group) {
346 | option.group_match = false;
347 | option.active_options = 0;
348 | }
349 | if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
350 | results_group = this.results_data[option.group_array_index];
351 | if (results_group.active_options === 0 && results_group.search_match) {
352 | results += 1;
353 | }
354 | results_group.active_options += 1;
355 | }
356 | if (!(option.group && !this.group_search)) {
357 | option.search_text = option.group ? option.label : option.text;
358 | option.search_match = this.search_string_match(option.search_text, regex);
359 | if (option.search_match && !option.group) {
360 | results += 1;
361 | }
362 | if (option.search_match) {
363 | if (searchText.length) {
364 | startpos = option.search_text.search(zregex);
365 | text = option.search_text.substr(0, startpos + searchText.length) + '' + option.search_text.substr(startpos + searchText.length);
366 | option.search_text = text.substr(0, startpos) + '' + text.substr(startpos);
367 | }
368 | if (results_group != null) {
369 | results_group.group_match = true;
370 | }
371 | } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
372 | option.search_match = true;
373 | }
374 | }
375 | }
376 | }
377 | this.result_clear_highlight();
378 | if (results < 1 && searchText.length) {
379 | this.update_results_content("");
380 | return this.no_results(searchText);
381 | } else {
382 | this.update_results_content(this.results_option_build());
383 | return this.winnow_results_set_highlight();
384 | }
385 | };
386 |
387 | AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
388 | var regex_anchor;
389 | regex_anchor = this.search_contains ? "" : "^";
390 | return new RegExp(regex_anchor + escaped_search_string, 'i');
391 | };
392 |
393 | AbstractChosen.prototype.search_string_match = function(search_string, regex) {
394 | var part, parts, _i, _len;
395 | if (regex.test(search_string)) {
396 | return true;
397 | } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
398 | parts = search_string.replace(/\[|\]/g, "").split(" ");
399 | if (parts.length) {
400 | for (_i = 0, _len = parts.length; _i < _len; _i++) {
401 | part = parts[_i];
402 | if (regex.test(part)) {
403 | return true;
404 | }
405 | }
406 | }
407 | }
408 | };
409 |
410 | AbstractChosen.prototype.choices_count = function() {
411 | var option, _i, _len, _ref;
412 | if (this.selected_option_count != null) {
413 | return this.selected_option_count;
414 | }
415 | this.selected_option_count = 0;
416 | _ref = this.form_field.options;
417 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
418 | option = _ref[_i];
419 | if (option.selected) {
420 | this.selected_option_count += 1;
421 | }
422 | }
423 | return this.selected_option_count;
424 | };
425 |
426 | AbstractChosen.prototype.choices_click = function(evt) {
427 | evt.preventDefault();
428 | if (!(this.results_showing || this.is_disabled)) {
429 | return this.results_show();
430 | }
431 | };
432 |
433 | AbstractChosen.prototype.keyup_checker = function(evt) {
434 | var stroke, _ref;
435 | stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
436 | this.search_field_scale();
437 | switch (stroke) {
438 | case 8:
439 | if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
440 | return this.keydown_backstroke();
441 | } else if (!this.pending_backstroke) {
442 | this.result_clear_highlight();
443 | return this.results_search();
444 | }
445 | break;
446 | case 13:
447 | evt.preventDefault();
448 | if (this.results_showing) {
449 | return this.result_select(evt);
450 | }
451 | break;
452 | case 27:
453 | if (this.results_showing) {
454 | this.results_hide();
455 | }
456 | return true;
457 | case 9:
458 | case 38:
459 | case 40:
460 | case 16:
461 | case 91:
462 | case 17:
463 | break;
464 | default:
465 | return this.results_search();
466 | }
467 | };
468 |
469 | AbstractChosen.prototype.clipboard_event_checker = function(evt) {
470 | var _this = this;
471 | return setTimeout((function() {
472 | return _this.results_search();
473 | }), 50);
474 | };
475 |
476 | AbstractChosen.prototype.container_width = function() {
477 | if (this.options.width != null) {
478 | return this.options.width;
479 | } else {
480 | return "" + this.form_field.offsetWidth + "px";
481 | }
482 | };
483 |
484 | AbstractChosen.prototype.include_option_in_results = function(option) {
485 | if (this.is_multiple && (!this.display_selected_options && option.selected)) {
486 | return false;
487 | }
488 | if (!this.display_disabled_options && option.disabled) {
489 | return false;
490 | }
491 | if (option.empty) {
492 | return false;
493 | }
494 | return true;
495 | };
496 |
497 | AbstractChosen.prototype.search_results_touchstart = function(evt) {
498 | this.touch_started = true;
499 | return this.search_results_mouseover(evt);
500 | };
501 |
502 | AbstractChosen.prototype.search_results_touchmove = function(evt) {
503 | this.touch_started = false;
504 | return this.search_results_mouseout(evt);
505 | };
506 |
507 | AbstractChosen.prototype.search_results_touchend = function(evt) {
508 | if (this.touch_started) {
509 | return this.search_results_mouseup(evt);
510 | }
511 | };
512 |
513 | AbstractChosen.prototype.outerHTML = function(element) {
514 | var tmp;
515 | if (element.outerHTML) {
516 | return element.outerHTML;
517 | }
518 | tmp = document.createElement("div");
519 | tmp.appendChild(element);
520 | return tmp.innerHTML;
521 | };
522 |
523 | AbstractChosen.browser_is_supported = function() {
524 | if (window.navigator.appName === "Microsoft Internet Explorer") {
525 | return document.documentMode >= 8;
526 | }
527 | if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
528 | return false;
529 | }
530 | if (/Android/i.test(window.navigator.userAgent)) {
531 | if (/Mobile/i.test(window.navigator.userAgent)) {
532 | return false;
533 | }
534 | }
535 | return true;
536 | };
537 |
538 | AbstractChosen.default_multiple_text = "Select Some Options";
539 |
540 | AbstractChosen.default_single_text = "Select an Option";
541 |
542 | AbstractChosen.default_no_result_text = "No results match";
543 |
544 | return AbstractChosen;
545 |
546 | })();
547 |
548 | $ = jQuery;
549 |
550 | $.fn.extend({
551 | chosen: function(options) {
552 | if (!AbstractChosen.browser_is_supported()) {
553 | return this;
554 | }
555 | return this.each(function(input_field) {
556 | var $this, chosen;
557 | $this = $(this);
558 | chosen = $this.data('chosen');
559 | if (options === 'destroy' && chosen instanceof Chosen) {
560 | chosen.destroy();
561 | } else if (!(chosen instanceof Chosen)) {
562 | $this.data('chosen', new Chosen(this, options));
563 | }
564 | });
565 | }
566 | });
567 |
568 | Chosen = (function(_super) {
569 | __extends(Chosen, _super);
570 |
571 | function Chosen() {
572 | _ref = Chosen.__super__.constructor.apply(this, arguments);
573 | return _ref;
574 | }
575 |
576 | Chosen.prototype.setup = function() {
577 | this.form_field_jq = $(this.form_field);
578 | this.current_selectedIndex = this.form_field.selectedIndex;
579 | return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
580 | };
581 |
582 | Chosen.prototype.set_up_html = function() {
583 | var container_classes, container_props;
584 | container_classes = ["chosen-container"];
585 | container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
586 | if (this.inherit_select_classes && this.form_field.className) {
587 | container_classes.push(this.form_field.className);
588 | }
589 | if (this.is_rtl) {
590 | container_classes.push("chosen-rtl");
591 | }
592 | container_props = {
593 | 'class': container_classes.join(' '),
594 | 'style': "width: " + (this.container_width()) + ";",
595 | 'title': this.form_field.title
596 | };
597 | if (this.form_field.id.length) {
598 | container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
599 | }
600 | this.container = $("
", container_props);
601 | if (this.is_multiple) {
602 | this.container.html('');
603 | } else {
604 | this.container.html('' + this.default_text + '
');
605 | }
606 | this.form_field_jq.hide().after(this.container);
607 | this.dropdown = this.container.find('div.chosen-drop').first();
608 | this.search_field = this.container.find('input').first();
609 | this.search_results = this.container.find('ul.chosen-results').first();
610 | this.search_field_scale();
611 | this.search_no_results = this.container.find('li.no-results').first();
612 | if (this.is_multiple) {
613 | this.search_choices = this.container.find('ul.chosen-choices').first();
614 | this.search_container = this.container.find('li.search-field').first();
615 | } else {
616 | this.search_container = this.container.find('div.chosen-search').first();
617 | this.selected_item = this.container.find('.chosen-single').first();
618 | }
619 | this.results_build();
620 | this.set_tab_index();
621 | return this.set_label_behavior();
622 | };
623 |
624 | Chosen.prototype.on_ready = function() {
625 | return this.form_field_jq.trigger("chosen:ready", {
626 | chosen: this
627 | });
628 | };
629 |
630 | Chosen.prototype.register_observers = function() {
631 | var _this = this;
632 | this.container.bind('touchstart.chosen', function(evt) {
633 | _this.container_mousedown(evt);
634 | });
635 | this.container.bind('touchend.chosen', function(evt) {
636 | _this.container_mouseup(evt);
637 | });
638 | this.container.bind('mousedown.chosen', function(evt) {
639 | _this.container_mousedown(evt);
640 | });
641 | this.container.bind('mouseup.chosen', function(evt) {
642 | _this.container_mouseup(evt);
643 | });
644 | this.container.bind('mouseenter.chosen', function(evt) {
645 | _this.mouse_enter(evt);
646 | });
647 | this.container.bind('mouseleave.chosen', function(evt) {
648 | _this.mouse_leave(evt);
649 | });
650 | this.search_results.bind('mouseup.chosen', function(evt) {
651 | _this.search_results_mouseup(evt);
652 | });
653 | this.search_results.bind('mouseover.chosen', function(evt) {
654 | _this.search_results_mouseover(evt);
655 | });
656 | this.search_results.bind('mouseout.chosen', function(evt) {
657 | _this.search_results_mouseout(evt);
658 | });
659 | this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
660 | _this.search_results_mousewheel(evt);
661 | });
662 | this.search_results.bind('touchstart.chosen', function(evt) {
663 | _this.search_results_touchstart(evt);
664 | });
665 | this.search_results.bind('touchmove.chosen', function(evt) {
666 | _this.search_results_touchmove(evt);
667 | });
668 | this.search_results.bind('touchend.chosen', function(evt) {
669 | _this.search_results_touchend(evt);
670 | });
671 | this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
672 | _this.results_update_field(evt);
673 | });
674 | this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
675 | _this.activate_field(evt);
676 | });
677 | this.form_field_jq.bind("chosen:open.chosen", function(evt) {
678 | _this.container_mousedown(evt);
679 | });
680 | this.form_field_jq.bind("chosen:close.chosen", function(evt) {
681 | _this.input_blur(evt);
682 | });
683 | this.search_field.bind('blur.chosen', function(evt) {
684 | _this.input_blur(evt);
685 | });
686 | this.search_field.bind('keyup.chosen', function(evt) {
687 | _this.keyup_checker(evt);
688 | });
689 | this.search_field.bind('keydown.chosen', function(evt) {
690 | _this.keydown_checker(evt);
691 | });
692 | this.search_field.bind('focus.chosen', function(evt) {
693 | _this.input_focus(evt);
694 | });
695 | this.search_field.bind('cut.chosen', function(evt) {
696 | _this.clipboard_event_checker(evt);
697 | });
698 | this.search_field.bind('paste.chosen', function(evt) {
699 | _this.clipboard_event_checker(evt);
700 | });
701 | if (this.is_multiple) {
702 | return this.search_choices.bind('click.chosen', function(evt) {
703 | _this.choices_click(evt);
704 | });
705 | } else {
706 | return this.container.bind('click.chosen', function(evt) {
707 | evt.preventDefault();
708 | });
709 | }
710 | };
711 |
712 | Chosen.prototype.destroy = function() {
713 | $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
714 | if (this.search_field[0].tabIndex) {
715 | this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
716 | }
717 | this.container.remove();
718 | this.form_field_jq.removeData('chosen');
719 | return this.form_field_jq.show();
720 | };
721 |
722 | Chosen.prototype.search_field_disabled = function() {
723 | this.is_disabled = this.form_field_jq[0].disabled;
724 | if (this.is_disabled) {
725 | this.container.addClass('chosen-disabled');
726 | this.search_field[0].disabled = true;
727 | if (!this.is_multiple) {
728 | this.selected_item.unbind("focus.chosen", this.activate_action);
729 | }
730 | return this.close_field();
731 | } else {
732 | this.container.removeClass('chosen-disabled');
733 | this.search_field[0].disabled = false;
734 | if (!this.is_multiple) {
735 | return this.selected_item.bind("focus.chosen", this.activate_action);
736 | }
737 | }
738 | };
739 |
740 | Chosen.prototype.container_mousedown = function(evt) {
741 | if (!this.is_disabled) {
742 | if (evt && evt.type === "mousedown" && !this.results_showing) {
743 | evt.preventDefault();
744 | }
745 | if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
746 | if (!this.active_field) {
747 | if (this.is_multiple) {
748 | this.search_field.val("");
749 | }
750 | $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
751 | this.results_show();
752 | } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
753 | evt.preventDefault();
754 | this.results_toggle();
755 | }
756 | return this.activate_field();
757 | }
758 | }
759 | };
760 |
761 | Chosen.prototype.container_mouseup = function(evt) {
762 | if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
763 | return this.results_reset(evt);
764 | }
765 | };
766 |
767 | Chosen.prototype.search_results_mousewheel = function(evt) {
768 | var delta;
769 | if (evt.originalEvent) {
770 | delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
771 | }
772 | if (delta != null) {
773 | evt.preventDefault();
774 | if (evt.type === 'DOMMouseScroll') {
775 | delta = delta * 40;
776 | }
777 | return this.search_results.scrollTop(delta + this.search_results.scrollTop());
778 | }
779 | };
780 |
781 | Chosen.prototype.blur_test = function(evt) {
782 | if (!this.active_field && this.container.hasClass("chosen-container-active")) {
783 | return this.close_field();
784 | }
785 | };
786 |
787 | Chosen.prototype.close_field = function() {
788 | $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
789 | this.active_field = false;
790 | this.results_hide();
791 | this.container.removeClass("chosen-container-active");
792 | this.clear_backstroke();
793 | this.show_search_field_default();
794 | return this.search_field_scale();
795 | };
796 |
797 | Chosen.prototype.activate_field = function() {
798 | this.container.addClass("chosen-container-active");
799 | this.active_field = true;
800 | this.search_field.val(this.search_field.val());
801 | return this.search_field.focus();
802 | };
803 |
804 | Chosen.prototype.test_active_click = function(evt) {
805 | var active_container;
806 | active_container = $(evt.target).closest('.chosen-container');
807 | if (active_container.length && this.container[0] === active_container[0]) {
808 | return this.active_field = true;
809 | } else {
810 | return this.close_field();
811 | }
812 | };
813 |
814 | Chosen.prototype.results_build = function() {
815 | this.parsing = true;
816 | this.selected_option_count = null;
817 | this.results_data = SelectParser.select_to_array(this.form_field);
818 | if (this.is_multiple) {
819 | this.search_choices.find("li.search-choice").remove();
820 | } else if (!this.is_multiple) {
821 | this.single_set_selected_text();
822 | if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
823 | this.search_field[0].readOnly = true;
824 | this.container.addClass("chosen-container-single-nosearch");
825 | } else {
826 | this.search_field[0].readOnly = false;
827 | this.container.removeClass("chosen-container-single-nosearch");
828 | }
829 | }
830 | this.update_results_content(this.results_option_build({
831 | first: true
832 | }));
833 | this.search_field_disabled();
834 | this.show_search_field_default();
835 | this.search_field_scale();
836 | return this.parsing = false;
837 | };
838 |
839 | Chosen.prototype.result_do_highlight = function(el) {
840 | var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
841 | if (el.length) {
842 | this.result_clear_highlight();
843 | this.result_highlight = el;
844 | this.result_highlight.addClass("highlighted");
845 | maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
846 | visible_top = this.search_results.scrollTop();
847 | visible_bottom = maxHeight + visible_top;
848 | high_top = this.result_highlight.position().top + this.search_results.scrollTop();
849 | high_bottom = high_top + this.result_highlight.outerHeight();
850 | if (high_bottom >= visible_bottom) {
851 | return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
852 | } else if (high_top < visible_top) {
853 | return this.search_results.scrollTop(high_top);
854 | }
855 | }
856 | };
857 |
858 | Chosen.prototype.result_clear_highlight = function() {
859 | if (this.result_highlight) {
860 | this.result_highlight.removeClass("highlighted");
861 | }
862 | return this.result_highlight = null;
863 | };
864 |
865 | Chosen.prototype.results_show = function() {
866 | if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
867 | this.form_field_jq.trigger("chosen:maxselected", {
868 | chosen: this
869 | });
870 | return false;
871 | }
872 | this.container.addClass("chosen-with-drop");
873 | this.results_showing = true;
874 | this.search_field.focus();
875 | this.search_field.val(this.search_field.val());
876 | this.winnow_results();
877 | return this.form_field_jq.trigger("chosen:showing_dropdown", {
878 | chosen: this
879 | });
880 | };
881 |
882 | Chosen.prototype.update_results_content = function(content) {
883 | return this.search_results.html(content);
884 | };
885 |
886 | Chosen.prototype.results_hide = function() {
887 | if (this.results_showing) {
888 | this.result_clear_highlight();
889 | this.container.removeClass("chosen-with-drop");
890 | this.form_field_jq.trigger("chosen:hiding_dropdown", {
891 | chosen: this
892 | });
893 | }
894 | return this.results_showing = false;
895 | };
896 |
897 | Chosen.prototype.set_tab_index = function(el) {
898 | var ti;
899 | if (this.form_field.tabIndex) {
900 | ti = this.form_field.tabIndex;
901 | this.form_field.tabIndex = -1;
902 | return this.search_field[0].tabIndex = ti;
903 | }
904 | };
905 |
906 | Chosen.prototype.set_label_behavior = function() {
907 | var _this = this;
908 | this.form_field_label = this.form_field_jq.parents("label");
909 | if (!this.form_field_label.length && this.form_field.id.length) {
910 | this.form_field_label = $("label[for='" + this.form_field.id + "']");
911 | }
912 | if (this.form_field_label.length > 0) {
913 | return this.form_field_label.bind('click.chosen', function(evt) {
914 | if (_this.is_multiple) {
915 | return _this.container_mousedown(evt);
916 | } else {
917 | return _this.activate_field();
918 | }
919 | });
920 | }
921 | };
922 |
923 | Chosen.prototype.show_search_field_default = function() {
924 | if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
925 | this.search_field.val(this.default_text);
926 | return this.search_field.addClass("default");
927 | } else {
928 | this.search_field.val("");
929 | return this.search_field.removeClass("default");
930 | }
931 | };
932 |
933 | Chosen.prototype.search_results_mouseup = function(evt) {
934 | var target;
935 | target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
936 | if (target.length) {
937 | this.result_highlight = target;
938 | this.result_select(evt);
939 | return this.search_field.focus();
940 | }
941 | };
942 |
943 | Chosen.prototype.search_results_mouseover = function(evt) {
944 | var target;
945 | target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
946 | if (target) {
947 | return this.result_do_highlight(target);
948 | }
949 | };
950 |
951 | Chosen.prototype.search_results_mouseout = function(evt) {
952 | if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
953 | return this.result_clear_highlight();
954 | }
955 | };
956 |
957 | Chosen.prototype.choice_build = function(item) {
958 | var choice, close_link,
959 | _this = this;
960 | choice = $(' ', {
961 | "class": "search-choice"
962 | }).html("" + item.html + " ");
963 | if (item.disabled) {
964 | choice.addClass('search-choice-disabled');
965 | } else {
966 | close_link = $(' ', {
967 | "class": 'search-choice-close',
968 | 'data-option-array-index': item.array_index
969 | });
970 | close_link.bind('click.chosen', function(evt) {
971 | return _this.choice_destroy_link_click(evt);
972 | });
973 | choice.append(close_link);
974 | }
975 | return this.search_container.before(choice);
976 | };
977 |
978 | Chosen.prototype.choice_destroy_link_click = function(evt) {
979 | evt.preventDefault();
980 | evt.stopPropagation();
981 | if (!this.is_disabled) {
982 | return this.choice_destroy($(evt.target));
983 | }
984 | };
985 |
986 | Chosen.prototype.choice_destroy = function(link) {
987 | if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
988 | this.show_search_field_default();
989 | if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
990 | this.results_hide();
991 | }
992 | link.parents('li').first().remove();
993 | return this.search_field_scale();
994 | }
995 | };
996 |
997 | Chosen.prototype.results_reset = function() {
998 | this.reset_single_select_options();
999 | this.form_field.options[0].selected = true;
1000 | this.single_set_selected_text();
1001 | this.show_search_field_default();
1002 | this.results_reset_cleanup();
1003 | this.form_field_jq.trigger("change");
1004 | if (this.active_field) {
1005 | return this.results_hide();
1006 | }
1007 | };
1008 |
1009 | Chosen.prototype.results_reset_cleanup = function() {
1010 | this.current_selectedIndex = this.form_field.selectedIndex;
1011 | return this.selected_item.find("abbr").remove();
1012 | };
1013 |
1014 | Chosen.prototype.result_select = function(evt) {
1015 | var high, item;
1016 | if (this.result_highlight) {
1017 | high = this.result_highlight;
1018 | this.result_clear_highlight();
1019 | if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
1020 | this.form_field_jq.trigger("chosen:maxselected", {
1021 | chosen: this
1022 | });
1023 | return false;
1024 | }
1025 | if (this.is_multiple) {
1026 | high.removeClass("active-result");
1027 | } else {
1028 | this.reset_single_select_options();
1029 | }
1030 | item = this.results_data[high[0].getAttribute("data-option-array-index")];
1031 | item.selected = true;
1032 | this.form_field.options[item.options_index].selected = true;
1033 | this.selected_option_count = null;
1034 | if (this.is_multiple) {
1035 | this.choice_build(item);
1036 | } else {
1037 | this.single_set_selected_text(item.text);
1038 | }
1039 | if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1040 | this.results_hide();
1041 | }
1042 | this.search_field.val("");
1043 | if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1044 | this.form_field_jq.trigger("change", {
1045 | 'selected': this.form_field.options[item.options_index].value
1046 | });
1047 | }
1048 | this.current_selectedIndex = this.form_field.selectedIndex;
1049 | return this.search_field_scale();
1050 | }
1051 | };
1052 |
1053 | Chosen.prototype.single_set_selected_text = function(text) {
1054 | if (text == null) {
1055 | text = this.default_text;
1056 | }
1057 | if (text === this.default_text) {
1058 | this.selected_item.addClass("chosen-default");
1059 | } else {
1060 | this.single_deselect_control_build();
1061 | this.selected_item.removeClass("chosen-default");
1062 | }
1063 | return this.selected_item.find("span").text(text);
1064 | };
1065 |
1066 | Chosen.prototype.result_deselect = function(pos) {
1067 | var result_data;
1068 | result_data = this.results_data[pos];
1069 | if (!this.form_field.options[result_data.options_index].disabled) {
1070 | result_data.selected = false;
1071 | this.form_field.options[result_data.options_index].selected = false;
1072 | this.selected_option_count = null;
1073 | this.result_clear_highlight();
1074 | if (this.results_showing) {
1075 | this.winnow_results();
1076 | }
1077 | this.form_field_jq.trigger("change", {
1078 | deselected: this.form_field.options[result_data.options_index].value
1079 | });
1080 | this.search_field_scale();
1081 | return true;
1082 | } else {
1083 | return false;
1084 | }
1085 | };
1086 |
1087 | Chosen.prototype.single_deselect_control_build = function() {
1088 | if (!this.allow_single_deselect) {
1089 | return;
1090 | }
1091 | if (!this.selected_item.find("abbr").length) {
1092 | this.selected_item.find("span").first().after(" ");
1093 | }
1094 | return this.selected_item.addClass("chosen-single-with-deselect");
1095 | };
1096 |
1097 | Chosen.prototype.get_search_text = function() {
1098 | if (this.search_field.val() === this.default_text) {
1099 | return "";
1100 | } else {
1101 | return $('
').text($.trim(this.search_field.val())).html();
1102 | }
1103 | };
1104 |
1105 | Chosen.prototype.winnow_results_set_highlight = function() {
1106 | var do_high, selected_results;
1107 | selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1108 | do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1109 | if (do_high != null) {
1110 | return this.result_do_highlight(do_high);
1111 | }
1112 | };
1113 |
1114 | Chosen.prototype.no_results = function(terms) {
1115 | var no_results_html;
1116 | no_results_html = $('' + this.results_none_found + ' " " ');
1117 | no_results_html.find("span").first().html(terms);
1118 | this.search_results.append(no_results_html);
1119 | return this.form_field_jq.trigger("chosen:no_results", {
1120 | chosen: this
1121 | });
1122 | };
1123 |
1124 | Chosen.prototype.no_results_clear = function() {
1125 | return this.search_results.find(".no-results").remove();
1126 | };
1127 |
1128 | Chosen.prototype.keydown_arrow = function() {
1129 | var next_sib;
1130 | if (this.results_showing && this.result_highlight) {
1131 | next_sib = this.result_highlight.nextAll("li.active-result").first();
1132 | if (next_sib) {
1133 | return this.result_do_highlight(next_sib);
1134 | }
1135 | } else {
1136 | return this.results_show();
1137 | }
1138 | };
1139 |
1140 | Chosen.prototype.keyup_arrow = function() {
1141 | var prev_sibs;
1142 | if (!this.results_showing && !this.is_multiple) {
1143 | return this.results_show();
1144 | } else if (this.result_highlight) {
1145 | prev_sibs = this.result_highlight.prevAll("li.active-result");
1146 | if (prev_sibs.length) {
1147 | return this.result_do_highlight(prev_sibs.first());
1148 | } else {
1149 | if (this.choices_count() > 0) {
1150 | this.results_hide();
1151 | }
1152 | return this.result_clear_highlight();
1153 | }
1154 | }
1155 | };
1156 |
1157 | Chosen.prototype.keydown_backstroke = function() {
1158 | var next_available_destroy;
1159 | if (this.pending_backstroke) {
1160 | this.choice_destroy(this.pending_backstroke.find("a").first());
1161 | return this.clear_backstroke();
1162 | } else {
1163 | next_available_destroy = this.search_container.siblings("li.search-choice").last();
1164 | if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1165 | this.pending_backstroke = next_available_destroy;
1166 | if (this.single_backstroke_delete) {
1167 | return this.keydown_backstroke();
1168 | } else {
1169 | return this.pending_backstroke.addClass("search-choice-focus");
1170 | }
1171 | }
1172 | }
1173 | };
1174 |
1175 | Chosen.prototype.clear_backstroke = function() {
1176 | if (this.pending_backstroke) {
1177 | this.pending_backstroke.removeClass("search-choice-focus");
1178 | }
1179 | return this.pending_backstroke = null;
1180 | };
1181 |
1182 | Chosen.prototype.keydown_checker = function(evt) {
1183 | var stroke, _ref1;
1184 | stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1185 | this.search_field_scale();
1186 | if (stroke !== 8 && this.pending_backstroke) {
1187 | this.clear_backstroke();
1188 | }
1189 | switch (stroke) {
1190 | case 8:
1191 | this.backstroke_length = this.search_field.val().length;
1192 | break;
1193 | case 9:
1194 | if (this.results_showing && !this.is_multiple) {
1195 | this.result_select(evt);
1196 | }
1197 | this.mouse_on_container = false;
1198 | break;
1199 | case 13:
1200 | if (this.results_showing) {
1201 | evt.preventDefault();
1202 | }
1203 | break;
1204 | case 32:
1205 | if (this.disable_search) {
1206 | evt.preventDefault();
1207 | }
1208 | break;
1209 | case 38:
1210 | evt.preventDefault();
1211 | this.keyup_arrow();
1212 | break;
1213 | case 40:
1214 | evt.preventDefault();
1215 | this.keydown_arrow();
1216 | break;
1217 | }
1218 | };
1219 |
1220 | Chosen.prototype.search_field_scale = function() {
1221 | var div, f_width, h, style, style_block, styles, w, _i, _len;
1222 | if (this.is_multiple) {
1223 | h = 0;
1224 | w = 0;
1225 | style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1226 | styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1227 | for (_i = 0, _len = styles.length; _i < _len; _i++) {
1228 | style = styles[_i];
1229 | style_block += style + ":" + this.search_field.css(style) + ";";
1230 | }
1231 | div = $('
', {
1232 | 'style': style_block
1233 | });
1234 | div.text(this.search_field.val());
1235 | $('body').append(div);
1236 | w = div.width() + 25;
1237 | div.remove();
1238 | f_width = this.container.outerWidth();
1239 | if (w > f_width - 10) {
1240 | w = f_width - 10;
1241 | }
1242 | return this.search_field.css({
1243 | 'width': w + 'px'
1244 | });
1245 | }
1246 | };
1247 |
1248 | return Chosen;
1249 |
1250 | })(AbstractChosen);
1251 |
1252 | }).call(this);
1253 |
--------------------------------------------------------------------------------