Merge remote-tracking branch 'origin/release/5.0' into fix/21858-wrong–positioning-of-check–all-in-permissions-view

pull/4031/head
Henriette Dinger 9 years ago
commit 5ddfc1ec84
  1. 2
      Gemfile
  2. 10
      Gemfile.lock
  3. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.eot
  4. 4
      app/assets/fonts/openproject_icon/openproject-icon-font.svg
  5. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.ttf
  6. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.woff
  7. 2
      app/assets/javascripts/flash_messages.js
  8. 2
      app/assets/stylesheets/_settings.scss
  9. 75
      app/assets/stylesheets/content/_accounts_mobile.sass
  10. 55
      app/assets/stylesheets/content/_forms_mobile.sass
  11. 17
      app/assets/stylesheets/content/_notifications_mobile.sass
  12. 4
      app/assets/stylesheets/content/_table.lsg
  13. 5
      app/assets/stylesheets/content/_widget_box.sass
  14. 2
      app/assets/stylesheets/content/_work_packages.sass
  15. 3
      app/assets/stylesheets/default.css.sass
  16. 7
      app/assets/stylesheets/fonts/_openproject_icon_definitions.scss
  17. 2
      app/assets/stylesheets/fonts/_openproject_icon_font.lsg
  18. 4
      app/assets/stylesheets/layout/_all.sass
  19. 70
      app/assets/stylesheets/layout/_base_mobile.sass
  20. 41
      app/assets/stylesheets/layout/_drop_down_mobile.sass
  21. 2
      app/assets/stylesheets/layout/_main_menu.sass
  22. 87
      app/assets/stylesheets/layout/_top_menu_mobile.sass
  23. 2
      app/assets/stylesheets/layout/_work_package.sass
  24. 195
      app/assets/stylesheets/layout/_work_package_mobile.sass
  25. 10
      app/assets/stylesheets/specific/homescreen.sass
  26. 2
      app/views/admin/plugins.html.erb
  27. 2
      app/views/admin/projects.html.erb
  28. 2
      app/views/auth_sources/index.html.erb
  29. 2
      app/views/boards/index.html.erb
  30. 2
      app/views/boards/show.html.erb
  31. 2
      app/views/custom_fields/_tab.html.erb
  32. 2
      app/views/enumerations/index.html.erb
  33. 2
      app/views/groups/_memberships.html.erb
  34. 2
      app/views/groups/_users.html.erb
  35. 2
      app/views/groups/index.html.erb
  36. 1
      app/views/layouts/angular.html.erb
  37. 1
      app/views/layouts/base.html.erb
  38. 2
      app/views/members/index.html.erb
  39. 2
      app/views/my/access_token.html.erb
  40. 2
      app/views/my/blocks/_timelog.html.erb
  41. 2
      app/views/planning_element_type_colors/index.html.erb
  42. 2
      app/views/project_associations/index.html.erb
  43. 2
      app/views/project_types/index.html.erb
  44. 2
      app/views/projects/form/_activities.html.erb
  45. 2
      app/views/projects/form/_types.html.erb
  46. 2
      app/views/projects/settings/_boards.html.erb
  47. 2
      app/views/projects/settings/_categories.html.erb
  48. 2
      app/views/projects/settings/_versions.html.erb
  49. 2
      app/views/reportings/index.html.erb
  50. 2
      app/views/repositories/_dir_list.html.erb
  51. 2
      app/views/repositories/_revisions.html.erb
  52. 2
      app/views/repositories/committers.html.erb
  53. 2
      app/views/roles/index.html.erb
  54. 2
      app/views/search/_mini_form.html.erb
  55. 2
      app/views/statuses/index.html.erb
  56. 2
      app/views/time_entries/reports/show.html.erb
  57. 2
      app/views/timelog/_list.html.erb
  58. 6
      app/views/types/_form.html.erb
  59. 2
      app/views/types/index.html.erb
  60. 2
      app/views/users/_memberships.html.erb
  61. 2
      app/views/users/index.html.erb
  62. 2
      app/views/wiki/history.html.erb
  63. 2
      app/views/work_packages/_list_simple.html.erb
  64. 2
      app/views/work_packages/reports/_report.html.erb
  65. 2
      app/views/workflows/_form.html.erb
  66. 2
      app/views/workflows/index.html.erb
  67. 2
      config/initializers/menus.rb
  68. 8
      config/locales/js-en.yml
  69. 1
      frontend/.gitignore
  70. 12
      frontend/app/components/inplace-edit/directives/field-edit/edit-date-range/edit-date-range.directive.js
  71. 9
      frontend/app/components/inplace-edit/directives/field-edit/edit-date/edit-date.directive.js
  72. 83
      frontend/app/components/responsive/responsive-view.service.test.ts
  73. 46
      frontend/app/components/responsive/responsive-view.service.ts
  74. 0
      frontend/app/components/routing/controllers/work-package-details.controller.js
  75. 0
      frontend/app/components/routing/controllers/work-package-details.controller.test.js
  76. 7
      frontend/app/components/routing/controllers/work-package-show.controller.js
  77. 0
      frontend/app/components/routing/controllers/work-packages-list.controller.js
  78. 0
      frontend/app/components/routing/controllers/work-packages-list.controller.test.js
  79. 19
      frontend/app/components/routing/controllers/work-packages.controller.js
  80. 20
      frontend/app/components/routing/controllers/work-packages.controller.test.js
  81. 41
      frontend/app/components/routing/routing.configuration.test.ts
  82. 274
      frontend/app/components/routing/routing.configuration.ts
  83. 2
      frontend/app/components/routing/views/work-packages.html
  84. 0
      frontend/app/components/routing/views/work-packages.list.details.html
  85. 11
      frontend/app/components/routing/views/work-packages.list.html
  86. 0
      frontend/app/components/routing/views/work-packages.list.new.html
  87. 0
      frontend/app/components/routing/views/work-packages.new.html
  88. 12
      frontend/app/components/routing/views/work-packages.show.html
  89. 9
      frontend/app/components/work-packages/controllers/wp-new.controller.js
  90. 2
      frontend/app/components/work-packages/directives/wp-create-form/wp-create-form.directive.html
  91. 2
      frontend/app/components/work-packages/directives/wp-create-form/wp-full-create-form.directive.html
  92. 26
      frontend/app/components/work-packages/directives/wp-toolbar/wp-toolbar.directive.test.ts
  93. 41
      frontend/app/components/work-packages/directives/wp-toolbar/wp-toolbar.directive.ts
  94. 5
      frontend/app/components/wp-table/directives/wp-column/wp-column.directive.js
  95. 7
      frontend/app/openproject-app.js
  96. 265
      frontend/app/routing.js
  97. 7
      frontend/app/templates/components/selectable_title.html
  98. 2
      frontend/app/templates/work_packages/attachments-edit.html
  99. 2
      frontend/app/templates/work_packages/attachments.html
  100. 1
      frontend/app/templates/work_packages/menus/query_select_dropdown_menu.html
  101. Some files were not shown because too many files have changed in this diff Show More

@ -130,7 +130,7 @@ gem 'cocaine'
# also, better than thin since we can control worker concurrency.
gem 'unicorn'
gem 'nokogiri', '~> 1.6.6'
gem 'nokogiri', '~> 1.6.7'
gem 'carrierwave', '~> 0.10.0'
gem 'fog', '~> 1.23.0', require: 'fog/aws/storage'

@ -45,7 +45,7 @@ GIT
GIT
remote: https://github.com/opf/openproject-translations.git
revision: 6c016d700eae59adcf9f03a2b98c5713306186f9
revision: 0df034a911406c75f21db87cf1c0a99af80430ae
branch: release/5.0
specs:
openproject-translations (5.0.8)
@ -305,7 +305,7 @@ GEM
mime-types (>= 1.16, < 3)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.6.2)
mini_portile2 (2.0.0)
minitest (5.8.0)
mixlib-shellout (2.1.0)
multi_json (1.11.2)
@ -318,8 +318,8 @@ GEM
net-ssh (2.9.2)
netrc (0.11.0)
newrelic_rpm (3.14.1.311)
nokogiri (1.6.6.4)
mini_portile (~> 0.6.0)
nokogiri (1.6.7.1)
mini_portile2 (~> 2.0.0.rc2)
non-stupid-digest-assets (1.0.4)
oj (2.11.5)
omniauth (1.2.2)
@ -598,7 +598,7 @@ DEPENDENCIES
mysql2 (~> 0.3.20)
net-ldap (~> 0.8.0)
newrelic_rpm
nokogiri (~> 1.6.6)
nokogiri (~> 1.6.7)
non-stupid-digest-assets
oj (~> 2.11.4)
omniauth

@ -74,7 +74,7 @@
<glyph glyph-name="view-list" unicode="&#57411;" d="M0 416l512 0 0-64-512 0z m0-96l512 0 0-64-512 0z m0-96l512 0 0-64-512 0z m0-96l512 0 0-64-512 0z"/>
<glyph glyph-name="view-split" unicode="&#57412;" d="M0 416l192 0 0-64-192 0z m0-96l192 0 0-64-192 0z m0-96l192 0 0-64-192 0z m0-96l192 0 0-64-192 0z m224 288l288 0 0-352-288 0z"/>
<glyph glyph-name="glossar" unicode="&#57413;" d="M256 368c0 80-178 96-256 96l0-352 16 0c6 0 11 0 16 0l0-32c64 0 192 19 192-32l64 0c0 51 128 32 192 32l0 32c5 0 10 0 16 0l16 0 0 352c-78 0-256-16-256-96z m-224 64c16 0 30-1 44-2 2 0 5 0 8 0 1 0 2 0 3 0 63-5 129-18 136-56 1-2 1-4 1-6l0-238c-47 27-134 30-192 30z m448-272c-58 0-145-3-192-30l0 238c0 21 34 62 192 64z m-383 91l-17-48-20 0 53 153 24 0 53-153-22 0-16 48z m51 16l-16 43c-3 10-5 20-8 28l0 0c-2-9-5-18-8-27l-15-44z m177-52l87 124 0 0-79 0 0 17 105 0 0-12-86-124 0 0 87 0 0-17-114 0 0 12z"/>
<glyph glyph-name="google-plus-1" unicode="&#57415;" d="M269 93c0 4-1 8-2 12-1 4-1 7-2 10-1 3-3 7-5 10-3 4-5 6-6 9-2 2-5 5-8 8-3 4-6 6-8 8-2 1-5 4-9 7-4 3-7 5-9 6-1 2-5 4-9 7-5 3-8 5-9 6-3 0-8 1-14 1-11 0-21-1-31-2-9-2-20-4-30-8-11-3-20-7-28-13-8-5-15-12-20-21-5-9-8-19-8-31 0-13 4-24 10-34 7-11 16-19 27-24 11-6 22-11 34-13 12-3 24-5 37-5 11 0 22 1 32 4 10 2 19 6 28 11 9 5 16 12 22 21 5 9 8 19 8 31z m-35 247c0 11-1 23-4 36-4 13-8 25-14 37-6 12-14 22-24 30-10 8-21 12-34 12-18 0-31-7-41-20-10-13-15-29-15-47 0-9 1-18 4-28 2-10 5-20 10-30 4-10 10-19 16-27 6-8 13-14 22-19 9-5 18-7 28-7 18 0 32 5 40 17 8 11 12 27 12 46z m-37 135l125 0-39-22-38 0c13-9 24-21 31-36 7-16 11-32 11-48 0-15-2-27-6-38-5-11-10-20-16-26-7-7-13-13-19-19-7-5-12-11-16-17-5-6-7-13-7-20 0-5 2-9 5-14 3-5 7-9 12-14 5-4 11-9 17-14 6-4 12-10 18-15 6-6 12-13 17-19 5-7 9-15 12-25 3-9 5-19 5-30 0-30-13-57-40-81-29-25-69-37-120-37-11 0-23 1-34 3-12 2-23 5-35 9-12 5-22 10-31 17-9 7-16 15-22 25-6 11-9 22-9 35 0 12 4 25 11 39 6 12 15 22 27 31 12 9 26 16 42 21 15 4 30 8 44 10 14 2 28 3 43 4-12 16-18 30-18 42 0 3 0 5 0 7 1 2 1 4 2 6 0 1 1 3 2 6 1 2 1 4 2 6-8-1-14-2-20-2-29 0-53 10-73 28-20 19-31 43-31 71 0 26 9 50 28 71 18 21 40 35 66 41 18 4 36 5 54 5z m297-73l0-36-73 0 0-73-37 0 0 73-73 0 0 36 73 0 0 73 37 0 0-73z"/>
<glyph glyph-name="google-plus" unicode="&#57415;" d="M269 93c0 4-1 8-2 12-1 4-1 7-2 10-1 3-3 7-5 10-3 4-5 6-6 9-2 2-5 5-8 8-3 4-6 6-8 8-2 1-5 4-9 7-4 3-7 5-9 6-1 2-5 4-9 7-5 3-8 5-9 6-3 0-8 1-14 1-11 0-21-1-31-2-9-2-20-4-30-8-11-3-20-7-28-13-8-5-15-12-20-21-5-9-8-19-8-31 0-13 4-24 10-34 7-11 16-19 27-24 11-6 22-11 34-13 12-3 24-5 37-5 11 0 22 1 32 4 10 2 19 6 28 11 9 5 16 12 22 21 5 9 8 19 8 31z m-35 247c0 11-1 23-4 36-4 13-8 25-14 37-6 12-14 22-24 30-10 8-21 12-34 12-18 0-31-7-41-20-10-13-15-29-15-47 0-9 1-18 4-28 2-10 5-20 10-30 4-10 10-19 16-27 6-8 13-14 22-19 9-5 18-7 28-7 18 0 32 5 40 17 8 11 12 27 12 46z m-37 135l125 0-39-22-38 0c13-9 24-21 31-36 7-16 11-32 11-48 0-15-2-27-6-38-5-11-10-20-16-26-7-7-13-13-19-19-7-5-12-11-16-17-5-6-7-13-7-20 0-5 2-9 5-14 3-5 7-9 12-14 5-4 11-9 17-14 6-4 12-10 18-15 6-6 12-13 17-19 5-7 9-15 12-25 3-9 5-19 5-30 0-30-13-57-40-81-29-25-69-37-120-37-11 0-23 1-34 3-12 2-23 5-35 9-12 5-22 10-31 17-9 7-16 15-22 25-6 11-9 22-9 35 0 12 4 25 11 39 6 12 15 22 27 31 12 9 26 16 42 21 15 4 30 8 44 10 14 2 28 3 43 4-12 16-18 30-18 42 0 3 0 5 0 7 1 2 1 4 2 6 0 1 1 3 2 6 1 2 1 4 2 6-8-1-14-2-20-2-29 0-53 10-73 28-20 19-31 43-31 71 0 26 9 50 28 71 18 21 40 35 66 41 18 4 36 5 54 5z m297-73l0-36-73 0 0-73-37 0 0 73-73 0 0 36 73 0 0 73 37 0 0-73z"/>
<glyph glyph-name="group" unicode="&#57414;" d="M506 161c-10 15-10 24-41 37-32 13-39 18-39 18l-1 30c0 0 12 9 16 37 7-2 15 11 15 18 1 7-1 26-10 24 2 14 4 26 3 33-2 24-26 50-63 50-37 0-61-26-63-50-1-7 0-19 2-33-9 2-10-17-10-24 1-7 8-20 16-18 3-28 15-37 15-37l-26-21c15-8 53-3 61-16 5-7 17-27 14-144l117 0c0 0 2 83-6 96z m-161 11c-11 16-46 26-81 41-35 15-44 20-44 20l0 33c0 0 13 10 17 42 8-2 17 12 18 20 0 8-2 28-12 26 2 16 4 30 3 37-2 27-29 56-70 56-41 0-68-29-70-56-1-7 1-21 3-37-10 2-12-18-12-26 1-8 9-22 18-20 4-31 17-42 17-42l0-33c0 0-9-5-44-20-35-15-70-25-81-41-9-15-7-107-7-107l352 0c0 0 2 92-7 107z"/>
<glyph glyph-name="group-by" unicode="&#57416;" d="M51 380l409 0 0-37-409 0z m1-64l409 0 0-36-409 0z m102 196l0-102-102 0z m-103-412l409 0 0-37-409 0z m1-64l409 0 0-36-409 0z m102 196l0-102-103 0z"/>
<glyph glyph-name="headline1" unicode="&#57417;" d="M0 102l0 307 41 0 0-137 166 0 0 137 41 0 0-307-41 0 0 140-166 0 0-140z m330 229l91 79 31 0 0-278 60 0 0-30-164 0 0 30 66 0 0 209c0 6 0 12 0 19l-55-47c-1-1-2-2-4-3-1 0-3 0-4 0-2 0-4 0-6 1-1 1-3 2-4 3z"/>
@ -214,4 +214,6 @@
<glyph glyph-name="yes" unicode="&#57548;" d="M176 22l-163 186c-19 16-13 45 6 61 23 16 51 13 71-7l83-92 249 304c16 19 48 22 71 9 22-13 25-41 9-61z"/>
<glyph glyph-name="getting-started" unicode="&#57549;" d="M512 153l-105 62 0-34-407 0 0-56 407 0 0-33z m-436 236c2 2 4 3 5 5 0-7-1-15-1-26l0-92 23 0 0 142-19 0-42-33 12-14c12 10 20 16 22 18z m105-92l-2 2-22 0c-2-15-3-31-7-49l16 0c8 19 12 35 15 47z m119-1l-68 0 0 1 25 24c11 10 19 19 24 25 5 6 8 12 10 18 3 5 4 12 4 18 0 12-4 21-12 28-8 7-19 10-32 10-8 0-16-1-24-4-7-3-15-7-23-14l13-15c6 5 12 9 17 11 5 2 11 3 16 3 7 0 12-2 16-6 4-3 6-9 6-15 0-5-1-9-3-13-1-4-4-9-7-13-4-5-11-13-22-24l-37-37 0-17 97 0z m48 1l-1 2-22 0c-2-15-4-31-8-49l17 0c8 19 11 35 14 47z m103-12c10 7 14 18 14 32 0 9-3 17-8 22-5 6-14 10-25 11l0 1c9 2 17 6 22 12 5 6 8 14 8 23 0 10-4 19-12 25-8 6-20 9-34 9-17 0-32-4-45-14l11-16c7 4 13 7 18 9 5 1 10 2 15 2 8 0 14-1 18-5 4-3 6-8 6-14 0-16-12-23-34-23l-13 0 0-19 12 0c13 0 23-2 29-6 6-3 9-9 9-16 0-9-3-15-8-19-6-4-14-6-25-6-6 0-13 0-19 2-7 2-14 4-20 7l0-21c11-5 24-7 40-7 18 0 32 4 41 11z"/>
<glyph glyph-name="arrow-right3" unicode="&#57550;" d="M505 235c1 1 1 2 2 3 0 0 1 1 1 2 0 1 1 1 1 2 0 0 0 0 0 1 0 0 1 1 1 2 0 1 1 2 1 3 0 1 0 2 0 3 0 1 0 1 1 2 0 1 0 2 0 3 0 1 0 2 0 3-1 1-1 2-1 3 0 0 0 1 0 2 0 1-1 2-1 3 0 1-1 2-1 2 0 1 0 1 0 1 0 1-1 2-1 2 0 1-1 2-1 2-1 1-1 2-2 3 0 1-1 1-1 2-1 1-2 2-2 2-1 1-1 1-1 1l-175 176c-15 14-39 14-53 0-15-15-15-39 0-53l111-112-347 0c-13 0-24-6-31-16-4-6-6-13-6-21 0-10 4-20 11-26 7-7 16-11 26-11l347 0-111-112c-15-14-15-38 0-53 7-7 17-11 26-11 10 0 19 4 27 11l175 176c0 0 0 0 1 1 0 0 1 1 2 2 0 1 1 1 1 2z"/>
<glyph glyph-name="show-more" unicode="&#57551;" d="M326 416c0-35-28-64-64-64-35 0-64 29-64 64 0 35 29 64 64 64 36 0 64-29 64-64z m0-166c0-36-28-64-64-64-35 0-64 28-64 64 0 35 29 64 64 64 36 0 64-29 64-64z m0-170c0-35-28-64-64-64-35 0-64 29-64 64 0 35 29 64 64 64 36 0 64-29 64-64z"/>
<glyph glyph-name="hamburger" unicode="&#57552;" d="M32 416l448 0 0-64-448 0z m0-128l448 0 0-64-448 0z m0-128l448 0 0-64-448 0z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 76 KiB

@ -27,7 +27,7 @@
//++
jQuery(document).ready(function($) {
$('body').on('click keydown', '.close-handler', function (e) {
$('body').on('click keydown touchend', '.close-handler', function (e) {
if (e.type == 'click' || e.keyCode == 13) {
$(this).parent('.flash, .errorExplanation').remove();
}

@ -120,7 +120,7 @@ $include-css: (
// These are our named breakpoints. You can use them in our breakpoint function like this: @include breakpoint(medium) { // Medium and larger styles }
$breakpoints: (
small: rem-calc(300),
small: rem-calc(480),
medium: rem-calc(640),
large: rem-calc(1200),
xlarge: rem-calc(1440),

@ -0,0 +1,75 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(680px down)
body.controller-account
#login-form,
#content .login-auth-providers,
.login_notice_div
width: 100%
#content .login-auth-providers
margin-top: 114px
h3:before
top: -14px
#login-form
.form--field-container
@include grid-content(12)
padding: 0
.login-options-container
position: relative
.login-links
float: none
position: absolute
text-align: center
top: 70px
width: 100%
a
display: block
.button
width: 100%
#new_user
.login-auth-providers
margin: 60px 0
h3 span
background: transparent
.form--label,
.form--field-container,
.form--field-instructions
@include grid-content(12)
margin-left: 0
padding: 0

@ -0,0 +1,55 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(680px down)
form
.grid-block
display: block
.grid-content
padding: 0
.form--label,
.form--field-container,
.form--select-container,
.form--field-instructions
@include grid-content(12)
margin-left: 0
padding: 0
.choice .choice--select
width: 100%
.ui-select-dropdown
.select2-search
&:before
top: 8px !important
&.select2-drop.select2-with-searchbox.select2-drop-active
margin-top: 0 !important
top: 1px !important

@ -26,11 +26,12 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
// TODO move to UI components
module.exports = function() {
return {
restrict: 'EA',
link: function(scope, element, attributes) {
}
};
};
@include breakpoint(680px down)
.notification-box--wrapper,
.flash,
#errorExplanation
left: 20px !important
margin: 0 !important
right: 20px !important
width: calc(100% - 40px) !important
top: 22px !important

@ -6,7 +6,7 @@
```
<div class="generic-table--container">
<div class="generic-table--results-container" style="max-height: 340px;">
<table role="grid" class="generic-table" interactive-table>
<table class="generic-table" interactive-table>
<colgroup>
<col highlight-col>
<col highlight-col>
@ -113,7 +113,7 @@
<div class="generic-table--container -with-footer">
<div class="generic-table--results-container" style="max-height: 340px;">
<table role="grid" class="generic-table" interactive-table>
<table class="generic-table" interactive-table>
<colgroup>
<col highlight-col>
<col highlight-col>

@ -124,3 +124,8 @@ $widget-box--enumeration-width: 20px
//necessary for correct alignment even with long texts
width: calc(100% - #{$widget-box--enumeration-width})
@include breakpoint(680px down)
.widget-boxes
&.-flex
.widget-box
flex-basis: 100%

@ -171,3 +171,5 @@ $work-package-details--tab-height: 40px
.assigned_to a
display: block
min-height: 22px
overflow: hidden
text-overflow: ellipsis

@ -45,13 +45,16 @@
@import layout/all
@import content/accounts
@import content/accounts_mobile
@import content/badges
@import content/context_menu
@import content/forms
@import content/forms_mobile
@import content/choice
@import content/copy_to_clipboard
@import content/ui_select
@import content/notifications
@import content/notifications_mobile
@import content/calendar
@import content/links
@import content/action_menu_main

@ -647,4 +647,9 @@
.icon-getting-started:before {
content: "\e0cd";
}
.icon-show-more:before {
content: "\e0cf";
}
.icon-hamburger:before {
content: "\e0d0";
}

@ -212,4 +212,6 @@
<li><span class="icon icon-yes"></span> yes</li>
<li><span class="icon icon-zoom-in"></span> zoom-in</li>
<li><span class="icon icon-zoom-out"></span> zoom-out</li>
<li><span class="icon icon-show-more"></span> show-more</li>
<li><span class="icon icon-hamburger"></span> burger</li>
</ul>

@ -27,12 +27,16 @@
//++
@import layout/base
@import layout/base_mobile
@import layout/grid
@import layout/top_menu
@import layout/top_menu_mobile
@import layout/breadcrumb
@import layout/main_menu
@import layout/footer
@import layout/drop_down
@import layout/drop_down_mobile
@import layout/toolbar
@import layout/work_package
@import layout/work_package_mobile
@import layout/angular-busy

@ -0,0 +1,70 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(680px down)
html
min-width: 0 !important
body
overflow: auto !important
overflow-y: scroll /* has to be scroll, not auto */
-webkit-overflow-scrolling: touch
#main,
#content
padding-bottom: 0 !important
position: relative !important
top: 0 !important
#main
overflow: visible
#header
min-width: 0 !important
#wrapper
background: #fff !important
#content
height: 100% !important
margin: 0 !important
padding: 20px !important
width: 100% !important
#main-menu,
#breadcrumb
display: none !important
h2
font-size: 1.4rem
.hidden-for-mobile
display: none !important
.jstElements
display: none

@ -0,0 +1,41 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
// Styles taken from jquery-dropdown plugin:
// https://github.com/plapier/jquery-dropdown
// (dual MIT/GPL-Licensed)
@include breakpoint(680px down)
.dropdown .dropdown-menu,
.toolbar .legacy-actions-more
LI > A,
LABEL
padding: 8px 13px 8px 10px
.dropdown .dropdown-menu
min-width: 0

@ -192,7 +192,7 @@ $toggler-width: 40px
height: 100%
padding: 0 10px 0 0
&:before
@extend .icon-duplicate:before
@extend .icon-double-arrow-right:before
a.navigation-toggler
@include default-transition
position: relative

@ -0,0 +1,87 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(680px down)
#logo
background-color: transparent
#top-menu
position: relative !important
#nav-login-content
float: none
padding: 15px 20px
width: 100%
.grid-block
display: block
.form--field
padding-right: 0
.login-auth-providers
width: 100% !important
white-space: normal
h3.login-auth-providers-title:before
border: none !important
.button
margin-right: 0
#account-nav-right
> li
display: none
&.drop-down
display: block
> a
display: block
padding: 0
position: relative
text-indent: -10000px
width: 68px
&:after
content: "\e0d0" !important
display: block
font-size: 1.5rem !important
position: absolute
right: 20px
text-indent: 0
top: 16px
z-index: 1000
+ ul
width: 100vw
box-shadow: 1px 1px 4px #cccccc
border: solid 1px rgba(0, 0, 0, 0.2)
li
max-width: none

@ -105,8 +105,8 @@
position: absolute
top: 0
bottom: 55px
right: 0
width: 100%
overflow: hidden
table
tr

@ -0,0 +1,195 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
@include breakpoint(680px down)
body.controller-work_packages
&.action-show #content
overflow: visible
.toolbar-container
margin-bottom: 4px
min-height: 0
.work-packages--show-view
padding: 0
#toolbar-items
background: #fff
display: flex
margin-bottom: 20px
width: calc(100% + 5px)
> li
-webkit-flex: 1 0 0
flex: 1 0 0
&:first-child
-webkit-flex: 3 0 0
flex: 3 0 0
button
width: 100%
.wp-create-button .dropdown
left: 0 !important
.action_menu_main .dropdown
left: auto !important
.work-packages--split-view
display: block
left: 0
padding: 0
position: relative
right: 0
top: 0
.tabrow
height: auto
margin: 0.75rem 0 2.5rem 0
a
color: $content-link-color
li
border-top: 2px solid $gray
font-size: 0.75rem
margin: 0
padding: 8px 0
width: 33.33%
&.selected
border-bottom: 2px solid $content-link-color
.subject-header
margin: 0
padding: 0
.work-packages--left-panel,
.work-packages--right-panel
border: none
margin: 0
min-width: 0
overflow: visible
width: 100%
// Fix for iOS: Otherwise the edit actions toolbar is misplaced
padding: 0 0 50px 0
.work-packages--panel-inner
padding: 0
&.edit-all-mode
.work-packages--right-panel
display: none
.attributes-key-value--key,
.attributes-key-value--value-container
@include grid-size(6)
font-size: 1rem
margin-bottom: 20px
.inplace-edit--read-value
padding: 0
.inplace-editing--container
border: none
.attributes-key-value--key
padding: 0 !important
.work-packages--panel-inner > .attributes-group:first-child
.attributes-group--header
border-bottom: none
padding-top: 4px
// Reset margin for mobile, since the wiki toolbar is hidden on mobile
.inplace-edit.attribute-description
.inplace-edit--write
margin-top: 0
div[class*='work-packages--details--']
width: 100%
.inplace-edit--read-value span
overflow: visible
white-space: normal
.work-packages--left-panel
.work-packages--edit-actions
bottom: -20px
width: calc(100vw + 20px)
// Stretch description to fullwidth
.inplace-edit--icon-wrapper
display: none
.work-package-details-activities-messages
font-size: 0.9rem
.work-package--new-state
margin-bottom: 0
overflow: visible
padding-right: 0
.work-packages--edit-actions
bottom: 0px !important
width: calc(100vw + 20px) !important
.detail-panel-description-content .relation h3
margin: 0 !important
padding: 8px 0 !important
font-size: 1rem
// Work packages list view
.work-packages--page-container
.toolbar
padding: 0
.title-container
max-width: 40%
overflow: hidden
span
display: block
a span span
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
> .work-packages--split-view
display: block
.work-packages--list-table-area
position: relative
.work-packages--list
padding-bottom: 55px

@ -61,3 +61,13 @@
margin-bottom: 10px
font-size: 3rem
color: $homescreen-footer-icon-color
@include breakpoint(680px down)
.homescreen--links
padding: 20px
flex-wrap: wrap
.homescreen--links--item
flex: auto
margin: 20px 0
width: 50%

@ -31,7 +31,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @plugins.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table plugins">
<table interactive-table class="generic-table plugins">
<colgroup>
<col>
<col>

@ -65,7 +65,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @projects.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -40,7 +40,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @auth_sources.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -30,7 +30,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= toolbar title: l(:label_board_plural) %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table boards">
<table interactive-table class="generic-table boards">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -70,7 +70,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @topics.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -30,7 +30,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if (@custom_fields_by_type[tab[:name]] || []).any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -34,7 +34,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if enumerations.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -34,7 +34,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @group.memberships.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table memberships">
<table interactive-table class="generic-table memberships">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -32,7 +32,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @group.users.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table users">
<table interactive-table class="generic-table users">
<colgroup>
<col highlight-col>
<col>

@ -39,7 +39,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @groups.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -31,6 +31,7 @@ See doc/COPYRIGHT.rdoc for more details.
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title><%= html_title %></title>
<meta name="viewport" content="width=device-width">
<meta name="description" content="<%= OpenProject::Info.app_name %>" />
<meta name="keywords" content="issue,bug,type" />
<meta name="app_base_path" content="<%= OpenProject::Configuration['rails_relative_url_root'] || '' %>" />

@ -31,6 +31,7 @@ See doc/COPYRIGHT.rdoc for more details.
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title><%= html_title %></title>
<meta name="viewport" content="width=device-width">
<meta name="description" content="<%= OpenProject::Info.app_name %>" />
<meta name="keywords" content="issue,bug,type" />
<meta name="app_base_path" content="<%= OpenProject::Configuration['rails_relative_url_root'] || '' %>" />

@ -44,7 +44,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% authorized = authorize_for('members', 'update') %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -37,7 +37,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if has_tokens? %>
<div class="generic-table--container">
<div class="generic-table--results-container" style="max-height: 340px;">
<table id="access-token-table" role="grid" class="generic-table" interactive-table>
<table id="access-token-table" class="generic-table" interactive-table>
<colgroup>
<col highlight-col>
<col highlight-col>

@ -51,7 +51,7 @@ entries_by_day = entries.group_by(&:spent_on)
<% if entries.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table time-entries">
<table interactive-table class="generic-table time-entries">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -41,7 +41,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @colors.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -52,7 +52,7 @@ See doc/COPYRIGHT.rdoc for more details.
</h3>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table timelines-project_associations">
<table interactive-table class="generic-table timelines-project_associations">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -41,7 +41,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @project_types.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -32,7 +32,7 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -44,7 +44,7 @@ See doc/COPYRIGHT.rdoc for more details.
</div>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table types" id="types-form">
<table interactive-table class="generic-table types" id="types-form">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -34,7 +34,7 @@ See doc/COPYRIGHT.rdoc for more details.
</legend>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -33,7 +33,7 @@ See doc/COPYRIGHT.rdoc for more details.
</legend>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -33,7 +33,7 @@ See doc/COPYRIGHT.rdoc for more details.
</legend>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -42,7 +42,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @reportings.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -28,7 +28,7 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table entries" id="browser">
<table interactive-table class="generic-table entries" id="browser">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -30,7 +30,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= form_tag({controller: '/repositories', action: 'diff', project_id: @project, path: to_path_param(path)}, method: :get) do %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table changesets">
<table interactive-table class="generic-table changesets">
<colgroup>
<col highlight-col>
<col>

@ -34,7 +34,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= form_tag({}) do %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -41,7 +41,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= render partial: 'layouts/action_menu_specific' %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See doc/COPYRIGHT.rdoc for more details.
++#%>
<div class="top-menu-search--wrapper">
<div class="top-menu-search--wrapper hidden-for-mobile">
<%= label_tag("q", l(:label_search), class: "hidden-for-sighted") %>
<%= form_tag(search_path(@project), method: :get) do %>

@ -48,7 +48,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @statuses.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<% if WorkPackage.use_status_for_done_ratio? %>

@ -84,7 +84,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% unless @hours.empty? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table" id="time-report">
<table interactive-table class="generic-table" id="time-report">
<colgroup>
<% @criterias.each do |criteria| %>
<col highlight-col>

@ -29,7 +29,7 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -68,13 +68,17 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @projects.any? %>
<fieldset class="form--fieldset" id="type_project_ids">
<legend class="form--fieldset-legend"><%= l(:label_project_plural) %></legend>
<div class="form--fieldset-control">
<span class="form--fieldset-control-container">
(<%= check_all_links 'type_project_ids' %>)
</span>
</div>
<%= project_nested_ul(@projects) do |p|
content_tag('label',
check_box_tag('type[project_ids][]', p.id, controller.type.projects.include?(p), id: nil) +
' ' + h(p), class: 'form--label-with-check-box')
end %>
<%= hidden_field_tag('type[project_ids][]', '', id: nil) %>
<div><%= check_all_links 'type_project_ids' %></div>
</fieldset>
<% end %>
</div>

@ -40,7 +40,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @types.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col>

@ -34,7 +34,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% if @user.memberships.any? %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table memberships">
<table interactive-table class="generic-table memberships">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -72,7 +72,7 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -31,7 +31,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= form_tag({action: "diff"}, method: :get) do %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table wiki-page-versions">
<table interactive-table class="generic-table wiki-page-versions">
<colgroup>
<col highlight-col>
<col>

@ -30,7 +30,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= form_tag({}) do %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table work_packages">
<table interactive-table class="generic-table work_packages">
<colgroup>
<col highlight-col>
<col highlight-col>

@ -36,7 +36,7 @@ See doc/COPYRIGHT.rdoc for more details.
<% column_names = report.statuses.map(&:name) + [l(:label_open_work_packages), l(:label_closed_work_packages), l(:label_total)] %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<% column_names.each do |name| %>
<col highlight-col>

@ -28,7 +28,7 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<div id="workflow_form_<%= name %>" class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table workflow-table transitions-<%= name %>">
<table interactive-table class="generic-table workflow-table transitions-<%= name %>">
<colgroup>
<col>
<col>

@ -32,7 +32,7 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="autoscroll">
<div class="generic-table--container">
<div class="generic-table--results-container">
<table interactive-table role="grid" class="generic-table">
<table interactive-table class="generic-table">
<colgroup>
<col>
<col highlight-col>

@ -68,9 +68,11 @@ end
Redmine::MenuManager.map :account_menu do |menu|
menu.push :administration,
{ controller: '/admin', action: 'projects' },
html: { class: 'hidden-for-mobile'},
if: Proc.new { User.current.admin? }
menu.push :my_account,
{ controller: '/my', action: 'account' },
html: { class: 'hidden-for-mobile'},
if: Proc.new { User.current.logged? }
menu.push :logout, :signout_path,
if: Proc.new { User.current.logged? }

@ -64,6 +64,11 @@ en:
description_subwork_package: "Sub work package of"
filter:
noneElement: "(none)"
sorting:
criteria:
one: "First sorting criteria"
two: "Second sorting criteria"
three: "Third sorting criteria"
general_text_no: "no"
general_text_yes: "yes"
general_text_No: "No"
@ -360,7 +365,6 @@ en:
label_filter_add: "Add filter"
label_options: "Options"
label_column_multiselect: "Combined dropdown field: Select with arrow keys, confirm selection with enter, delete with backspace"
label_column_select: "Status - Combined dropdown field: Selection with auto-completion."
message_error_during_bulk_delete: An error occurred while trying to delete work packages.
message_successful_bulk_delete: Successfully deleted work packages.
create:
@ -439,6 +443,8 @@ en:
delete: "Delete"
filter: "Filter"
unselected_title: "Work package"
search_query_label: "Search saved filter queries"
search_query_title: "Click to search saved filter queries"
modals:
label_settings: "Rename query"
label_name: "Name"

@ -1,4 +1,3 @@
/typings
/.sass-cache
/bower_components
/coverage

@ -31,7 +31,7 @@ angular
.directive('inplaceEditorDateRange', inplaceEditorDateRange);
function inplaceEditorDateRange($timeout, TimezoneService, WorkPackageFieldService,
EditableFieldsState, Datepicker, inplaceEditAll) {
EditableFieldsState, Datepicker, inplaceEditAll, responsiveView) {
return {
restrict: 'E',
@ -40,7 +40,7 @@ function inplaceEditorDateRange($timeout, TimezoneService, WorkPackageFieldServi
templateUrl: '/components/inplace-edit/directives/field-edit/edit-date-range/' +
'edit-date-range.directive.html',
controller: function() {},
controller: angular.noop,
controllerAs: 'customEditorController',
link: function(scope, element) {
@ -153,6 +153,14 @@ function inplaceEditorDateRange($timeout, TimezoneService, WorkPackageFieldServi
endDatepicker.hide();
}
});
startDatepicker.setState(!responsiveView.isSmall());
endDatepicker.setState(!responsiveView.isSmall());
responsiveView.onResize(function () {
startDatepicker.setState(!responsiveView.isSmall());
endDatepicker.setState(!responsiveView.isSmall());
});
}
};
}

@ -30,7 +30,7 @@ angular
.module('openproject.inplace-edit')
.directive('inplaceEditorDate', inplaceEditorDate);
function inplaceEditorDate($timeout, inplaceEditAll, TimezoneService, Datepicker) {
function inplaceEditorDate($timeout, inplaceEditAll, TimezoneService, Datepicker, responsiveView) {
var parseISODate = TimezoneService.parseISODate,
customDateFormat = 'YYYY-MM-DD',
customFormattedDate = function(date) {
@ -45,7 +45,7 @@ function inplaceEditorDate($timeout, inplaceEditAll, TimezoneService, Datepicker
templateUrl: '/components/inplace-edit/directives/field-edit/edit-date/' +
'edit-date.directive.html',
controller: function() {},
controller: angular.noop,
controllerAs: 'customEditorController',
link: function(scope, element) {
@ -94,6 +94,11 @@ function inplaceEditorDate($timeout, inplaceEditAll, TimezoneService, Datepicker
datepicker.hide();
}
});
datepicker.setState(!responsiveView.isSmall());
responsiveView.onResize(function () {
datepicker.setState(!responsiveView.isSmall());
});
}
};
}

@ -0,0 +1,83 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
import {ResponsiveView} from './responsive-view.service';
var expect = chai.expect;
describe('responsiveView service', () => {
describe('isSmall method', () => {
var responsiveView;
var $window = {
innerWidth: 0
};
beforeEach(() => {
angular.mock.module('openproject.responsive', ($provide) => {
$provide.value('$window', $window);
});
angular.mock.inject((_responsiveView_: ResponsiveView) => {
responsiveView = _responsiveView_;
$window.innerWidth = responsiveView.small;
});
});
it('should return true if the window size is less than the "small" value', () => {
$window.innerWidth -= 10;
expect(responsiveView.isSmall()).to.be.true;
});
it('should return false if the window width is greater than the "small" value', () => {
$window.innerWidth += 10;
expect(responsiveView.isSmall()).to.be.false;
})
});
describe('onResize method', () => {
var responsiveView, $window;
beforeEach(() => {
angular.mock.module('openproject.responsive');
angular.mock.inject((_responsiveView_:ResponsiveView, _$window_:ng.IWindowService) => {
responsiveView = _responsiveView_;
$window = _$window_;
});
});
it('should execute the given callback', () => {
var callback = sinon.stub();
responsiveView.onResize(callback);
angular.element($window).trigger('resize');
expect(callback.calledOnce).to.be.true;
});
});
});

@ -0,0 +1,46 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
export class ResponsiveView {
public small: number = 680;
constructor(public $window: ng.IWindowService) {}
public isSmall(): boolean {
return this.$window.innerWidth <= this.small;
}
public onResize(callback) {
angular.element(this.$window).on('resize', callback);
}
}
angular
.module('openproject.responsive')
.service('responsiveView', ResponsiveView);

@ -252,7 +252,12 @@ function WorkPackageShowController($scope, $rootScope, $state, latestTab, workPa
vm.hideEmptyFields = true;
vm.workPackage = $scope.workPackage;
vm.isGroupHideable = WorkPackagesDisplayHelper.isGroupHideable;
vm.shouldHideGroup = function(group) {
return WorkPackagesDisplayHelper.shouldHideGroup(vm.hideEmptyFields,
vm.groupedFields,
group,
vm.workPackage);
};
vm.isFieldHideable = WorkPackagesDisplayHelper.isFieldHideable;
vm.getLabel = WorkPackagesDisplayHelper.getLabel;
vm.isSpecified = WorkPackagesDisplayHelper.isSpecified;

@ -1,4 +1,4 @@
//-- copyright
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
@ -24,21 +24,26 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
// ++
module.exports = function($scope, $state, $stateParams, QueryService, PathHelper, $rootScope,
angular
.module('openproject.workPackages.controllers')
.controller('WorkPackagesController', WorkPackagesController);
function WorkPackagesController($scope, $state, $stateParams, QueryService, $rootScope,
inplaceEditAll) {
// Setup
$scope.$state = $state;
$scope.selectedTitle = I18n.t('js.label_work_package_plural');
$scope.query_id = $stateParams.query_id;
$scope.$watch(QueryService.getAvailableGroupedQueries, function(availableQueries) {
if (availableQueries) {
$scope.groups = [{ name: I18n.t('js.label_global_queries'), models: availableQueries['queries']},
{ name: I18n.t('js.label_custom_queries'), models: availableQueries['user_queries']}];
$scope.groups = [
{ name: I18n.t('js.label_global_queries'), models: availableQueries['queries']},
{ name: I18n.t('js.label_custom_queries'), models: availableQueries['user_queries']}
];
}
});
@ -54,4 +59,4 @@ module.exports = function($scope, $state, $stateParams, QueryService, PathHelper
return (activate) ? I18n.t('js.label_activate') + ' ' : '';
};
$rootScope.$broadcast('openproject.layout.activateMenuItem');
};
}

@ -1,4 +1,4 @@
//-- copyright
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
@ -24,27 +24,27 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
/*jshint expr: true*/
// ++
describe('WorkPackagesController', function() {
var scope, win, ctrl, testParams, buildController, stateParams = {};
beforeEach(module('openproject.workPackages.controllers', 'openproject.api', 'openproject.layout','openproject.services'));
beforeEach(module('openproject.templates', function($provide) {
var configurationService = {};
beforeEach(angular.mock.module('openproject.workPackages.controllers', 'openproject.api',
'openproject.layout','openproject.services'));
beforeEach(angular.mock.module('openproject.templates', function($provide) {
var configurationService = {};
configurationService.isTimezoneSet = sinon.stub().returns(false);
$provide.constant('$stateParams', stateParams);
$provide.constant('ConfigurationService', configurationService);
}));
beforeEach(inject(function($rootScope, $controller, $timeout) {
beforeEach(angular.mock.inject(function($rootScope) {
scope = $rootScope.$new();
}));
beforeEach(inject(function($rootScope, $controller) {
beforeEach(angular.mock.inject(function($rootScope, $controller) {
scope = $rootScope.$new();
win = {
location: { pathname: "" }
@ -61,6 +61,4 @@ describe('WorkPackagesController', function() {
});
};
}));
});

@ -26,35 +26,46 @@
// See doc/COPYRIGHT.rdoc for more details.
// ++
describe('Routing', function () {
var $rootScope, $state, mockState = { go: function () {} };
var expect = chai.expect;
beforeEach(module('openproject', function ($provide) {
describe('Routing', () => {
var $rootScope: ng.IRootScopeService;
var $state: ng.ui.IStateService;
var mockState = {
go: () => {}
};
beforeEach(angular.mock.module('openproject', ($provide: ng.auto.IProvideService) => {
$provide.value('$state', mockState);
}));
beforeEach(inject(function (_$rootScope_) {
beforeEach(angular.mock.inject((_$rootScope_: ng.IRootScopeService) => {
$rootScope = _$rootScope_;
}));
describe('when the project id is set', function () {
var toState, toParams,
spy = sinon.spy(mockState, 'go'),
broadcast = function () {
$rootScope.$broadcast('$stateChangeStart', toState, toParams);
};
describe('when the project id is set', () => {
interface CustomStateParams extends ng.ui.IStateParamsService {
projects: string
}
var toState: Object;
var toParams: CustomStateParams;
var spy = sinon.spy(mockState, 'go');
var broadcast = () => {
$rootScope.$broadcast('$stateChangeStart', toState, toParams);
};
beforeEach(function () {
toState = { name: 'work-packages.list' };
toParams = { projectPath: 'my_project', projects: null };
beforeEach(() => {
toState = {name: 'work-packages.list'};
toParams = {projectPath: 'my_project', projects: null};
});
it('sets the projects path segment to "projects" ', function () {
it('sets the projects path segment to "projects" ', () => {
broadcast();
expect(toParams.projects).to.equal('projects');
});
it('routes to the given state', function () {
it('routes to the given state', () => {
broadcast();
expect(spy.withArgs(toState, toParams).called).to.be.true;
});

@ -0,0 +1,274 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
interface LocationService extends angular.ILocationService {
$$rewrite(href: string): string;
$$parse(url: string): string;
}
interface BrowserService extends angular.IBrowserService {
url(): string;
}
interface WindowService extends angular.IWindowService {
angular: angular.IAngularStatic;
}
angular
.module('openproject')
.config(($stateProvider: ng.ui.IStateProvider, $urlRouterProvider: ng.ui.IUrlRouterProvider,
$urlMatcherFactoryProvider: ng.ui.IUrlMatcherFactory) => {
$urlRouterProvider.when('/work_packages/', '/work_packages');
$urlMatcherFactoryProvider.strictMode(false);
var panels = {
get watchers() {
return {
url: '/watchers',
template: '<watchers-panel work-package="workPackage"></watchers-panel>'
}
},
get activity() {
return {
url: '/activity',
template: '<activity-panel work-package="workPackage"></activity-panel>'
}
},
get activityDetails() {
var activity = this.activity;
activity.url = '#{activity_no:\d+}';
return activity;
},
get relations() {
return {
url: '/relations',
templateUrl: '/templates/work_packages/tabs/relations.html'
};
}
};
$stateProvider
.state('work-packages', {
url: '',
abstract: true,
templateUrl: '/components/routing/views/work-packages.html',
controller: 'WorkPackagesController',
resolve: {
latestTab: ($state) => {
var stateName = 'work-packages.list.details.overview'; // the default tab
return {
getStateName: () => {
return stateName;
},
registerState: () => {
stateName = $state.current.name;
}
};
}
}
})
.state('work-packages.new', {
url: '/{projects}/{projectPath}/work_packages/new?type&parent_id',
templateUrl: '/components/routing/views/work-packages.new.html',
reloadOnSearch: false
})
.state('work-packages.copy', {
url: '/work_packages/{copiedFromWorkPackageId:[0-9]+}/copy',
templateUrl: '/components/routing/views/work-packages.new.html'
})
.state('work-packages.edit', {
url: '/{projects}/{projectPath}/work_packages/{workPackageId}/edit',
params: {
projectPath: {value: null, squash: true},
projects: {value: null, squash: true}
},
onEnter: ($state, $stateParams, inplaceEditAll) => {
inplaceEditAll.start();
$state.go('work-packages.list.details.overview', $stateParams);
}
})
.state('work-packages.show', {
url: '/work_packages/{workPackageId:[0-9]+}?query_props',
templateUrl: '/components/routing/views/work-packages.show.html',
controller: 'WorkPackageShowController',
controllerAs: 'vm',
resolve: {
workPackage: (WorkPackageService, $stateParams) => {
return WorkPackageService.getWorkPackage($stateParams.workPackageId);
},
// TODO hack, get rid of latestTab in ShowController
latestTab: ($state) => {
var stateName = 'work-package.overview'; // the default tab
return {
getStateName: () => {
return stateName;
},
registerState: () => {
stateName = $state.current.name;
}
};
}
},
// HACK
// This is to avoid problems with the css depending on which page the
// browser starts from (deep-link). As we have CSS rules that change the
// layout drastically when on the show action (e.g. position: relative)
// and this should not be applied to the other states, we need to remove
// the trigger used in the CSS. The correct fix would be to alter the
// CSS.
onEnter: ($state, $timeout) => {
angular.element('body').addClass('action-show');
$timeout(() => {
if ($state.is('work-packages.show')) {
$state.go('work-packages.show.activity');
}
});
},
onExit: () => {
angular.element('body').removeClass('action-show');
}
})
.state('work-packages.show.activity', panels.activity)
.state('work-packages.show.activity.details', panels.activityDetails)
.state('work-packages.show.relations', panels.relations)
.state('work-packages.show.watchers', panels.watchers)
.state('work-packages.list', {
url: '/{projects}/{projectPath}/work_packages?query_id&query_props',
controller: 'WorkPackagesListController',
templateUrl: '/components/routing/views/work-packages.list.html',
params: {
// value: null makes the parameter optional
// squash: true avoids duplicate slashes when the paramter is not provided
projectPath: {value: null, squash: true},
projects: {value: null, squash: true}
},
reloadOnSearch: false,
// HACK
// This is to avoid problems with the css depending on which page the
// browser starts from (deep-link). As we have CSS rules that change the
// layout drastically when on the index action (e.g. position: absolute,
// heigt of footer, ...), and this should not be applied to the other
// states, we need to remove the trigger used in the CSS The correct fix
// would be to alter the CSS.
onEnter: () => {
angular.element('body').addClass('action-index');
},
onExit: () => {
angular.element('body').removeClass('action-index');
}
})
.state('work-packages.list.new', {
url: '/create_new?type&parent_id',
templateUrl: '/components/routing/views/work-packages.list.new.html',
reloadOnSearch: false
})
.state('work-packages.list.copy', {
url: '/details/{copiedFromWorkPackageId:[0-9]+}/copy',
templateUrl: '/components/routing/views/work-packages.list.new.html',
reloadOnSearch: false
})
.state('work-packages.list.details', {
url: '/details/{workPackageId:[0-9]+}',
templateUrl: '/components/routing/views/work-packages.list.details.html',
controller: 'WorkPackageDetailsController',
reloadOnSearch: false,
resolve: {
workPackage: (WorkPackageService, $stateParams) => {
return WorkPackageService.getWorkPackage($stateParams.workPackageId);
}
}
})
.state('work-packages.list.details.overview', {
url: '/overview',
templateUrl: '/templates/work_packages/tabs/overview.html',
controller: 'DetailsTabOverviewController',
controllerAs: 'vm',
})
.state('work-packages.list.details.activity', panels.activity)
.state('work-packages.list.details.activity.details', panels.activityDetails)
.state('work-packages.list.details.relations', panels.relations)
.state('work-packages.list.details.watchers', panels.watchers);
})
.run(($location: LocationService, $rootElement: ng.IRootElementService,
$browser: BrowserService, $rootScope: ng.IRootScopeService, $state: ng.ui.IStateService,
$window: WindowService) => {
// Our application is still a hybrid one, meaning most routes are still
// handled by Rails. As such, we disable the default link-hijacking that
// Angular's HTML5-mode turns on.
$rootElement.off('click');
$rootElement.on('click', 'a[data-ui-route]', (event) => {
if (!jQuery('body').has('div[ui-view]').length || event.ctrlKey || event.metaKey
|| event.which === 2) {
return;
}
// NOTE: making use of event delegation, thus jQuery-only.
var elm = jQuery(event.target);
var absHref = elm.prop('href');
var rewrittenUrl = $location.$$rewrite(absHref);
if (absHref && !elm.attr('target') && rewrittenUrl && !event.isDefaultPrevented()) {
event.preventDefault();
if (rewrittenUrl !== $browser.url()) {
// update location manually
$location.$$parse(rewrittenUrl);
$rootScope.$apply();
// hack to work around FF6 bug 684208 when scenario runner clicks on links
$window.angular['ff-684208-preventDefault'] = true;
}
}
});
$rootScope.$on('$stateChangeStart', (event, toState, toParams) => {
if (!toParams.projects && toParams.projectPath) {
toParams.projects = 'projects';
$state.go(toState, toParams);
}
});
}
);

@ -1,5 +1,3 @@
<div id="work-packages-index">
<div ui-view class="work-packages--page-container"></div>
</div>

@ -1,5 +1,5 @@
<div class="toolbar-container">
<div toolbar class="toolbar">
<div wp-toolbar class="toolbar">
<selectable-title focus
selected-title="selectedTitle"
groups="groups"
@ -11,7 +11,7 @@
<wp-create-button project-identifier="projectIdentifier"
state-name="work-packages.list.new"></wp-create-button>
</li>
<li class="toolbar-item">
<li class="toolbar-item hidden-for-mobile">
<label for="work-packages-filter-toggle-button" class="hidden-for-sighted">
{{ getToggleActionLabel(showFiltersOptions) + ' ' + I18n.t('js.button_filter') }}
</label>
@ -26,7 +26,7 @@
<span class="badge -secondary">{{ getFilterCount() }}</span>
</button>
</li>
<li class="toolbar-item" feature-flag="detailsView">
<li class="toolbar-item hidden-for-mobile" feature-flag="detailsView">
<ul id="work-packages-view-mode-selection" class="toolbar-button-group">
<li>
<wp-list-view-button project-identifier="projectIdentifier"></wp-list-view-button>
@ -53,7 +53,7 @@
</li>
</ul>
</li>
<li class="toolbar-item">
<li class="toolbar-item hidden-for-mobile">
<label for="work-packages-settings-button" class="hidden-for-sighted">
{{ I18n.t('js.button_settings') }}
</label>
@ -64,8 +64,7 @@
has-dropdown-menu
target="SettingsDropdownMenu"
locals="query">
<i class="button--icon icon-settings"></i>
<i class="button--dropdown-indicator"></i>
<i class="button--icon icon-show-more"></i>
</button>
</li>
</ul>

@ -1,6 +1,6 @@
<div class="work-packages--show-view" ng-class="{'edit-all-mode': editAll.state}">
<div class="toolbar-container">
<div toolbar id="toolbar">
<div wp-toolbar id="toolbar">
<ul id="toolbar-items" class="toolbar-items">
<li class="toolbar-item">
<wp-create-button project-identifier="projectIdentifier"
@ -19,7 +19,7 @@
<li class="toolbar-item" ng-if="displayWatchButton">
<wp-watcher-button work-package="workPackage" disabled="editAll.state"></wp-watcher-button>
</li>
<li class="toolbar-item" feature-flag="detailsView">
<li class="toolbar-item hidden-for-mobile" feature-flag="detailsView">
<ul id="work-packages-view-mode-selection" class="toolbar-button-group">
<li>
<wp-list-view-button project-identifier="projectIdentifier"></wp-list-view-button>
@ -51,9 +51,9 @@
ng-disabled="!actionsAvailable || editAll.state"
has-dropdown-menu
target="ShowMoreDropdownMenu"
locals="permittedActions,actionsAvailable,triggerMoreMenuAction">
<span class="button--text" ng-bind="::I18n.t('js.button_more')"></span>
<i class="button--dropdown-indicator"></i>
locals="permittedActions,actionsAvailable,triggerMoreMenuAction"
title="{{I18n.t('js.button_more')}}">
<i class="button--icon icon-show-more"></i>
</button>
</li>
</ul>
@ -95,7 +95,7 @@
</div>
</div>
<div ng-repeat="group in vm.groupedFields" ng-hide="vm.hideEmptyFields && vm.isGroupHideable(vm.groupedFields, group.groupName, vm.workPackage)" class="attributes-group">
<div ng-repeat="group in vm.groupedFields" ng-hide="vm.shouldHideGroup(group.groupName)" class="attributes-group">
<div class="attributes-group--header">
<div class="attributes-group--header-container">

@ -51,9 +51,14 @@ function WorkPackageNewController($scope,
vm.loaderPromise = null;
vm.isFieldHideable = WorkPackagesDisplayHelper.isFieldHideableOnCreate;
vm.isGroupHideable = function(groups, group, wp) {
return WorkPackagesDisplayHelper.isGroupHideable(groups, group, wp, vm.isFieldHideable);
vm.shouldHideGroup = function(group) {
return WorkPackagesDisplayHelper.shouldHideGroup(vm.hideEmptyFields,
vm.groupedFields,
group,
vm.workPackage,
vm.isFieldHideable);
};
vm.getLabel = WorkPackagesDisplayHelper.getLabel;
vm.isSpecified = WorkPackagesDisplayHelper.isSpecified;
vm.isEditable = WorkPackagesDisplayHelper.isEditable;

@ -19,7 +19,7 @@
</div>
<div ng-repeat="group in vm.groupedFields"
ng-hide="vm.hideEmptyFields && vm.isGroupHideable(vm.groupedFields, group.groupName, vm.workPackage)"
ng-hide="vm.shouldHideGroup(group.groupName)"
class="attributes-group">
<div class="attributes-group--header">

@ -49,7 +49,7 @@
</div>
<div ng-repeat="group in vm.groupedFields"
ng-hide="vm.hideEmptyFields && vm.isGroupHideable(vm.groupedFields, group.groupName, vm.workPackage)"
ng-hide="vm.shouldHideGroup(group.groupName)"
class="attributes-group">
<div class="attributes-group--header">

@ -1,4 +1,4 @@
//-- copyright
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
@ -24,41 +24,39 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
// ++
/*jshint expr: true*/
var expect = chai.expect;
describe('toolbar Directive', function() {
describe('toolbar Directive', () => {
var compile, element, rootScope, scope;
beforeEach(angular.mock.module('openproject.uiComponents'));
beforeEach(module('openproject.templates'));
beforeEach(angular.mock.module('openproject.templates'));
beforeEach(inject(function($rootScope, $compile) {
beforeEach(angular.mock.inject(($rootScope, $compile) => {
var html;
html = '<div toolbar></div>';
html = '<div wp-toolbar></div>';
element = angular.element(html);
rootScope = $rootScope;
scope = $rootScope.$new();
scope.doNotShow = true;
compile = function() {
compile = () => {
$compile(element)(scope);
scope.$digest();
};
}));
describe('element', function() {
beforeEach(function() {
compile();
});
describe('element', () => {
beforeEach(() => compile());
it('should preserve its div', function() {
it('should preserve its div', () => {
expect(element.prop('tagName')).to.equal('DIV');
});
it('should be in a collapsed state', function() {
it('should be in a collapsed state', () => {
expect(element.is(":visible")).to.be.false;
});
});

@ -0,0 +1,41 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
// ++
angular
.module('openproject.uiComponents')
.directive('wpToolbar', wpToolbar);
function wpToolbar(): ng.IDirective {
return {
restrict: 'A',
link: function(scope: ng.IScope, element: ng.IAugmentedJQuery) {
}
};
}

@ -80,7 +80,10 @@ function WorkPackageColumnController($scope, PathHelper, WorkPackagesHelper) {
setDisplayText(getFormattedColumnValue());
if (vm.column.meta_data.link.display) {
displayDataAsLink(WorkPackagesHelper.getColumnDataId(vm.workPackage, vm.column));
var id = WorkPackagesHelper.getColumnDataId(vm.workPackage, vm.column)
if (id) {
displayDataAsLink(id);
}
} else {
setCustomDisplayType();
}

@ -176,6 +176,7 @@ angular.module('openproject.templates', []);
// refactoring
angular.module('openproject.inplace-edit', []);
angular.module('openproject.wpButtons', ['ui.router']);
angular.module('openproject.responsive', []);
// main app
var openprojectApp = angular.module('openproject', [
@ -198,7 +199,8 @@ var openprojectApp = angular.module('openproject', [
'openproject.templates',
'monospaced.elastic',
'openproject.inplace-edit',
'openproject.wpButtons'
'openproject.wpButtons',
'openproject.responsive'
]);
window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') ||
@ -296,7 +298,6 @@ require('./helpers');
require('./layout');
require('./messages');
require('./models');
require('./routing');
require('./services');
require('./time_entries');
require('./timelines');
@ -308,5 +309,5 @@ requireTemplate.keys().forEach(requireTemplate);
require('!ngtemplate?module=openproject.templates!html!angular-busy/angular-busy.html');
var requireComponent = require.context('./components/', true, /^((?!\.(test|spec)).)*\.(js|html)$/);
var requireComponent = require.context('./components/', true, /^((?!\.(test|spec)).)*\.(js|ts|html)$/);
requireComponent.keys().forEach(requireComponent);

@ -1,265 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
angular.module('openproject')
.config([
'$stateProvider',
'$urlRouterProvider',
'$urlMatcherFactoryProvider',
function($stateProvider, $urlRouterProvider, $urlMatcherFactoryProvider) {
$urlRouterProvider.when('/work_packages/', '/work_packages');
$urlMatcherFactoryProvider.strictMode(false);
var panels = {
get watchers() {
return {
url: '/watchers',
template: '<watchers-panel work-package="workPackage"></watchers-panel>'
}
},
get activity() {
return {
url: '/activity',
template: '<activity-panel work-package="workPackage"></activity-panel>'
}
},
get activityDetails() {
var activity = this.activity;
activity.url = '#{activity_no:\d+}';
return activity;
}
};
$stateProvider
.state('work-packages', {
url: '',
abstract: true,
templateUrl: '/templates/work_packages.html',
controller: 'WorkPackagesController',
resolve: {
latestTab: function($state) {
var stateName = 'work-packages.list.details.overview'; // the default tab
return {
getStateName: function() {
return stateName;
},
registerState: function() {
stateName = $state.current.name;
}
};
}
}
})
.state('work-packages.new', {
url: '/{projects}/{projectPath}/work_packages/new?type&parent_id',
templateUrl: '/components/routes/partials/work-packages.new.html',
controllerAs: 'vm',
reloadOnSearch: false
})
.state('work-packages.copy', {
url: '/work_packages/{copiedFromWorkPackageId:[0-9]+}/copy',
templateUrl: '/components/routes/partials/work-packages.new.html'
})
.state('work-packages.edit', {
url: '/{projects}/{projectPath}/work_packages/{workPackageId}/edit',
params: {
projectPath: { value: null, squash: true },
projects: { value: null, squash: true }
},
onEnter: function ($state, $stateParams, inplaceEditAll) {
inplaceEditAll.start();
$state.go('work-packages.list.details.overview', $stateParams);
}
})
.state('work-packages.show', {
url: '/work_packages/{workPackageId:[0-9]+}?query_props',
templateUrl: '/components/routes/partials/work-packages.show.html',
controller: 'WorkPackageShowController',
controllerAs: 'vm',
resolve: {
workPackage: function(WorkPackageService, $stateParams) {
return WorkPackageService.getWorkPackage($stateParams.workPackageId);
},
// TODO hack, get rid of latestTab in ShowController
latestTab: function($state) {
var stateName = 'work-package.overview'; // the default tab
return {
getStateName: function() {
return stateName;
},
registerState: function() {
stateName = $state.current.name;
}
};
}
},
// HACK
// This is to avoid problems with the css depending on which page the
// browser starts from (deep-link). As we have CSS rules that change the
// layout drastically when on the show action (e.g. position: relative)
// and this should not be applied to the other states, we need to remove
// the trigger used in the CSS. The correct fix would be to alter the
// CSS.
onEnter: function($state, $timeout){
angular.element('body').addClass('action-show');
$timeout(function () {
if ($state.is('work-packages.show')) {
$state.go('work-packages.show.activity');
}
});
},
onExit: function(){
angular.element('body').removeClass('action-show');
}
})
.state('work-packages.show.activity', panels.activity)
.state('work-packages.show.activity.details', panels.activityDetails)
.state('work-packages.show.relations', {
url: '/relations',
templateUrl: '/templates/work_packages/tabs/relations.html'
})
.state('work-packages.show.watchers', panels.watchers)
.state('work-packages.list', {
url: '/{projects}/{projectPath}/work_packages?query_id&query_props',
controller: 'WorkPackagesListController',
templateUrl: '/components/routes/partials/work-packages.list.html',
params: {
// value: null makes the parameter optional
// squash: true avoids duplicate slashes when the paramter is not provided
projectPath: { value: null, squash: true },
projects: { value: null, squash: true }
},
reloadOnSearch: false,
// HACK
// This is to avoid problems with the css depending on which page the
// browser starts from (deep-link). As we have CSS rules that change the
// layout drastically when on the index action (e.g. position: absolute,
// heigt of footer, ...), and this should not be applied to the other
// states, we need to remove the trigger used in the CSS The correct fix
// would be to alter the CSS.
onEnter: function(){
angular.element('body').addClass('action-index');
},
onExit: function(){
angular.element('body').removeClass('action-index');
}
})
.state('work-packages.list.new', {
url: '/create_new?type&parent_id',
templateUrl: '/components/routes/partials/work-packages.list.new.html',
reloadOnSearch: false
})
.state('work-packages.list.copy', {
url: '/details/{copiedFromWorkPackageId:[0-9]+}/copy',
templateUrl: '/components/routes/partials/work-packages.list.new.html',
reloadOnSearch: false
})
.state('work-packages.list.details', {
url: '/details/{workPackageId:[0-9]+}',
templateUrl: '/components/routes/partials/work-packages.list.details.html',
controller: 'WorkPackageDetailsController',
reloadOnSearch: false,
resolve: {
workPackage: function(WorkPackageService, $stateParams) {
return WorkPackageService.getWorkPackage($stateParams.workPackageId);
}
}
})
.state('work-packages.list.details.overview', {
url: '/overview',
controller: 'DetailsTabOverviewController',
templateUrl: '/templates/work_packages/tabs/overview.html',
controllerAs: 'vm',
})
.state('work-packages.list.details.activity', panels.activity)
.state('work-packages.list.details.activity.details', panels.activityDetails)
.state('work-packages.list.details.relations', {
url: '/relations',
templateUrl: '/templates/work_packages/tabs/relations.html',
})
.state('work-packages.list.details.watchers', panels.watchers);
}])
.run([
'$location',
'$rootElement',
'$browser',
'$rootScope',
'$state',
function($location, $rootElement, $browser, $rootScope, $state) {
// Our application is still a hybrid one, meaning most routes are still
// handled by Rails. As such, we disable the default link-hijacking that
// Angular's HTML5-mode turns on.
$rootElement.off('click');
$rootElement.on('click', 'a[data-ui-route]', function(event) {
if (!jQuery('body').has('div[ui-view]').length) { return; }
if (event.ctrlKey || event.metaKey || event.which === 2) { return; }
// NOTE: making use of event delegation, thus jQuery-only.
var elm = jQuery(event.target);
var absHref = elm.prop('href');
var rewrittenUrl = $location.$$rewrite(absHref);
if (absHref && !elm.attr('target') &&
rewrittenUrl &&
!event.isDefaultPrevented()) {
event.preventDefault();
if (rewrittenUrl !== $browser.url()) {
// update location manually
$location.$$parse(rewrittenUrl);
$rootScope.$apply();
// hack to work around FF6 bug 684208 when scenario runner clicks on links
window.angular['ff-684208-preventDefault'] = true;
}
}
});
$rootScope.$on('$stateChangeStart', function(event, toState, toParams){
if (!toParams.projects && toParams.projectPath) {
toParams.projects = 'projects';
$state.go(toState, toParams);
}
});
}
]);

@ -1,10 +1,13 @@
<div class="title-container">
<div class="text">
<h2 title="{{ selectedTitle }}">
<h2 title="{{ I18n.t('js.toolbar.search_query_title') }}">
<span has-dropdown-menu target="QuerySelectDropdownMenu"
locals="selectedTitle,groups,transitionMethod">
<accessible-by-keyboard>
{{ selectedTitle | characters:50 }}<i class="icon-pulldown icon-button icon-small"></i>
<i class="icon-pulldown icon-button icon-small">
<span class="hidden-for-sighted">{{ I18n.t('js.toolbar.search_query_title') }}</span>
</i>
{{ selectedTitle | characters:50 }}
</accessible-by-keyboard>
</span>
</h2>

@ -1,4 +1,4 @@
<div class="work-packages--attachments">
<div class="work-packages--attachments attributes-group">
<div class="attributes-group--header">
<div class="attributes-group--header-container">
<h3 class="attributes-group--header-text">

@ -1,4 +1,4 @@
<div class="work-packages--attachments">
<div class="work-packages--attachments attributes-group">
<div class="attributes-group--header">
<div class="attributes-group--header-container">
<h3 class="attributes-group--header-text">

@ -1,5 +1,6 @@
<div class="dropdown dropdown-relative" id="querySelectDropdown">
<div class="search-query-wrapper">
<label for="title-filter" class="hidden-for-sighted">{{ I18n.t('js.toolbar.search_query_label') }}</label>
<input type="search" focus=""
ng-model="filterBy"
ng-change="filterModels(filterBy)"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save