Merge branch 'dev' into feature/rails4

Signed-off-by: Alex Coles <alex@alexbcoles.com>

Conflicts:
	.travis.yml
	Gemfile
	Gemfile.lock
	README.md
	app/assets/stylesheets/external.css.sass.erb
	app/assets/stylesheets/legacy/main.css.sass
	app/models/work_package.rb
	config/routes.rb
	lib/tabular_form_builder.rb
	spec/controllers/versions_controller_spec.rb
	spec/exemplars/type_exemplar.rb
	spec/factories/type_factory.rb
	spec/legacy/unit/default_data_spec.rb
	spec/legacy/unit/helpers/application_helper_spec.rb
	spec/legacy/unit/mail_handler_spec.rb
	spec/legacy/unit/project_spec.rb
	spec/legacy/unit/time_entry_activity_spec.rb
	spec/legacy/unit/type_spec.rb
	spec/models/work_package/work_package_validations_spec.rb
	spec/requests/api/v3/render_resource_spec.rb
	test/functional/types_controller_test.rb
	test/test_helper.rb
	test/unit/version_test.rb
pull/2952/head
Alex Coles 10 years ago
commit e5da2578d5
  1. 3
      .bowerrc
  2. 2
      .buildpacks
  3. 10
      .editorconfig
  4. 37
      .env.sample
  5. 18
      .gitignore
  6. 272
      .hound.yml
  7. 2
      .jshintignore
  8. 3
      .jshintrc
  9. 19
      .pkgr.yml
  10. 2
      .rspec
  11. 268
      .rubocop.yml
  12. 10
      .teatro.yml
  13. 69
      .travis.yml
  14. 13
      CODE_OF_CONDUCT.md
  15. 104
      CONTRIBUTING.md
  16. 92
      Gemfile
  17. 2
      Guardfile
  18. 3
      Procfile.dev
  19. 13
      README.md
  20. 2
      Rakefile
  21. BIN
      app/assets/fonts/lato/Lato-Bold.eot
  22. 1572
      app/assets/fonts/lato/Lato-Bold.svg
  23. BIN
      app/assets/fonts/lato/Lato-Bold.ttf
  24. BIN
      app/assets/fonts/lato/Lato-Bold.woff
  25. BIN
      app/assets/fonts/lato/Lato-BoldItalic.eot
  26. 1590
      app/assets/fonts/lato/Lato-BoldItalic.svg
  27. BIN
      app/assets/fonts/lato/Lato-BoldItalic.ttf
  28. BIN
      app/assets/fonts/lato/Lato-BoldItalic.woff
  29. BIN
      app/assets/fonts/lato/Lato-Italic.eot
  30. 1572
      app/assets/fonts/lato/Lato-Italic.svg
  31. BIN
      app/assets/fonts/lato/Lato-Italic.ttf
  32. BIN
      app/assets/fonts/lato/Lato-Italic.woff
  33. BIN
      app/assets/fonts/lato/Lato-Light.eot
  34. 1544
      app/assets/fonts/lato/Lato-Light.svg
  35. BIN
      app/assets/fonts/lato/Lato-Light.ttf
  36. BIN
      app/assets/fonts/lato/Lato-Light.woff
  37. BIN
      app/assets/fonts/lato/Lato-LightItalic.eot
  38. 1551
      app/assets/fonts/lato/Lato-LightItalic.svg
  39. BIN
      app/assets/fonts/lato/Lato-LightItalic.ttf
  40. BIN
      app/assets/fonts/lato/Lato-LightItalic.woff
  41. BIN
      app/assets/fonts/lato/Lato-Regular.eot
  42. 1570
      app/assets/fonts/lato/Lato-Regular.svg
  43. BIN
      app/assets/fonts/lato/Lato-Regular.ttf
  44. BIN
      app/assets/fonts/lato/Lato-Regular.woff
  45. 0
      app/assets/fonts/lato/OFL.txt
  46. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.eot
  47. 5
      app/assets/fonts/openproject_icon/openproject-icon-font.svg
  48. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.ttf
  49. BIN
      app/assets/fonts/openproject_icon/openproject-icon-font.woff
  50. BIN
      app/assets/images/jquery-ui/ui-icons_222222_256x240.png
  51. BIN
      app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png
  52. BIN
      app/assets/images/jquery-ui/ui-icons_454545_256x240.png
  53. BIN
      app/assets/images/jquery-ui/ui-icons_888888_256x240.png
  54. BIN
      app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png
  55. BIN
      app/assets/images/select2/select2-spinner.gif
  56. BIN
      app/assets/images/styleguide/logo_openproject.png
  57. 2
      app/assets/javascripts/accessibility.js
  58. 4
      app/assets/javascripts/action_menu.js
  59. 2
      app/assets/javascripts/admin_users.js
  60. 2
      app/assets/javascripts/ajaxappender.js
  61. 87
      app/assets/javascripts/angular/config/configuration-service.js
  62. 79
      app/assets/javascripts/angular/timelines/directives/timeline-toolbar-directive.js
  63. 170
      app/assets/javascripts/angular/ui_components/has-dropdown-menu-directive.js
  64. 158
      app/assets/javascripts/angular/ui_components/inplace-editor-directive.js
  65. 237
      app/assets/javascripts/angular/ui_components/selectable-title-directive.js
  66. 126
      app/assets/javascripts/angular/ui_components/with-dropdown-directive.js
  67. 77
      app/assets/javascripts/angular/ui_components/zoom-slider-directive.js
  68. 200
      app/assets/javascripts/angular/work_packages/controllers/details-tab-overview-controller.js
  69. 92
      app/assets/javascripts/angular/work_packages/controllers/dialogs/columns.js
  70. 154
      app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js
  71. 165
      app/assets/javascripts/angular/work_packages/directives/options-dropdown-directive.js
  72. 86
      app/assets/javascripts/angular/work_packages/index.js
  73. 200
      app/assets/javascripts/application.js.erb
  74. 2
      app/assets/javascripts/autocomplete_textareas.js.erb
  75. 2
      app/assets/javascripts/autocompleter.js
  76. 2
      app/assets/javascripts/breadcrumb.js
  77. 54
      app/assets/javascripts/colors.js
  78. 2
      app/assets/javascripts/contextual_fieldset.js
  79. 129
      app/assets/javascripts/custom-fields.js
  80. 53
      app/assets/javascripts/date-range.js
  81. 2
      app/assets/javascripts/findDomElement.js
  82. 2
      app/assets/javascripts/jquery_noconflict.js
  83. 2
      app/assets/javascripts/jstoolbar.js
  84. 6
      app/assets/javascripts/jstoolbar/jstoolbar.js
  85. 196
      app/assets/javascripts/keyboard_shortcuts.js
  86. 2
      app/assets/javascripts/members_form.js
  87. 2
      app/assets/javascripts/members_select_boxes.js
  88. 2
      app/assets/javascripts/modal.js
  89. 2
      app/assets/javascripts/openproject.js
  90. 2
      app/assets/javascripts/openproject_plugins.js.erb
  91. 2
      app/assets/javascripts/project/responsible_attribute.js
  92. 2
      app/assets/javascripts/repository_navigation.js
  93. 41
      app/assets/javascripts/search.js
  94. 2
      app/assets/javascripts/select_list_move.js
  95. 2
      app/assets/javascripts/settings.js.erb
  96. 2
      app/assets/javascripts/specific/main_menu.js.erb
  97. 4
      app/assets/javascripts/specific/toggable_fieldset.js
  98. 2
      app/assets/javascripts/tab_handling.js
  99. 10
      app/assets/javascripts/timelines_modal.js
  100. 32
      app/assets/javascripts/timelines_select_boxes.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,3 +0,0 @@
{
"directory": "vendor/assets/components"
}

@ -1,2 +1,2 @@
https://github.com/heroku/heroku-buildpack-nodejs.git#v58
https://github.com/heroku/heroku-buildpack-nodejs.git#v71
https://github.com/pkgr/heroku-buildpack-ruby.git#universal

@ -0,0 +1,10 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,rb}]
charset = utf-8
indent_style = space
indent_size = 2

@ -0,0 +1,37 @@
#-- 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.
#++
# If you place a .env file into the root directory of OpenProject
# you can override some default settings that foreman will use
# to start OpenProject
# override the default bind address
HOST=0.0.0.0
# override the default port
PORT=1337

18
.gitignore vendored

@ -1,6 +1,6 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.
@ -35,17 +35,18 @@
# Ignore bundler config
/.bundle
# Ignore the default SQLite database.
/db/*.sqlite3
# Ignore all logfiles and tempfiles.
/log/*.log
/npm-debug.log
/tmp
# Ignore RubyMine files
/.idea
/backup
/.project
/.loadpath
/app/assets/javascripts/openproject-app.bundle.js*
/app/assets/javascripts/bundles/*.*
/config/additional_environment.rb
/config/configuration.yml
/config/database.yml
@ -56,7 +57,6 @@
/db/*.sqlite3
/db/schema.rb
/files/*
/karma/reports
/log/*.log*
/log/mongrel_debug
/public/dispatch.*
@ -68,20 +68,18 @@
/tmp/sessions/*
/tmp/sockets/*
/tmp/test/*
/vendor/rails
/vendor/assets/components
/*.rbc
/doc/app
#/Gemfile.lock
/Gemfile.local
/Gemfile.plugins
/.rvmrc*
/.ruby-version
/.ruby-gemset
/.foreman
/.env
# coverage in plugins
/lib/plugins/*/coverage
# asset cache
/.sass-cache/
/node_modules/

@ -1,266 +1,6 @@
AllCops:
Exclude:
- db/schema.rb
- lib/plugins/rfpdf/**/*
AccessorMethodName:
Enabled: false
ActionFilter:
Enabled: false
Alias:
Enabled: false
AndOr:
Enabled: false
ArrayJoin:
Enabled: false
AsciiComments:
Enabled: false
AsciiIdentifiers:
Enabled: false
Attr:
Enabled: false
BlockNesting:
Enabled: false
Blocks:
Enabled: false
CaseEquality:
Enabled: false
CharacterLiteral:
Enabled: false
ClassAndModuleChildren:
Enabled: false
ClassLength:
Enabled: false
ClassVars:
Enabled: false
CollectionMethods:
PreferredMethods:
find: detect
reduce: inject
collect: map
find_all: select
ColonMethodCall:
Enabled: false
CommentAnnotation:
Enabled: false
CyclomaticComplexity:
Enabled: false
Delegate:
Enabled: false
DeprecatedHashMethods:
Enabled: false
Documentation:
Enabled: false
DotPosition:
EnforcedStyle: leading
DoubleNegation:
Enabled: false
EachWithObject:
Enabled: false
EmptyLiteral:
Enabled: false
Encoding:
Enabled: false
EvenOdd:
Enabled: false
FileName:
Enabled: false
FlipFlop:
Enabled: false
FormatString:
Enabled: false
GlobalVars:
Enabled: false
GuardClause:
Enabled: false
IfUnlessModifier:
Enabled: false
IfWithSemicolon:
Enabled: false
InlineComment:
Enabled: false
Lambda:
Enabled: false
LambdaCall:
Enabled: false
LineEndConcatenation:
Enabled: false
LineLength:
Max: 99
MethodLength:
Enabled: false
ModuleFunction:
Enabled: false
NegatedIf:
Enabled: false
NegatedWhile:
Enabled: false
Next:
Enabled: false
NilComparison:
Enabled: false
Not:
Enabled: false
NumericLiterals:
Enabled: false
OneLineConditional:
Enabled: false
OpMethod:
Enabled: false
ParameterLists:
Enabled: false
PercentLiteralDelimiters:
Enabled: false
PerlBackrefs:
Enabled: false
PredicateName:
NamePrefixBlacklist:
- is_
Proc:
Enabled: false
RaiseArgs:
Enabled: false
RegexpLiteral:
Enabled: false
SelfAssignment:
Enabled: false
SingleLineBlockParams:
Enabled: false
SingleLineMethods:
Enabled: false
SignalException:
Enabled: false
SpecialGlobalVars:
Enabled: false
StringLiterals:
EnforcedStyle: single_quotes
VariableInterpolation:
Enabled: false
TrailingComma:
Enabled: false
TrivialAccessors:
Enabled: false
VariableInterpolation:
Enabled: false
WhenThen:
Enabled: false
WhileUntilModifier:
Enabled: false
WordArray:
Enabled: false
# Lint
AmbiguousOperator:
Enabled: false
AmbiguousRegexpLiteral:
Enabled: false
AssignmentInCondition:
Enabled: false
ConditionPosition:
Enabled: false
DeprecatedClassMethods:
Enabled: false
ElseLayout:
Enabled: false
HandleExceptions:
Enabled: false
InvalidCharacterLiteral:
Enabled: false
LiteralInCondition:
Enabled: false
LiteralInInterpolation:
Enabled: false
Loop:
Enabled: false
ParenthesesAsGroupedExpression:
Enabled: false
RequireParentheses:
Enabled: false
UnderscorePrefixedVariableName:
Enabled: false
Void:
Enabled: false
ruby:
enabled: true
config_file: .rubocop.yml
java_script:
enabled: true
config_file: ./frontend/.jshintrc

@ -2,7 +2,5 @@ app/assets/javascripts/date-de-DE.js
app/assets/javascripts/date-en-US.js
app/assets/javascripts/jstoolbar/**/*
app/assets/javascripts/jquery_noconflict.js
app/assets/javascripts/pages/**/*
app/assets/javascripts/project/**/*
app/assets/javascripts/jquery-ui-i18n.js
app/assets/javascripts/lib/**/*

@ -1,3 +0,0 @@
{
"sub": true
}

@ -12,19 +12,22 @@ targets:
- ImageMagick-devel
centos-6:
<<: *redhat
sles-12:
build_dependencies:
- ImageMagick-devel
before_precompile: "packaging/setup"
crons:
- packaging/cron/openproject-clear-old-sessions
- packaging/cron/openproject-create-svn-repositories
services:
- postgres
installer: https://github.com/pkgr/installer.git#master
installer: https://github.com/pkgr/installer.git#suse
wizards:
- https://github.com/pkgr/addon-legacy-installer.git#installer
- https://github.com/pkgr/addon-mysql.git#installer
- https://github.com/pkgr/addon-apache2.git#installer
- https://github.com/pkgr/addon-svn-dav.git#installer
- https://github.com/pkgr/addon-smtp.git#installer
- https://github.com/pkgr/addon-memcached.git#installer
- https://github.com/pkgr/addon-openproject.git#installer
- https://github.com/pkgr/addon-legacy-installer.git
- https://github.com/pkgr/addon-mysql.git#suse
- https://github.com/pkgr/addon-apache2.git#suse
- https://github.com/pkgr/addon-svn-dav.git#suse
- https://github.com/pkgr/addon-smtp.git#suse
- https://github.com/pkgr/addon-memcached.git#suse
- https://github.com/pkgr/addon-openproject.git#suse
buildpack: https://github.com/ddollar/heroku-buildpack-multi.git

@ -1,6 +1,6 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.

@ -1,2 +1,266 @@
inherit_from:
- ./.hound.yml
AllCops:
Exclude:
- db/schema.rb
- lib/plugins/rfpdf/**/*
AccessorMethodName:
Enabled: false
ActionFilter:
Enabled: false
Alias:
Enabled: false
AndOr:
Enabled: false
ArrayJoin:
Enabled: false
AsciiComments:
Enabled: false
AsciiIdentifiers:
Enabled: false
Attr:
Enabled: false
BlockNesting:
Enabled: false
Blocks:
Enabled: false
CaseEquality:
Enabled: false
CharacterLiteral:
Enabled: false
ClassAndModuleChildren:
Enabled: false
ClassLength:
Enabled: false
ClassVars:
Enabled: false
CollectionMethods:
PreferredMethods:
find: detect
reduce: inject
collect: map
find_all: select
ColonMethodCall:
Enabled: false
CommentAnnotation:
Enabled: false
CyclomaticComplexity:
Enabled: false
Delegate:
Enabled: false
DeprecatedHashMethods:
Enabled: false
Documentation:
Enabled: false
DotPosition:
EnforcedStyle: leading
DoubleNegation:
Enabled: false
EachWithObject:
Enabled: false
EmptyLiteral:
Enabled: false
Encoding:
Enabled: false
EvenOdd:
Enabled: false
FileName:
Enabled: false
FlipFlop:
Enabled: false
FormatString:
Enabled: false
GlobalVars:
Enabled: false
GuardClause:
Enabled: false
IfUnlessModifier:
Enabled: false
IfWithSemicolon:
Enabled: false
InlineComment:
Enabled: false
Lambda:
Enabled: false
LambdaCall:
Enabled: false
LineEndConcatenation:
Enabled: false
LineLength:
Max: 99
MethodLength:
Enabled: false
ModuleFunction:
Enabled: false
NegatedIf:
Enabled: false
NegatedWhile:
Enabled: false
Next:
Enabled: false
NilComparison:
Enabled: false
Not:
Enabled: false
NumericLiterals:
Enabled: false
OneLineConditional:
Enabled: false
OpMethod:
Enabled: false
ParameterLists:
Enabled: false
PercentLiteralDelimiters:
Enabled: false
PerlBackrefs:
Enabled: false
PredicateName:
NamePrefixBlacklist:
- is_
Proc:
Enabled: false
RaiseArgs:
Enabled: false
RegexpLiteral:
Enabled: false
SelfAssignment:
Enabled: false
SingleLineBlockParams:
Enabled: false
SingleLineMethods:
Enabled: false
SignalException:
Enabled: false
SpecialGlobalVars:
Enabled: false
StringLiterals:
EnforcedStyle: single_quotes
VariableInterpolation:
Enabled: false
TrailingComma:
Enabled: false
TrivialAccessors:
Enabled: false
VariableInterpolation:
Enabled: false
WhenThen:
Enabled: false
WhileUntilModifier:
Enabled: false
WordArray:
Enabled: false
# Lint
AmbiguousOperator:
Enabled: false
AmbiguousRegexpLiteral:
Enabled: false
AssignmentInCondition:
Enabled: false
ConditionPosition:
Enabled: false
DeprecatedClassMethods:
Enabled: false
ElseLayout:
Enabled: false
HandleExceptions:
Enabled: false
InvalidCharacterLiteral:
Enabled: false
LiteralInCondition:
Enabled: false
LiteralInInterpolation:
Enabled: false
Loop:
Enabled: false
ParenthesesAsGroupedExpression:
Enabled: false
RequireParentheses:
Enabled: false
UnderscorePrefixedVariableName:
Enabled: false
Void:
Enabled: false

@ -1,12 +1,16 @@
stage:
before:
- bower install --allow-root
- npm install -g npm
- cd frontend;
/usr/local/bin/npm install --unsafe-perm --ignore-scripts &&
bower install --allow-root;
cd ..
- cp config/configuration.yml.example config/configuration.yml
- cp config/database.teatro.yml config/database.yml
- bundle exec rake generate_secret_token
- bundle exec rake generate_secret_token
database:
- bundle exec rake db:create db:migrate
- bundle exec rake db:seed RAILS_ENV=development
run: foreman start -c web=1,worker=1
run: foreman start -f Procfile.dev

@ -1,6 +1,6 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.
@ -27,43 +27,62 @@
#++
language: ruby
rvm:
- 2.1
sudo: false
cache:
- bundler
- npm
branches:
only:
- dev
- stable
- release/3.0
- release/4.0
- feature/rails4
- bundler: true
- directories:
- frontend/node_modules
- frontend/bower_components
env:
# Frontend
- "TEST_SUITE=karma"
- "TEST_SUITE=protractor"
# mysql2
- "TEST_SUITE=cucumber CI=true RAILS_ENV=test DB=mysql2 BUNDLE_WITHOUT=rmagick:mysql:postgres:sqlite:development"
- "TEST_SUITE=test CI=true RAILS_ENV=test DB=mysql2 BUNDLE_WITHOUT=rmagick:mysql:postgres:sqlite:development"
- "TEST_SUITE=spec CI=true RAILS_ENV=test DB=mysql2 BUNDLE_WITHOUT=rmagick:mysql:postgres:sqlite:development"
# postgres
- "TEST_SUITE=cucumber CI=true RAILS_ENV=test DB=postgres BUNDLE_WITHOUT=rmagick:mysql:mysql2:sqlite:development"
- "TEST_SUITE=test CI=true RAILS_ENV=test DB=postgres BUNDLE_WITHOUT=rmagick:mysql:mysql2:sqlite:development"
- "TEST_SUITE=spec CI=true RAILS_ENV=test DB=postgres BUNDLE_WITHOUT=rmagick:mysql:mysql2:sqlite:development"
script: "if [[ $TEST_SUITE =~ ^(karma|protractor)$ ]]; then npm run $TEST_SUITE; else bundle exec rake $TEST_SUITE; fi"
global:
- CI=true
- RAILS_ENV=test
- BUNDLE_WITHOUT=development
matrix:
# Frontend
- "TEST_SUITE=karma"
- "TEST_SUITE=protractor"
# mysql2
- "TEST_SUITE=cucumber DB=mysql2"
- "TEST_SUITE=spec:core DB=mysql2"
- "TEST_SUITE=spec:legacy DB=mysql2"
# postgres
- "TEST_SUITE=cucumber DB=postgres"
- "TEST_SUITE=spec:core DB=postgres"
- "TEST_SUITE=spec:legacy DB=postgres"
before_install:
- "echo `firefox -v`"
- "export DISPLAY=:99.0"
- "/sbin/start-stop-daemon --start -v --pidfile ./tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1920x1080x16"
- "echo `xdpyinfo -display :99 | grep 'dimensions' | awk '{ print $2 }'`"
- "nvm use 0.10"
- "travis_retry npm install"
- "nvm install 0.10 && nvm use 0.10"
- "cd frontend && travis_retry npm install && cd .."
before_script:
- "if [[ ! $TEST_SUITE =~ ^(karma|protractor)$ ]]; then RAILS_ENV=production bundle exec rake ci:travis:prepare; fi"
- if [[ ! $TEST_SUITE =~ ^(karma|protractor)$ ]]; then
RAILS_ENV=production bundle exec rake ci:travis:prepare;
fi
script:
- if [[ $TEST_SUITE =~ ^(karma|protractor)$ ]]; then
cd frontend && npm run $TEST_SUITE;
else
bundle exec rake $TEST_SUITE;
fi
notifications:
email: false
webhooks:
urls:
- "https://webhooks.gitter.im/e/435ab5d5c6944305da2f"
# Disabling coverage reporting until CodeClimate supports merging results from multiple partial tests
# addons:
# code_climate:

@ -0,0 +1,13 @@
### Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/). By participating in this project you agree to abide by its terms.

@ -1,7 +1,99 @@
OpenProject is an open source project and we encourage you to help us out. We'd be happy if you do one of these things:
OpenProject is an open source project and we encourage you to help us out. For contributing to OpenProject, please read the following guidelines.
* Create a [new work package on openproject.org](https://www.openproject.org/projects/openproject/work_packages) if you find a bug or need a feature
* Help out other people on our [forums](https://www.openproject.org/projects/openproject/boards)
* Help us [translate OpenProject to more languages](https://www.openproject.org/projects/openproject/wiki/Translations)
* Contribute code via GitHub Pull Requests, see our [contribution page](https://www.openproject.org/projects/openproject/wiki/Contribution) for more information
* See [Git Flow](https://www.openproject.org/projects/openproject/wiki/Git_Branching_Model)
*Please also note that these rules should be acknowledged by everyone, but repository contributors might occasionally deviate from them for practical purposes, e.g. not fork the repo, but have a branch on the main repository. This should however stay an exception.*
## Contributors License Agreement
External contributors have to sign a CLA before contributing to OpenProject.
The [CLA can be found here](https://www.openproject.org/wp-content/uploads/2014/09/OPF-Contributor-License-Agreement_v.2.pdf) and has to be filled out and sent to cla@openproject.org. Additionally, a GPG signature has to be provided.
## Development flow
For contributing source code, please follow the git workflow below:
- **Fork** OpenProject on GitHub
- Clone your fork to your development machine:
```
git clone git@github.com/<username>/openproject
```
- Optional: Add the original OpenProject repository as a remote, so you can fetch changes:
```
git remote add upstream git@github.com:opf/openproject
```
- Make sure you're on the right branch. The main development branch is `dev`:
```
git checkout dev
```
- Create a feature branch:
```
git checkout -b feature/<short description of your feature>
```
- Make your changes, then push the branch into your ***own*** repository:
```
git push origin <your feature branch>
```
- Create a pull request against a branch of of the <opf/openproject> repository, containing a ***clear description*** of what the pull request attempts to change and/or fix.
If your pull request **does not contain a description** for what it does and what it's intentions are, we will reject it. If you are working on a specific work package from the [list](https://community.openproject.org/projects/openproject/work_packages?query_props=%7B%22c%22:%5B%22type%22,%22status%22,%22subject%22,%22assigned_to%22%5D,%22t%22:%22parent:desc%22,%22f%22:%5B%7B%22n%22:%22status_id%22,%22o%22:%22!%22,%22t%22:%22list_status%22,%22v%22:%5B%2217%22,%2223%22,%223%22,%2214%22,%226%22%5D%7D%5D,%22pa%22:1,%22pp%22:20%7D), you may include a link to that work package in the description, so we can track your work.
We will then review your pull request. Please note that you can add commits after the pull request has been created by pushing to the branch in your fork.
## Important notes
To ensure a smooth workflow for everyone, please take note of the following:
### Testing
Please add tests to your code to verify functionality, especially if it is a new feature.
Pull requests will be verified by TravisCI as well, but please run them locally as well and make sure they are green before creating your pull request. We have a lot of pull requests coming in and it takes some time to run the complete suite for each one.
### Branching model
The main development branch for upcoming releases is `dev`. If in doubt, create your pull request against `dev`. All new features, gem updates and bugfixes for the upcoming release should go into the `dev` branch.
#### Bugs and hotfixes
Bugfixes for one of the actively supported versions of OpenProject should be issued against the respective branch. A fix for the current version (called "Hotfix" and the branch ideally being named `hotfix/XYZ`) should target `release/*` and a fix for the former version (called "Backport" and the branch ideally being named `backport/XYZ`) should target `backport/*`. We will try to merge hotfixes into dev branch but if that is no trivial task, we might ask you to create another PR for that.
#### Travis CI
If you push to your branch in quick sucession, please consider stopping the associated Travis builds, as Travis will run for each commit. This is especially true if you force push to the branch.
Please also use `[ci skip]` in your commit message to suppress builds which are not necessary (e.g. after fixing a typo in the `README`).
### Inactive pull requests
We want to keep the Pull request list as cleaned up as possible - we will aim close pull requests after an **inactivity period of 72 hours** (no comments, no further pushes) which are not labelled as `work in progress` by us.
### Issue tracking and coordination
We use OpenProject for development coordination - please have a look at [the work packages list](https://community.openproject.org/projects/openproject/work_packages?query_props=%7B%22c%22:%5B%22type%22,%22status%22,%22subject%22,%22assigned_to%22%5D,%22t%22:%22parent:desc%22,%22f%22:%5B%7B%22n%22:%22status_id%22,%22o%22:%22!%22,%22t%22:%22list_status%22,%22v%22:%5B%2217%22,%2223%22,%223%22,%2214%22,%226%22%5D%7D%5D,%22pa%22:1,%22pp%22:20%7D) for upcoming features and reported bugs.
### Contributor Code of Conduct
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
### Get in touch
If you want to get in touch with us, there is also a [Gitter channel](https://gitter.im/opf/openproject) to talk to us directly.

@ -1,6 +1,6 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.
@ -33,18 +33,18 @@ gem 'protected_attributes'
gem 'actionpack-action_caching'
gem 'rails-observers'
gem "coderay", "~> 1.0.5"
gem "coderay", "~> 1.0.9"
gem "rubytree", "~> 0.8.3"
gem "rdoc", ">= 2.4.2"
gem 'globalize'
gem 'globalize', "~> 3.1.0"
gem 'omniauth'
gem 'request_store'
gem 'request_store', "~> 1.1.0"
gem 'gravatar_image_tag', '~> 1.2.0'
# TODO: adds #auto_link which was deprecated in rails 3.1
gem 'rails_autolink'
gem 'rails_autolink', '~> 1.1.6'
gem "will_paginate", '~> 3.0'
gem "acts_as_list", "~> 0.2.0"
gem "acts_as_list", "~> 0.3.0"
gem "awesome_nested_set", '~> 2.1.6'
@ -59,7 +59,8 @@ gem 'htmldiff'
# used for statistics on svn repositories
gem 'svg-graph'
gem "date_validator"
gem "date_validator", '~> 0.7.1'
gem 'ruby-duration', '~> 3.2.0'
# We rely on this specific version, which is the latest as of now (end of 2013),
# because we have to apply to it a bugfix which could break things in other versions.
@ -67,40 +68,48 @@ gem "date_validator"
# See: config/initializers/rabl_hack.rb
gem 'rabl', '0.9.3'
gem 'multi_json'
gem 'oj'
gem 'oj', '~> 2.11.4'
gem 'delayed_job_active_record', '~> 4.0.2'
gem 'daemons'
# include custom rack-protection for now until rkh/rack-protection is fixed and released
# (see https://www.openproject.org/work_packages/3029)
# (see https://community.openproject.org/work_packages/3029)
gem 'rack-protection', :git => "https://github.com/finnlabs/rack-protection.git", :ref => '5a7d1bd'
gem 'syck', :platforms => [:ruby_20, :mingw_20, :ruby_21, :mingw_21], :require => false
# Rack::Attack is a rack middleware to protect your web app from bad clients.
# It allows whitelisting, blacklisting, throttling, and tracking based on arbitrary properties of the request.
# https://github.com/kickstarter/rack-attack
gem 'rack-attack'
gem 'syck', :platforms => [:mri, :mingw], :require => false
gem 'gon', '~> 4.0'
# catch exceptions and send them to any airbrake compatible backend
gem 'airbrake', '~> 4.1.0'
group :production do
# we use dalli as standard memcache client
# requires memcached 1.4+
# see https://github.com/mperham/dalli
gem 'dalli'
gem 'dalli', '~> 2.7.2'
end
gem 'non-stupid-digest-assets'
gem 'sass-rails', '5.0.0.beta1'
gem 'sass', '~> 3.3.6'
gem 'bourbon', '~> 4.0'
gem 'sass', '~> 3.4.12'
gem 'autoprefixer-rails'
gem 'execjs', '~> 2.4.0'
gem 'bourbon', '~> 4.2.0'
gem 'uglifier', '>= 1.0.3', require: false
gem 'livingstyleguide', '~> 1.2.0'
gem 'livingstyleguide', '~> 1.2.2'
gem "prototype-rails"
# remove once we no longer use the deprecated "link_to_remote", "remote_form_for" and alike methods
# replace those with :remote => true
gem 'prototype_legacy_helper', '0.0.0', :git => 'https://github.com/rails/prototype_legacy_helper.git'
gem 'i18n-js', '~> 3.0.0.rc6'
# small wrapper around the command line
gem 'cocaine'
@ -112,70 +121,75 @@ gem 'unicorn'
# Gems we don't depend directly on, but specify here to make sure we don't use a vulnerable
# version. Please add a link to a security advisory when adding a Gem here.
gem 'i18n', '>=0.6.8'
gem 'i18n', '~> 0.6.8'
# see https://groups.google.com/forum/#!topic/ruby-security-ann/pLrh6DUw998
gem 'nokogiri', '>=1.5.11'
# see https://groups.google.com/forum/#!topic/ruby-security-ann/DeJpjTAg1FA
gem 'nokogiri', '~> 1.6.6'
gem 'carrierwave', '~> 0.10.0'
gem 'fog', '~> 1.23.0', require: "fog/aws/storage"
group :test do
gem 'rack-test', '~> 0.6.2'
gem 'shoulda'
gem 'shoulda-context', '~> 1.2'
gem 'object-daddy', '~> 1.1.0'
gem "launchy", "~> 2.3.0"
gem "factory_girl_rails", "~> 4.0"
gem 'cucumber-rails', :require => false
gem "factory_girl_rails", "~> 4.5"
gem 'cucumber-rails', "~> 1.4.2", :require => false
gem 'rack_session_access'
# restrict because in version 1.3 a lot of tests using acts as journalized
# fail stating: "Column 'user_id' cannot be null". I don't understand the
# connection with database cleaner here but setting it to 1.2 fixes the
# issue.
gem 'database_cleaner', '~> 1.2.0'
gem "cucumber-rails-training-wheels" # http://aslakhellesoy.com/post/11055981222/the-training-wheels-came-off
gem 'rspec', '~> 2.99.0'
gem 'rspec', '~> 3.2.0'
# also add to development group, so "spec" rake task gets loaded
gem "rspec-rails", "~> 2.99.0", :group => :development
gem 'rspec-rails', '~> 3.2.0', group: :development
gem 'rspec-activemodel-mocks'
gem 'rspec-example_disabler', git: "https://github.com/finnlabs/rspec-example_disabler.git"
gem 'rspec-legacy_formatters'
gem 'capybara', '~> 2.3.0'
gem 'capybara-screenshot'
gem 'capybara-screenshot', '~> 1.0.4'
gem 'selenium-webdriver', '~> 2.44.0'
gem 'timecop', "~> 0.6.1"
gem 'timecop', '~> 0.7.1'
gem 'rb-readline', "~> 0.5.1" # ruby on CI needs this
# why in Gemfile? see: https://github.com/guard/guard-test
gem 'ruby-prof'
gem 'simplecov', '0.8.0.pre'
gem "shoulda-matchers"
gem "shoulda-matchers", '~> 2.8', require: nil
gem "json_spec"
gem "activerecord-tableless", "~> 1.0"
gem "codeclimate-test-reporter", :require => nil
gem 'equivalent-xml', '~> 0.5.1'
end
group :ldap do
gem "net-ldap", '~> 0.2.2'
gem "net-ldap", '~> 0.8.0'
end
group :development do
gem 'letter_opener', '~> 1.0.0'
gem 'letter_opener', '~> 1.3.0'
# gem 'rails-dev-tweaks', '~> 0.6.1'
gem 'thin'
gem 'faker'
gem 'quiet_assets'
gem 'rubocop', '~> 0.28'
end
group :development, :test do
gem 'pry-rails'
gem 'pry-stack_explorer'
gem 'pry-rescue'
gem 'pry-byebug', :platforms => [:mri_20,:mri_21]
gem 'pry-byebug', :platforms => [:mri]
gem 'pry-doc'
end
# API gems
gem 'grape', '~> 0.9.0'
gem 'roar', '~> 1.0.0.beta2'
gem 'reform', '~> 1.1.1', require: false
gem 'grape', '~> 0.10.1'
gem 'roar', '~> 1.0.0'
gem 'reform', '~> 1.2.6', require: false
# Use the commented pure ruby gems, if you have not the needed prerequisites on
# board to compile the native ones. Note, that their use is discouraged, since
@ -191,10 +205,6 @@ platforms :mri, :mingw do
group :postgres do
gem 'pg', "~> 0.17.1"
end
group :sqlite do
gem "sqlite3"
end
end
platforms :jruby do
@ -207,14 +217,10 @@ platforms :jruby do
group :postgres do
gem "activerecord-jdbcpostgresql-adapter"
end
group :sqlite do
gem "activerecord-jdbcsqlite3-adapter"
end
end
# Load Gemfile.local, Gemfile.plugins and plugins' Gemfiles
Dir.glob File.expand_path("../{Gemfile.local,Gemfile.plugins,lib/plugins/*/Gemfile}", __FILE__) do |file|
next unless File.readable?(file)
instance_eval File.read(file)
eval_gemfile(file)
end

@ -1,6 +1,6 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.

@ -0,0 +1,3 @@
web: bundle exec unicorn --config-file config/unicorn.rb --host ${HOST:="127.0.0.1"} --port ${PORT:="8080"} --env ${RAILS_ENV:="development"}
assets: cd frontend && $(npm bin)/webpack --colors --watch --progress
worker: bundle exec rake jobs:work

@ -1,9 +1,9 @@
# OpenProject
[<img src="https://travis-ci.org/opf/openproject.svg?branch=feature/rails4" alt="Build Status" />](https://travis-ci.org/opf/openproject)
[<img src="https://gemnasium.com/opf/openproject.png" alt="Dependency Status" />](https://gemnasium.com/opf/openproject)
[![Code Climate](https://codeclimate.com/github/opf/openproject/badges/gpa.svg)](https://codeclimate.com/github/opf/openproject)
[![Inline docs](http://inch-ci.org/github/opf/openproject.png?branch=dev)](http://inch-ci.org/github/opf/openproject)
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/opf/openproject?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
OpenProject is a web-based project management software. Its key features are:
@ -23,7 +23,13 @@ More information and screenshots can be found on [openproject.org](https://www.o
## Installation
There is an [installation guide](https://openproject.org/download/) and a [reference of configuration options](doc/CONFIGURATION.md).
If you want to run an instance of OpenProject in production (or for evaluation), refer to our
in-depth [installation guides](https://openproject.org/download/).
If you're a developer wanting to set-up a local environment for contributing to OpenProject or
developing plugins, you should refer instead to our [Quick Start for Developers](doc/QUICK_START.md).
Our [developer documentation](doc/README.md) also includes a [reference of configuration options](doc/CONFIGURATION.md).
## Contact
@ -34,7 +40,7 @@ Please find ways to contact us on the OpenProject [help page](https://www.openpr
## Community
OpenProject is driven by an active group of open source enthusiasts: software engineers, project managers, creatives, and consultants. OpenProject is supported by companies as well as individuals. We share the vision to build great open source project collaboration software.
The [OpenProject Foundation (OPF)](https://www.openproject.org/projects/openproject/wiki/OpenProject_Foundation) will give official guidance to the project and the community and oversees contributions and decisions.
The [OpenProject Foundation (OPF)](https://community.openproject.org/projects/openproject/wiki/OpenProject_Foundation) will give official guidance to the project and the community and oversees contributions and decisions.
## Repository
@ -70,4 +76,3 @@ OpenProject Icon Font by the OpenProject Foundation (OPF) is licensed under Crea
and Free for both personal and commercial use. You can copy, adapt, remix, distribute or transmit it.
Under this condition: provide a mention of the "OpenProject Foundation" and a link back to OpenProject www.openproject.org.

@ -1,7 +1,7 @@
#!/usr/bin/env rake
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
# 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.

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 156 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 160 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 159 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 154 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 159 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 155 KiB

@ -254,4 +254,9 @@
<glyph unicode="&#57585;" d="M448 320l64 64-64 64-160 0 0 64-64 0 0-64-128 0 0-128 128 0 0-32-160 0-64-64 64-64 160 0 0-160 64 0 0 160 128 0 0 128-128 0 0 32z m-323 29l25 67 10 0 29-67-13 0-6 22-29 0-7-22z m19 29l22 0-6 19c-3 6-3 9-6 13 0-4-4-10-4-13z m83-29l0 6c-3-6-9-6-16-6-3 0-6 0-9 3-4 0-7 3-7 10-3 3-3 6-3 12 0 4 0 10 0 13 3 3 3 7 6 10 4 3 7 3 10 3 3 0 6 0 10-3 6 0 6-3 9-3l0 25 10 0 0-67-10 0z m-29 25c0-6 0-9 4-12 3-4 6-4 9-4 3 0 7 0 10 4 3 0 6 6 6 12 0 7-3 10-3 13 0 3-6 7-10 7-3 0-6 0-9-4-3-3-7-9-7-16z m48-25l0 51 10 0 0-6c0 3 3 3 6 6 4 0 7 3 10 3 3 0 6 0 10-3 3 0 3-3 6-6 0 3 6 6 13 6 6 0 9 0 13-3 0-3 0-7 0-13l0-35-7 0 0 32c0 3 0 6 0 6 0 0 0 3-3 3-3 0-3 0-6 0-4 0-7 0-10-3-3-3-3-3-3-9l0-29-7 0 0 32c0 3 0 6-3 9-3 4-3 4-6 4-3 0-3 0-7-4-3 0-3-3-6-6-3-3 0-6 0-10l0-25z m80 61l0 9 10 0 0-9z m0-61l0 51 10 0 0-51z m23 0l0 51 6 0 0-6c3 6 10 9 16 9 3 0 7 0 10-3 3 0 3-3 6-3 3 0 3-3 3-7 0 0 0-3 0-9l0-32-9 0 0 32c0 3 0 6 0 6 0 3-3 3-3 3-4 0-4 0-7 0-3 0-6 0-9-3-4-3-4-6-4-13l0-25z"/>
<glyph unicode="&#57586;" d="M448 320l64 64-64 64-160 0 0 64-64 0 0-64-128 0 0-128 128 0 0-32-160 0-64-64 64-64 160 0 0-160 64 0 0 160 128 0 0 128-128 0 0 32z m-288-61l10 0 0-38c0-7 0-13-4-16-3-3-3-10-9-13-3-3-10-3-16-3-7 0-13 0-16 3-3 3-7 3-7 10 0 6-3 9-3 16l0 41 10 0 0-38c0-7 0-10 3-13 0-3 3-6 6-6 4 0 7-4 10-4 6 0 13 0 13 4 0 3 3 6 3 16z m19-54l10 0c0-3 3-7 3-7 0-3 3-3 10-3 3 0 6 0 9 3 3 0 3 4 3 7 0 3 0 3-3 3 0 0-3 3-9 3-7 0-10 3-13 3-3 0-3 4-7 4 0 3-3 6-3 6 0 3 0 3 0 6 0 4 3 4 3 4 0 0 4 3 7 3 3 0 3 0 6 0 3 0 7 0 10-3 3 0 6-4 6-4 0-3 3-3 3-6l-3 0c0 3 0 3-3 6-3 4-6 4-10 4-3 0-6 0-6-4 0-3-3-3-3-3 0 0 0-3 0-3 0 0 3-3 3-3 0 0 3 0 6-3 7 0 10-4 13-4 3 0 3-3 7-3 3 0 3-3 3-6 0-3 0-7-3-7 0-6-4-6-7-9-3 0-6-3-9-3-7 0-13 0-16 3-4 3-7 9-7 16z m87 0l9 0c0-7-3-10-6-13-3-3-10-3-13-3-6 0-13 3-16 6-10 3-13 10-13 19 0 10 3 16 7 20 3 3 9 6 16 6 6 0 12-3 16-6 3-4 6-10 6-20 0 0 0 0 0-3l-35 0c0-6 3-9 3-13 3-3 6-3 10-3 3 0 6 0 6 3 0 4 6 4 10 7z m-29 13l29 0c0 3 0 6-4 9-3 3-6 7-12 7-4 0-7 0-10-4 0-3-3-6-3-12z m48-29l0 51 6 0 0-6c3 3 3 6 7 6 3 0 3 3 6 3 3 0 6 0 10-3l-7-10c-3 0-3 4-6 4-3 0-3 0-7-4 0 0-3-3-3-3 0-3 0-6 0-9l0-26-6 0z"/>
<glyph unicode="&#57587;" d="M326 499l-140 0c-26 0-42-16-42-32l0-419c0-19 19-35 42-35l144 0c22 0 41 16 41 35l0 419c-3 16-19 32-45 32z m-28-35l70-96 74 96z m0-144l70-96 74 96z m0-147l70-96 74 96z m-228 291l74-96 70 96z m0-144l74-96 70 96z m0-147l74-96 70 96z m250 227c0-35-29-64-64-64-35 0-64 29-64 64 0 35 29 64 64 64 35 0 64-29 64-64z m0-144c0-35-29-64-64-64-35 0-64 29-64 64 0 35 29 64 64 64 35 0 64-29 64-64z m0-147c0-36-29-64-64-64-35 0-64 28-64 64 0 35 29 64 64 64 35 0 64-29 64-64z"/>
<glyph unicode="&#57589;" d="M256 384c0 80-179 96-256 96l0-352 16 0c6 0 10 0 16 0l0-32c64 0 192 19 192-32l64 0c0 51 128 32 192 32l0 32c6 0 10 0 16 0l16 0 0 352c-77 0-256-16-256-96z m-224 64c16 0 29 0 45-3 3 0 6 0 6 0 0 0 3 0 3 0 64-3 132-19 138-55 0-3 0-3 0-6l0-237c-48 29-134 29-192 29z m448-272c-58 0-144-3-192-29l0 237c0 22 35 64 192 64z m-384 90l-16-48-19 0 51 153 26 0 54-153-22 0-20 48z m51 16l-16 44c-3 10-3 20-6 29-3-9-7-19-10-29l-16-44z m179-52l87 125-80 0 0 16 105 0 0-13-86-121 86 0 0-16-112 0z"/>
<glyph unicode="&#57588;" d="M400 496l-51 0c-45 0-80-35-80-80l0-128-87 0c-3 0-6 0-6 0-3 0-10 0-13 0l-48 0c-45 0-83-35-83-80l0-102c0-45 35-80 80-80l51 0c45 0 80 35 80 80l0 102c0 10-3 19-3 26l29 0 0-93c0-16 13-26 25-26 16 0 26 13 26 26l0 96 16 0c3 0 6 0 10 0l51 0c45 0 80 35 80 80l0 99c3 45-32 80-77 80z m-211-390c0-13-13-26-26-26l-48 0c-16 0-25 13-25 26l0 102c0 16 12 26 25 26l51 0c16 0 26-13 26-26l0-102z m237 208c0-16-13-26-26-26l-51 0c-3 0-3 0-7 0 0 0 0 0 4 0l-4 0c-12 3-19 13-19 26l0 102c0 13 13 26 26 26l51 0c13 0 26-13 26-26z"/>
<glyph unicode="&#57591;" d="M512 188c0-29-10-53-30-73-20-20-44-30-72-30l-291 0c-32 0-61 12-84 35-23 24-35 52-35 85 0 23 6 45 19 64 13 20 29 34 50 44-1 5-1 9-1 11 0 38 14 70 40 97 27 26 59 40 97 40 28 0 53-8 76-24 23-15 40-36 50-61 13 11 27 17 44 17 19 0 35-7 49-20 13-14 20-30 20-49 0-13-4-25-11-37 23-5 42-17 57-35 15-19 22-40 22-64z"/>
<glyph unicode="&#57592;" d="M407 270c-18 66-74 113-139 113-45 0-88-23-115-62-8 2-15 3-23 3-61 0-110-54-110-121 0-23 6-46 18-66 3-5 8-8 13-8l414 0c5 0 9 3 12 7 10 15 15 32 15 50 0 50-40 90-85 84z"/>
<glyph unicode="&#57590;" d="M392 437l45-45-317-317-45 45z m-272 0l317-317-45-45-317 317z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.
@ -34,7 +34,7 @@
<li><a>Menu item text</a></li>
<li class="drop-down">
<a class="icon icon-more" href="javascript:">More functions</a>
<ul style="display:none;" class="action_menu_more">
<ul style="display:none;" class="legacy-actions-more">
<li><a>Menu item text</a></li>
</ul>
</li>

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,87 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($log) {
return {
settingsPresent: function() {
return gon && gon.settings;
},
userPreferencesPresent: function() {
return this.settingsPresent() && gon.settings.hasOwnProperty('user_preferences');
},
displaySettingsPresent: function() {
return this.settingsPresent() && gon.settings.hasOwnProperty('display');
},
displaySettingPresent: function(setting) {
return this.displaySettingsPresent()
&& gon.settings.display.hasOwnProperty(setting)
&& gon.settings.display[setting] != false;
},
accessibilityModeEnabled: function() {
if (!this.userPreferencesPresent()) {
$log.error('User preferences are not available.');
return false;
} else {
return gon.settings.user_preferences.impaired;
}
},
commentsSortedInDescendingOrder: function() {
if (!this.userPreferencesPresent()) {
$log.error('User preferences are not available.');
return false;
} else {
return gon.settings.user_preferences.others.comments_sorting === 'desc';
}
},
isTimezoneSet: function() {
return this.userPreferencesPresent() && gon.settings.user_preferences.time_zone != '';
},
timezone: function() {
return (this.isTimezoneSet()) ? gon.settings.user_preferences.time_zone : '';
},
dateFormatPresent: function() {
return this.displaySettingPresent('date_format');
},
dateFormat: function() {
return gon.settings.display.date_format;
},
timeFormatPresent: function() {
return this.displaySettingPresent('time_format');
},
timeFormat: function() {
return gon.settings.display.time_format;
},
enabledModulesPresent: function() {
return this.settingsPresent() && gon.settings.hasOwnProperty('enabled_modules');
},
isModuleEnabled: function(module) {
return gon.settings.enabled_modules.indexOf(module) >= 0;
},
};
};

@ -1,79 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function(TimelineTableHelper) {
return {
restrict: 'E',
replace: true,
templateUrl: '/templates/timelines/toolbar.html',
link: function(scope) {
scope.currentScaleName = 'monthly';
scope.updateToolbar = function() {
scope.slider.slider('value', scope.timeline.zoomIndex + 1);
scope.currentOutlineLevel = Timeline.OUTLINE_LEVELS[scope.timeline.expansionIndex];
scope.currentScaleName = Timeline.ZOOM_SCALES[scope.timeline.zoomIndex];
};
scope.increaseZoom = function() {
if(scope.currentScaleIndex < Object.keys(Timeline.ZOOM_CONFIGURATIONS).length - 1) {
scope.currentScaleIndex++;
}
};
scope.decreaseZoom = function() {
if(scope.currentScaleIndex > 0) {
scope.currentScaleIndex--;
}
};
scope.resetOutline = function(){
scope.timeline.expandTo(0);
};
scope.$watch('currentScaleName', function(newScaleName, oldScaleName){
if (newScaleName !== oldScaleName) {
scope.currentScale = Timeline.ZOOM_CONFIGURATIONS[scope.currentScaleName].scale;
scope.timeline.scale = scope.currentScale;
scope.currentScaleIndex = Timeline.ZOOM_SCALES.indexOf(scope.currentScaleName);
scope.slider.slider('value', scope.currentScaleIndex + 1);
scope.timeline.zoom(scope.currentScaleIndex); // TODO replace event-driven adaption by bindings
}
});
scope.$watch('currentOutlineLevel', function(outlineLevel, formerLevel) {
if (outlineLevel !== formerLevel) {
scope.timeline.expansionIndex = Timeline.OUTLINE_LEVELS.indexOf(outlineLevel);
scope.timeline.expandToOutlineLevel(outlineLevel); // TODO replace event-driven adaption by bindings
TimelineTableHelper.setRowLevelVisibility(scope.rows, scope.timeline.expansionIndex);
}
});
}
};
}

@ -1,170 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($injector, $window, $parse) {
function getCssPositionProperties(dropdown, trigger) {
var hOffset = 0,
vOffset = 0;
// Styling logic taken from jQuery-dropdown plugin: https://github.com/plapier/jquery-dropdown
// (dual MIT/GPL-Licensed)
// Position the dropdown relative-to-parent or relative-to-document
if (dropdown.hasClass('dropdown-relative')) {
return {
left: dropdown.hasClass('dropdown-anchor-right') ?
trigger.position().left - (dropdown.outerWidth(true) - trigger.outerWidth(true)) - parseInt(trigger.css('margin-right')) + hOffset :
trigger.position().left + parseInt(trigger.css('margin-left')) + hOffset,
top: trigger.position().top + trigger.outerHeight(true) - parseInt(trigger.css('margin-top')) + vOffset
};
} else {
return {
left: dropdown.hasClass('dropdown-anchor-right') ?
trigger.offset().left - (dropdown.outerWidth() - trigger.outerWidth()) + hOffset : trigger.offset().left + hOffset,
top: trigger.offset().top + trigger.outerHeight() + vOffset
};
}
}
return {
restrict: 'A',
controller: [function() {
var dropDownMenuOpened = false;
this.open = function() {
dropDownMenuOpened = true;
};
this.close = function() {
dropDownMenuOpened = false;
};
this.opened = function() {
return dropDownMenuOpened;
};
}],
link: function(scope, element, attrs, ctrl) {
var contextMenu = $injector.get(attrs.target),
locals = {},
win = angular.element($window),
menuElement,
positionRelativeTo = attrs.positionRelativeTo,
triggerOnEvent = attrs.triggerOnEvent || 'click';
/* contextMenu is a mandatory attribute and used to bind a specific context
menu to the trigger event
triggerOnEvent allows for binding the event for opening the menu to "click" */
// prepare locals, these define properties to be passed on to the context menu scope
var localKeys = attrs.locals.split(',').map(function(local) {
return local.trim();
});
angular.forEach(localKeys, function(key) {
locals[key] = scope[key];
});
function toggle(event) {
active() ? close() : open(event);
}
function active() {
return contextMenu.active() && ctrl.opened();
}
function open(event) {
ctrl.open();
contextMenu.open(event.target, locals)
.then(function(element) {
menuElement = element;
angular.element(element).trap();
});
}
function close() {
ctrl.close();
contextMenu.close();
}
function positionDropdown() {
var positionRelativeToElement = positionRelativeTo ?
element.find(positionRelativeTo) : element;
menuElement.css(getCssPositionProperties(menuElement, positionRelativeToElement));
}
element.bind(triggerOnEvent, function(event) {
event.preventDefault();
event.stopPropagation();
scope.$apply(function() {
toggle(event);
});
// set css position parameters after the digest has been completed
if (contextMenu.active()) positionDropdown();
scope.$root.$broadcast('openproject.markDropdownsAsClosed', element);
});
scope.$on('openproject.markDropdownsAsClosed', function(event, target) {
if (element !== target && ctrl.opened()) {
scope.$apply(ctrl.close);
}
});
win.on('resize', function(event) {
if (contextMenu.active() && menuElement && ctrl.opened()) {
positionDropdown();
}
});
win.bind('keyup', function(event) {
if (contextMenu.active() && event.keyCode === 27) {
scope.$apply(function() {
close();
});
}
});
function handleWindowClickEvent(event) {
if (contextMenu.active() && event.button !== 2) {
scope.$apply(function() {
close();
});
}
}
// Firefox treats a right-click as a click and a contextmenu event while other browsers
// just treat it as a contextmenu event
win.bind('click', handleWindowClickEvent);
win.bind(triggerOnEvent, handleWindowClickEvent);
}
};
}

@ -1,158 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($timeout) {
return {
restrict: 'A',
transclude: false,
templateUrl: "/templates/components/inplace_editor.html",
scope: {
type: "@inedType",
entity: "=inedEntity",
attribute: "@inedAttribute"
},
link: link,
controller: Controller
};
function link(scope, element, attrs) {
element.on("click", ".ined-read-value", function() {
scope.$apply(function() {
scope.startEditing();
});
});
element.bind("keydown keypress", function(e) {
if (e.keyCode == 27) {
scope.$apply(function() {
scope.discardEditing();
});
}
});
scope.$on('startEditing', function() {
$timeout(function() {
element.find(".ined-input-wrapper input, .ined-input-wrapper textarea").focus();
});
});
scope.$on('finishEditing', function() {
$timeout(function() {
element.find(".ined-read-value a").focus();
});
});
}
Controller.$inject = ['$scope', 'WorkPackageService', 'ApiHelper'];
function Controller($scope, WorkPackageService, ApiHelper) {
$scope.isEditing = false;
$scope.isBusy = false;
$scope.readValue = "";
$scope.editTitle = I18n.t('js.inplace.button_edit');
$scope.saveTitle = I18n.t('js.inplace.button_save');
$scope.saveAndSendTitle = I18n.t('js.inplace.button_save_and_send');
$scope.cancelTitle = I18n.t('js.inplace.button_cancel');
$scope.error = null;
$scope.startEditing = startEditing;
$scope.discardEditing = discardEditing;
$scope.submit = submit;
$scope.onSuccess = onSuccess;
$scope.onFail = onFail;
$scope.onFinally = onFinally;
activate();
function activate() {
// ng-model works weird with isolated scope
// also it's better to make an intermediate container
// to avoid live editing
setWriteValue();
setReadValue();
}
function startEditing() {
setWriteValue();
$scope.isEditing = true;
$scope.error = null;
$scope.isBusy = false;
$scope.$broadcast('startEditing');
}
function submit(withEmail) {
var data = {};
data[$scope.attribute] = $scope.dataObject.value;
data.lockVersion = $scope.entity.props.lockVersion;
$scope.isBusy = true;
var result = WorkPackageService.updateWorkPackage($scope.entity, data);
result.then(function(workPackage) {
$scope.onSuccess(workPackage);
});
result.catch(function(e) {
$scope.onFail(e);
});
result.finally(function() {
$scope.onFinally();
});
}
function onSuccess(workPackage) {
angular.extend($scope.entity, workPackage);
$scope.dataObject.value = $scope.entity.props[$scope.attribute];
$scope.error = null;
setReadValue();
finishEditing();
$scope.$emit("workPackageRefreshRequired");
}
function onFail(e) {
$scope.error = ApiHelper.getErrorMessage(e);
}
function onFinally() {
$scope.isBusy = false;
}
function discardEditing() {
finishEditing();
}
function finishEditing() {
$scope.isEditing = false;
$scope.$broadcast('finishEditing');
}
function setWriteValue() {
$scope.dataObject = {
value: $scope.entity.props[$scope.attribute]
};
}
function setReadValue() {
$scope.readValue = $scope.dataObject.value;
}
}
};

@ -1,237 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
// TODO move to UI components
module.exports = function($sce, LABEL_MAX_CHARS, KEY_CODES) {
return {
restrict: 'E',
replace: true,
scope: {
selectedTitle: '=',
groups: '=',
transitionMethod: '='
},
templateUrl: '/templates/components/selectable_title.html',
link: function(scope) {
scope.$watch('groups', refreshFilteredGroups);
scope.$watch('selectedId', selectTitle);
function refreshFilteredGroups() {
if(scope.groups){
initFilteredModels();
}
}
function selectTitle() {
angular.forEach(scope.filteredGroups, function(group) {
if(group.models.length) {
angular.forEach(group.models, function(model){
model.highlighted = model.id == scope.selectedId;
});
}
});
}
function initFilteredModels() {
scope.filteredGroups = angular.copy(scope.groups);
angular.forEach(scope.filteredGroups, function(group) {
group.models = group.models.map(function(model){
return {
label: model[0],
labelHtml: $sce.trustAsHtml(truncate(model[0], LABEL_MAX_CHARS)),
id: model[1],
highlighted: false
}
});
});
}
function labelHtml(label, filterBy) {
filterBy = filterBy.toLowerCase();
label = truncate(label, LABEL_MAX_CHARS);
if(label.toLowerCase().indexOf(filterBy) >= 0) {
var labelHtml = label.substr(0, label.toLowerCase().indexOf(filterBy))
+ "<span class='filter-selection'>" + label.substr(label.toLowerCase().indexOf(filterBy), filterBy.length) + "</span>"
+ label.substr(label.toLowerCase().indexOf(filterBy) + filterBy.length);
} else {
var labelHtml = label;
}
return $sce.trustAsHtml(labelHtml);
}
function truncate(text, chars) {
if (text.length > chars) {
return text.substr(0, chars) + "...";
}
return text;
}
function modelIndex(models) {
return models.map(function(model){
return model.id;
}).indexOf(scope.selectedId);
}
function performSelect() {
scope.transitionMethod(scope.selectedId);
}
function nextNonEmptyGroup(groups, currentGroupIndex) {
currentGroupIndex = (currentGroupIndex == undefined) ? -1 : currentGroupIndex;
while(currentGroupIndex < groups.length - 1) {
if(groups[currentGroupIndex + 1].models.length) {
return groups[currentGroupIndex + 1];
}
currentGroupIndex = currentGroupIndex + 1;
}
return null;
}
function previousNonEmptyGroup(groups, currentGroupIndex) {
while(currentGroupIndex > 0) {
if(groups[currentGroupIndex - 1].models.length) {
return groups[currentGroupIndex - 1];
}
currentGroupIndex = currentGroupIndex - 1;
}
return null;
}
function getModelPosition(groups, selectedId) {
for(var group_index = 0; group_index < groups.length; group_index++) {
var models = groups[group_index].models;
var model_index = modelIndex(models);
if(model_index >= 0) {
return {
group: group_index,
model: model_index
};
}
}
return false;
}
function selectNext() {
var groups = scope.filteredGroups;
if(!scope.selectedId) {
var nextGroup = nextNonEmptyGroup(groups);
scope.selectedId = nextGroup ? nextGroup.models[0].id : 0;
} else {
var position = getModelPosition(groups, scope.selectedId);
if (!position) return;
var models = groups[position.group].models;
if(position.model == models.length - 1){ // It is the last in the group
var nextGroup = nextNonEmptyGroup(groups, position.group);
if(nextGroup) {
scope.selectedId = nextGroup.models[0].id;
}
} else {
scope.selectedId = models[position.model + 1].id;
}
}
}
function selectPrevious() {
var groups = scope.filteredGroups;
if(scope.selectedId) {
var position = getModelPosition(groups, scope.selectedId);
if (!position) return;
var models = groups[position.group].models;
if(position.model == 0){ // It is the last in the group
var previousGroup = previousNonEmptyGroup(groups, position.group);
if(previousGroup) {
scope.selectedId = previousGroup.models[previousGroup.models.length - 1].id;
}
} else {
scope.selectedId = models[position.model - 1].id;
}
}
}
function preventDefault(event) {
event.preventDefault();
event.stopPropagation();
}
angular.element('#title-filter').bind('click', function(event) {
preventDefault(event);
});
scope.handleSelection = function(event) {
switch(event.which) {
case KEY_CODES.enter:
performSelect();
preventDefault(event);
break;
case KEY_CODES.down:
selectNext();
preventDefault(event);
break;
case KEY_CODES.up:
selectPrevious();
preventDefault(event);
break;
default:
break;
}
};
scope.reload = function(modelId, newTitle) {
scope.selectedTitle = newTitle;
scope.reloadMethod(modelId);
scope.$emit('hideAllDropdowns');
};
scope.filterModels = function(filterBy) {
initFilteredModels();
scope.selectedId = 0;
angular.forEach(scope.filteredGroups, function(group) {
if(filterBy.length) {
group.filterBy = filterBy;
group.models = group.models.filter(function(model){
return model.label.toLowerCase().indexOf(filterBy.toLowerCase()) >= 0;
});
if(group.models.length) {
angular.forEach(group.models, function(model){
model['labelHtml'] = labelHtml(model.label, filterBy);
});
if(!scope.selectedId) {
group.models[0].highlighted = true;
scope.selectedId = group.models[0].id;
}
}
}
});
};
}
};
}

@ -1,126 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
// TODO move to UI components
module.exports = function ($rootScope, $window, ESC_KEY, FocusHelper) {
function position(dropdown, trigger) {
var hOffset = 0,
vOffset = 0;
if( dropdown.length === 0 || !trigger ) return;
// Styling logic taken from jQuery-dropdown plugin: https://github.com/plapier/jquery-dropdown
// (dual MIT/GPL-Licensed)
// Position the dropdown relative-to-parent or relative-to-document
if (dropdown.hasClass('dropdown-relative')) {
leftPosition = dropdown.hasClass('dropdown-anchor-right') ?
trigger.position().left - (dropdown.outerWidth(true) - trigger.outerWidth(true)) - parseInt(trigger.css('margin-right')) + hOffset :
trigger.position().left + parseInt(trigger.css('margin-left')) + hOffset;
if (dropdown.hasClass('dropdown-up')) {
var dropdownHeight = dropdown.outerHeight(true);
dropdown.css({
left: leftPosition,
top: trigger.position().top - dropdownHeight + parseInt(trigger.css('margin-top')) - vOffset
});
} else {
dropdown.css({
left: leftPosition,
top: trigger.position().top + trigger.outerHeight(true) - parseInt(trigger.css('margin-top')) + vOffset
});
}
} else {
dropdown.css({
left: dropdown.hasClass('dropdown-anchor-right') ?
trigger.offset().left - (dropdown.outerWidth() - trigger.outerWidth()) + hOffset : trigger.offset().left + hOffset,
top: trigger.offset().top + trigger.outerHeight() + vOffset
});
}
}
function accessDropdown(dropdown) {
var links = dropdown.find('a');
if (links.length > 0) {
angular.element(links[0]).focus();
}
angular.element(dropdown).trap();
}
return {
restrict: 'EA',
scope: {
dropdownId: '@',
focusElementId: '@'
},
link: function (scope, element, attributes) {
var dropdown = jQuery("#" + attributes.dropdownId),
trigger;
$rootScope.$on('hideAllDropdowns', function(event){
jQuery('.dropdown').hide();
});
angular.element($window).on('resize', function(event) {
if(dropdown.is(':visible')) {
position(dropdown, trigger);
}
});
element.on('click', function (event) {
var showDropdown = dropdown.is(':hidden');
trigger = jQuery(this);
event.preventDefault();
event.stopPropagation();
scope.$emit('hideAllDropdowns');
if (showDropdown) dropdown.show();
position(dropdown, trigger);
accessDropdown(dropdown);
if(attributes.focusElementId) {
angular.element('#' + attributes.focusElementId).focus();
}
});
angular.element(dropdown).on('keyup', function(event) {
if (event.keyCode === ESC_KEY) {
scope.$emit('hideAllDropdowns');
FocusHelper.focusElement(element);
}
});
}
};
}

@ -1,77 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function(I18n) {
function makeSliderAccessible(slider) {
var defaultLabel = angular.element('<span class="hidden-for-sighted">');
var sliderLabel = defaultLabel.text(I18n.t('js.timelines.zoom.slider'));
var sliderHandle = slider.find('a.ui-slider-handle');
sliderHandle.append(sliderLabel);
}
// TODO pass options to directive and do not refer to timelines
return {
restrict: 'A',
link: function(scope, element, attributes) {
scope.currentScaleIndex = Timeline.ZOOM_SCALES.indexOf(scope.currentScaleName);
scope.slider = element.slider({
min: 1,
max: Timeline.ZOOM_SCALES.length,
range: 'min',
value: scope.currentScaleIndex + 1,
slide: function(event, ui) {
scope.currentScaleIndex = ui.value - 1;
scope.$apply();
},
change: function(event, ui) {
scope.currentScaleIndex = ui.value - 1;
}
}).css({
// top right bottom left
'margin': '4px 6px 3px'
});
// Slider
// TODO integrate angular-ui-slider
makeSliderAccessible(scope.slider);
scope.$watch('currentScaleIndex', function(newIndex){
scope.currentScaleIndex = newIndex;
newScaleName = Timeline.ZOOM_SCALES[newIndex];
if (scope.currentScaleName !== newScaleName) {
scope.currentScaleName = newScaleName;
}
});
}
};
}

@ -1,200 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($scope,
I18n,
WorkPackagesOverviewService,
TEXT_TYPE,
VERSION_TYPE,
CATEGORY_TYPE,
USER_TYPE,
USER_FIELDS,
CustomFieldHelper,
WorkPackagesHelper,
PathHelper,
UserService,
HookService,
$q) {
// work package properties
$scope.userPath = PathHelper.staticUserPath;
function getPropertyValue(property, format) {
switch(format) {
case VERSION_TYPE:
if ($scope.workPackage.props.versionId == undefined) {
return;
}
var versionId = $scope.workPackage.props.versionId,
versionLinkPresent = !!$scope.workPackage.links.version;
var versionTitle = versionLinkPresent ? $scope.workPackage.links.version.props.title : $scope.workPackage.props.versionName,
versionHref = versionLinkPresent ? $scope.workPackage.links.version.href : null;
return {href: versionHref, title: versionTitle, viewable: versionLinkPresent};
break;
case USER_TYPE:
return $scope.workPackage.embedded[property];
break;
case CATEGORY_TYPE:
return $scope.workPackage.embedded[property];
break;
default:
return getFormattedPropertyValue(property);
}
}
function getFormattedPropertyValue(property) {
if (property === 'date') {
return getDateProperty();
} else {
return WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props[property], property);
}
}
function getDateProperty() {
if ($scope.workPackage.props.startDate || $scope.workPackage.props.dueDate) {
var displayedStartDate = WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props.startDate, 'startDate') || I18n.t('js.label_no_start_date'),
displayedEndDate = WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props.dueDate, 'dueDate') || I18n.t('js.label_no_due_date');
return displayedStartDate + ' - ' + displayedEndDate;
}
}
$scope.groupedAttributes = WorkPackagesOverviewService.getGroupedWorkPackageOverviewAttributes();
(function setupWorkPackageProperties() {
var otherAttributes = WorkPackagesOverviewService.getGroupAttributesForGroupedAttributes('other', $scope.groupedAttributes);
angular.forEach($scope.workPackage.props.customProperties, function(customProperty) {
this.push(customProperty);
}, otherAttributes);
angular.forEach($scope.groupedAttributes, function(group) {
var attributesWithValues = [];
angular.forEach(group.attributes, function(attribute) {
if (typeof attribute == 'string') {
this.push(getWorkPackageProperty(attribute));
} else {
this.push(getWorkPackageCustomProperty(attribute));
}
}, attributesWithValues);
group.attributes = attributesWithValues;
});
// The loops before overwrite the attributes array of group 'other'. Thus,
// to get the current values of that array, I need to get that array again.
otherAttributes = WorkPackagesOverviewService.getGroupAttributesForGroupedAttributes('other', $scope.groupedAttributes);
// Sorting the 'other' group is an acutal requirement. So, check if the
// requirement has changed before removing this code!
otherAttributes.sort(function(a, b) {
return a.label.toLowerCase().localeCompare(b.label.toLowerCase());
});
})();
function getWorkPackageProperty(property) {
var label = I18n.t('js.work_packages.properties.' + property),
format = getPropertyFormat(property);
value = getPropertyValue(property, format);
if (!(value === null || value === undefined)) {
return getFormattedValueToPresentProperties(property, label, value, format);
} else {
var plugInValues = HookService.call('workPackageOverviewAttributes',
{ type: property,
workPackage: $scope.workPackage });
if (plugInValues.length == 0) {
return getFormattedValueToPresentProperties(property, label, null, format);
} else {
for (var x = 0; x < plugInValues.length; x++) {
return getFormattedValueToPresentProperties(property, label, plugInValues[x], 'dynamic');
}
}
}
}
function getWorkPackageCustomProperty(property) {
var label = property.name,
value = (property.value) ? getCustomPropertyValue(property) : null,
format = property.format;
return getFormattedValueToPresentProperties(property.name, label, value, format);
}
function getPropertyFormat(property) {
var format = USER_FIELDS.indexOf(property) === -1 ? TEXT_TYPE : USER_TYPE;
format = (property === 'versionName') ? VERSION_TYPE : format;
format = (property === 'category') ? CATEGORY_TYPE : format;
return format;
}
function getCustomPropertyValue(customProperty) {
if (!!customProperty.value && customProperty.format === USER_TYPE) {
return UserService.getUser(customProperty.value);
} else {
return CustomFieldHelper.formatCustomFieldValue(customProperty.value, customProperty.format);
}
}
function getFormattedValueToPresentProperties(property, label, value, format) {
var propertyData = {
property: property,
label: label,
format: format,
value: null
};
$q.when(value).then(function(value) {
propertyData.value = value;
});
return propertyData;
}
// toggles
$scope.toggleStates = {
hideFullDescription: true,
hideAllAttributes: true
};
$scope.isGroupEmpty = function(group) {
return group.attributes.filter(function(element) {
return !!element.value;
}).length == 0;
};
$scope.anyEmptyWorkPackageValue = function() {
return $scope.groupedAttributes.filter(function(element) {
return $scope.isGroupEmpty(element);
}).length > 0;
};
}

@ -1,92 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($scope, $filter, columnsModal, QueryService, WorkPackageService, WorkPackagesTableService, $rootScope) {
this.name = 'Columns';
this.closeMe = columnsModal.deactivate;
$scope.getObjectsData = function(term, result) {
var filtered = $filter('filter')($scope.availableColumnsData.filter(function(column) {
//Note: very special case; if such columns shall multiple, we better add a field
// to the query model hash of available columns
return column.id != "id";
}), {label: term});
var sorted = $filter('orderBy')(filtered, 'label');
return result(sorted);
};
// Data conversion for select2
function convertColumnsForSelect2(columns) {
return columns.map(function(column){
return { id: column.name, label: column.title, other: column.title };
});
}
function getColumnIdentifiersFromSelection(selectedColumnsData) {
return selectedColumnsData.map(function(column) { return column.id; });
}
// Selected Columns
var selectedColumns = QueryService.getSelectedColumns();
var previouslySelectedColumnNames = selectedColumns
.map(function(column){ return column.name; });
function getNewlyAddedColumns() {
return selectedColumns.select(function(column){
return previouslySelectedColumnNames.indexOf(column.name) < 0;
});
}
$scope.selectedColumnsData = convertColumnsForSelect2(selectedColumns);
// Available selectable Columns
QueryService.loadAvailableColumns()
.then(function(availableColumns){
$scope.availableColumns = availableColumns;
$scope.availableColumnsData = convertColumnsForSelect2(availableColumns);
});
$scope.updateSelectedColumns = function(){
// Note: Can't directly manipulate selected columns because select2 returns a new array when you change the values:(
QueryService.setSelectedColumns(getColumnIdentifiersFromSelection($scope.selectedColumnsData));
// Augment work packages with new columns data
var addedColumns = getNewlyAddedColumns(),
currentWorkPackages = WorkPackagesTableService.getRowsData(),
groupBy = WorkPackagesTableService.getGroupBy();
if(groupBy.length === 0) groupBy = undefined; // don't pass an empty string as groupBy
if(addedColumns.length) {
$rootScope.refreshWorkPackages = WorkPackageService.augmentWorkPackagesWithColumnsData(currentWorkPackages, addedColumns, groupBy);
}
columnsModal.deactivate();
};
}

@ -1,154 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function($scope, $state, latestTab, workPackage, I18n, RELATION_TYPES, RELATION_IDENTIFIERS, $q, WorkPackagesHelper, PathHelper, UsersHelper, ConfigurationService, CommonRelationsHandler, ChildrenRelationsHandler, ParentRelationsHandler) {
$scope.$on('$stateChangeSuccess', function(event, toState){
latestTab.registerState(toState.name);
});
$scope.$on('workPackageRefreshRequired', function(event, toState){
refreshWorkPackage();
});
// initialization
setWorkPackageScopeProperties(workPackage);
$scope.I18n = I18n;
$scope.$parent.preselectedWorkPackageId = $scope.workPackage.props.id;
$scope.maxDescriptionLength = 800;
function refreshWorkPackage() {
workPackage.links.self
.fetch({force: true})
.then(setWorkPackageScopeProperties);
}
$scope.refreshWorkPackage = refreshWorkPackage; // expose to child controllers
// Inform parent that work package is loaded so back url can be maintained
$scope.$emit('workPackgeLoaded');
function outputMessage(message, isError) {
$scope.$emit('flashMessage', {
isError: !!isError,
text: message
});
}
function outputError(error) {
outputMessage(error.message, true);
}
$scope.outputMessage = outputMessage; // expose to child controllers
$scope.outputError = outputError; // expose to child controllers
function setWorkPackageScopeProperties(workPackage){
$scope.workPackage = workPackage;
$scope.isWatched = !!workPackage.links.unwatchChanges;
$scope.toggleWatchLink = workPackage.links.watchChanges === undefined ? workPackage.links.unwatchChanges : workPackage.links.watchChanges;
$scope.watchers = workPackage.embedded.watchers;
// activities and latest activities
$scope.activitiesSortedInDescendingOrder = ConfigurationService.commentsSortedInDescendingOrder();
$scope.activities = displayedActivities($scope.workPackage);
// watchers
$scope.watchers = workPackage.embedded.watchers;
// Author
$scope.author = workPackage.embedded.author;
$scope.authorPath = PathHelper.staticUserPath($scope.author.props.id);
$scope.authorActive = UsersHelper.isActive($scope.author);
// Attachments
$scope.attachments = workPackage.embedded.attachments;
// relations
$q.all(WorkPackagesHelper.getParent(workPackage)).then(function(parents) {
var relationsHandler = new ParentRelationsHandler(workPackage, parents, "parent");
$scope.wpParent = relationsHandler;
});
$q.all(WorkPackagesHelper.getChildren(workPackage)).then(function(children) {
var relationsHandler = new ChildrenRelationsHandler(workPackage, children);
$scope.wpChildren = relationsHandler;
});
for (var key in RELATION_TYPES) {
if (RELATION_TYPES.hasOwnProperty(key)) {
(function(key) {
$q.all(WorkPackagesHelper.getRelationsOfType(workPackage, RELATION_TYPES[key])).then(function(relations) {
var relationsHandler = new CommonRelationsHandler(workPackage,
relations,
RELATION_IDENTIFIERS[key]);
$scope[key] = relationsHandler;
});
})(key);
}
}
// Author
$scope.author = workPackage.embedded.author;
}
$scope.toggleWatch = function() {
$scope.toggleWatchLink
.fetch({ ajax: $scope.toggleWatchLink.props })
.then(refreshWorkPackage, outputError);
};
$scope.canViewWorkPackageWatchers = function() {
return !!($scope.workPackage && $scope.workPackage.embedded.watchers !== undefined);
};
function displayedActivities(workPackage) {
var activities = workPackage.embedded.activities;
activities.splice(0, 1); // remove first activity (assumes activities are sorted chronologically)
if ($scope.activitiesSortedInDescendingOrder) {
activities.reverse();
}
return activities;
}
// toggles
$scope.toggleStates = {
hideFullDescription: true,
hideAllAttributes: true
};
function getFocusAnchorLabel(tab, workPackage) {
var tabLabel = I18n.t('js.work_packages.tabs.' + tab);
var params = { tab: tabLabel, type: workPackage.props.type, subject: workPackage.props.subject };
return I18n.t('js.label_work_package_details_you_are_here', params);
}
$scope.focusAnchorLabel = getFocusAnchorLabel($state.current.url.replace(/\//, ''), $scope.workPackage);
}

@ -1,165 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
module.exports = function(I18n, columnsModal, exportModal, saveModal, settingsModal, shareModal, sortingModal, groupingModal, QueryService, AuthorisationService, $window, $state, $timeout){
return {
restrict: 'AE',
scope: true,
link: function(scope, element, attributes) {
angular.element($window).bind('click', function() {
scope.$emit('hideAllDropdowns');
});
scope.$watch('query.displaySums', function(newValue, oldValue) {
$timeout(function() {
scope.displaySumsLabel = (newValue) ? I18n.t('js.toolbar.settings.hide_sums')
: I18n.t('js.toolbar.settings.display_sums');
});
});
scope.saveQuery = function(event){
if(scope.query.isNew()){
if( allowQueryAction(event, 'create') ){
scope.$emit('hideAllDropdowns');
saveModal.activate();
}
} else {
if( allowQueryAction(event, 'update') ) {
QueryService.saveQuery()
.then(function(data){
scope.$emit('flashMessage', data.status);
$state.go('work-packages.list', { query_id: scope.query.id, query: null }, { notify: false });
});
}
}
};
scope.deleteQuery = function(event){
if( allowQueryAction(event, 'delete') && preventNewQueryAction(event) && deleteConfirmed() ){
QueryService.deleteQuery()
.then(function(data){
settingsModal.deactivate();
scope.$emit('flashMessage', data.status);
$state.go('work-packages.list', { query_id: null, query: null }, { reload: true });
});
}
};
// Modals
scope.showSaveAsModal = function(event){
if( allowQueryAction(event, 'create') ) {
showExistingQueryModal.call(saveModal, event);
}
};
scope.showShareModal = function(event){
if (allowQueryAction(event, 'publicize') || allowQueryAction(event, 'star')) {
showExistingQueryModal.call(shareModal, event);
}
}
scope.showSettingsModal = function(event){
if( allowQueryAction(event, 'update') ) {
showExistingQueryModal.call(settingsModal, event);
}
};
scope.showExportModal = function(event){
if( allowWorkPackageAction(event, 'export') ) {
showModal.call(exportModal);
}
};
scope.showColumnsModal = function(){
showModal.call(columnsModal);
};
scope.showGroupingModal = function(){
showModal.call(groupingModal);
};
scope.showSortingModal = function(){
showModal.call(sortingModal);
};
scope.toggleDisplaySums = function(){
scope.$emit('hideAllDropdowns');
scope.query.displaySums = !scope.query.displaySums;
// This eventually calls the resize event handler defined in the
// WorkPackagesTable directive and ensures that the sum row at the
// table footer is properly displayed.
angular.element($window).trigger('resize');
};
function preventNewQueryAction(event){
if (event && scope.query.isNew()) {
event.preventDefault();
event.stopPropagation();
return false;
}
return true;
}
function showModal() {
scope.$emit('hideAllDropdowns');
this.activate();
}
function showExistingQueryModal(event) {
if( preventNewQueryAction(event) ){
scope.$emit('hideAllDropdowns');
this.activate();
}
}
function allowQueryAction(event, action) {
return allowAction(event, 'query', action);
}
function allowWorkPackageAction(event, action) {
return allowAction(event, 'work_package', action);
}
function allowAction(event, modelName, action) {
if(AuthorisationService.can(modelName, action)){
return true;
} else {
event.preventDefault();
event.stopPropagation();
return false;
}
}
function deleteConfirmed() {
return $window.confirm(I18n.t('js.text_query_destroy_confirmation'));
}
}
};
}

@ -1,86 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
require('./config');
require('./controllers');
require('./directives');
require('./filters');
require('./helpers');
require('./models');
require('./services');
require('./tabs');
require('./view_models');
angular.module('openproject.workPackages')
.factory('ColumnContextMenu', [
'ngContextMenu',
function(ngContextMenu) {
return ngContextMenu({
controller: 'ColumnContextMenuController',
controllerAs: 'contextMenu',
templateUrl: '/templates/work_packages/column_context_menu.html',
container: '.work-packages--list-table-area'
});
}
])
.controller('ColumnContextMenuController', [
'$scope',
'ColumnContextMenu',
'I18n',
'QueryService',
'WorkPackagesTableHelper',
'WorkPackagesTableService',
'columnsModal',
require('./column-context-menu')
])
.constant('PERMITTED_CONTEXT_MENU_ACTIONS', ['edit', 'watch', 'log_time',
'duplicate', 'move', 'copy', 'delete'
])
.factory('WorkPackageContextMenu', [
'ngContextMenu',
function(ngContextMenu) {
return ngContextMenu({
controller: 'WorkPackageContextMenuController',
controllerAs: 'contextMenu',
templateUrl: '/templates/work_packages/work_package_context_menu.html'
});
}
])
.controller('WorkPackageContextMenuController', [
'$scope',
'WorkPackagesTableHelper',
'WorkPackageContextMenuHelper',
'WorkPackageService',
'WorkPackagesTableService',
'I18n',
'$window',
'PERMITTED_CONTEXT_MENU_ACTIONS',
require('./work-package-context-menu')
]);

@ -1,42 +1,42 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
// 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
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
// 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.
//
//= require jquery
//= require jquery-migrate/jquery-migrate
//= require jquery-ujs
//= require jquery-ui
//= require jquery-ui/ui/i18n/jquery.ui.datepicker-en-GB.js
//= require jquery-ui/ui/i18n/jquery.ui.datepicker-de.js
//= require lodash
//= require momentjs
//= require momentjs/lang/en-gb.js
//= require momentjs/lang/de.js
//= require moment-timezone/moment-timezone.js
//= require moment-timezone/moment-timezone-data.js
//= require jquery.atwho/dist/js/jquery.atwho.js
//= require Caret.js/src/jquery.caret.js
//= require jquery_noconflict
// 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.
//++
//= require ./bundles/openproject-global
//# require jquery_noconflict
//= require prototype
//= require effects
//= require dragdrop
//= require controls
//= require i18n/translations
//= require lib/jquery.colorcontrast
//= require lib/jquery.trap
//= require select2
//= require top_menu
//= require action_menu
//= require openproject
@ -46,7 +46,6 @@
//= require ajaxappender
//= require settings
//= require modal
//= require keyboard_shortcuts
//= require tab_handling
//= require top-shelf
//= require unsupported-browsers
@ -56,7 +55,13 @@
//= require versions
//= require_tree ./specific
//= require ./openproject-app.bundle
//= require ./bundles/openproject-core-app
//= require_tree ./bundles
//= require custom-fields
//= require date-range
//= require search
//= require colors
//source: http://stackoverflow.com/questions/8120065/jquery-and-prototype-dont-work-together-with-array-prototype-reverse
if (typeof []._reverse == 'undefined') {
@ -80,48 +85,6 @@ jQuery(document).ready(function ($) {
}
});
if (typeof CS !== "undefined") {
var regions = $.datepicker.regional;
var regional = regions[CS.lang] || regions[""];
$.datepicker.setDefaults(regional);
var gotoToday = $.datepicker._gotoToday;
$.datepicker._gotoToday = function (id) {
gotoToday.call(this, id);
var target = $(id),
inst = this._getInst(target[0]),
dateStr = $.datepicker._formatDate(inst);
target.val(dateStr);
target.blur();
$.datepicker._hideDatepicker();
};
var defaults = {
showWeek: true,
changeMonth: true,
changeYear: true,
yearRange: "c-100:c+10",
dateFormat: 'yy-mm-dd',
showButtonPanel: true,
calculateWeek: function (day) {
var dayOfWeek = new Date(+day);
if (day.getDay() != 1) {
dayOfWeek.setDate(day.getDate() - day.getDay() + 1);
}
return $.datepicker.iso8601Week(dayOfWeek);
}
};
if (CS.firstWeekDay && CS.firstWeekDay !== "") {
defaults.firstDay = parseInt(CS.firstWeekDay, 10);
}
$.datepicker.setDefaults(defaults);
}
$(document).on('click', '#show_more_wp_properties', function(el){
$(this).find('.icon').toggleClass('icon-arrow-right6-3 icon-arrow-right6-1');
Effect.toggle("work_package_descr_fields", "appear", {duration:0.3});
@ -129,7 +92,6 @@ jQuery(document).ready(function ($) {
return false;
});
});
function checkAll (id, checked) {
@ -826,42 +788,44 @@ var I18nForms = (function ($) {
update_interaction_elements,
update_locale_availability;
active_locale_selectors = function (localized_p) {
return localized_p.find('.locale_selector');
active_locale_selectors = function (localizedField) {
return localizedField.find('.locale_selector');
};
add_locale_fields = function (localized_p) {
var backup = localized_p.find('.translation').first(),
add_link = localized_p.find('.add_locale'),
new_items = backup.clone();
add_locale_fields = function (localizedField) {
var backup = localizedField.find('.translation').first(),
add_link = localizedField.find('.add_locale'),
new_items = backup.clone(),
new_language_selector = new_items.find('.locale_selector'),
other_language_selectors = active_locale_selectors(localizedField);
new_items.find('input, textarea').val("");
new_items.insertBefore(add_link);
select_first_untaken_option(new_items.find('.locale_selector'), active_locale_selectors(localized_p));
update_interaction_elements(localized_p);
select_first_untaken_option(new_language_selector, other_language_selectors);
update_interaction_elements(localizedField);
new_items.find('.destroy_locale').click(function () {
destroy_locale($(this));
});
observe_destroy_locale_links(new_items.find('.destroy_locale'));
};
destroy_locale = function (element) {
var localized_p = element.closest('p');
var localizedField = element.closest('.form--field');
element.closest('.translation').remove();
update_interaction_elements(localized_p);
update_interaction_elements(localizedField);
};
observe_add_locale_link = function () {
$('.add_locale').click(function () {
add_locale_fields($(this).closest('p'));
observe_add_locale_link = function (selector) {
$(selector).click(function (event) {
event.preventDefault();
add_locale_fields($(this).closest('.form--field'));
});
};
observe_destroy_locale_links = function () {
$('.destroy_locale').click(function () {
observe_destroy_locale_links = function (selector) {
$(selector).click(function (event) {
event.preventDefault();
destroy_locale($(this));
});
};
@ -883,12 +847,12 @@ var I18nForms = (function ($) {
select.val(available.pop());
};
update_add_link_status = function (localized_p) {
var indicator_selector = active_locale_selectors(localized_p),
update_add_link_status = function (localizedField) {
var indicator_selector = active_locale_selectors(localizedField),
taken = taken_options(indicator_selector),
all_options,
available,
add_link = localized_p.find('.add_locale');
add_link = localizedField.find('.add_locale');
available = indicator_selector.first().find('option').map(function (index, element) {
element = $(element);
@ -901,20 +865,20 @@ var I18nForms = (function ($) {
add_link.toggle(available.size() > 0);
};
update_destroy_link_status = function (localized_p) {
var active_selectors = active_locale_selectors(localized_p);
update_destroy_link_status = function (localizedField) {
var active_selectors = active_locale_selectors(localizedField);
localized_p.find('.destroy_locale').toggle(active_selectors.size() > 1);
localizedField.find('.destroy_locale').toggle(active_selectors.size() > 1);
};
update_interaction_elements = function (localized_p) {
update_locale_availability(localized_p);
update_add_link_status(localized_p);
update_destroy_link_status(localized_p);
update_interaction_elements = function (localizedField) {
update_locale_availability(localizedField);
update_add_link_status(localizedField);
update_destroy_link_status(localizedField);
};
update_locale_availability = function (localized_p) {
var active_selectors = active_locale_selectors(localized_p),
update_locale_availability = function (localizedField) {
var active_selectors = active_locale_selectors(localizedField),
active_locales = taken_options(active_selectors);
active_selectors.each(function (index, element) {
@ -938,10 +902,10 @@ var I18nForms = (function ($) {
};
init = function () {
observe_add_locale_link();
observe_destroy_locale_links();
observe_add_locale_link($('.add_locale'));
observe_destroy_locale_links($('.destroy_locale'));
$('form .translation').closest('p').each(function (i, element) {
$('form .translation').closest('.form--field').each(function (i, element) {
element = $(element);
update_interaction_elements(element);
});
@ -1145,13 +1109,13 @@ var I18nForms = (function ($) {
})();
init = function () {
var translated_paragraph = $('form .translation').closest('p');
var translatedField = $('form .translation').closest('.form--field');
if (translated_paragraph.size() > 0) {
if (translatedField.size() > 0) {
memorize_ids();
event_handler.init();
translated_paragraph.closest('form').submit(function () {
translatedField.closest('form').submit(function () {
submit_preparer.prepare($(this));
// allow default behaviour
});
@ -1227,23 +1191,3 @@ var SubmitConfirm = (function($) {
init: init
};
})(jQuery);
var Preview = (function ($) {
$('document').ready(function() {
$('html').on('click','a.preview', function() {
$.ajax({
url: $(this).attr('href'),
type: 'POST',
data: $("#" + $(this).attr('id').replace(/-preview/, "")).serialize().replace('_method=put&', ''),
success: function(data) { $('#preview').html(data);
$('html, body').animate({
scrollTop: $('#preview').offset().top
},
'slow');
}
});
return false;
});
});
})(jQuery);

@ -1,6 +1,6 @@
<%#-- copyright
OpenProject is a project management system.
Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -0,0 +1,54 @@
//-- 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.
//++
(function ($) {
$(function() {
$('.timelines-x-update-color').each(function() {
var preview, input, func, target;
preview = $(this);
target = preview.data('target');
if(target) {
input = $(target);
} else {
input = preview.next('input');
}
if (input.length === 0) {
return;
}
func = function () {
preview.css('background-color', input.val());
};
input.keyup(func).change(func).focus(func);
func();
});
});
}(jQuery));

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -0,0 +1,129 @@
//-- 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.
//++
(function($) {
/*
* @see /app/views/custom_fields/_form.html.erb
*/
$(function() {
var customFieldForm = $('#custom_field_form');
if (customFieldForm.length === 0) {
return;
}
// collect the nodes involved
var format = $('#custom_field_field_format'),
lengthField = $('#custom_field_length'),
regexpField = $('#custom_field_regexp'),
possibleValues = $('#custom_field_possible_values_attributes'),
defaultValueFields = $('#custom_field_default_value_attributes'),
spanDefaultTextMulti = $('#default_value_text_multi'),
spanDefaultTextSingle = $('#default_value_text_single'),
spanDefaultBool = $('#default_value_bool');
var deactivate = function(element) {
element.hide().find('input, textarea').not('.destroy_flag').attr('disabled', true);
},
activate = function(element) {
element.show().find('input, textarea').not('.destroy_flag').removeAttr('disabled');
},
toggleVisibility = function(method, args) {
var fields = Array.prototype.slice.call(args);
$.each(fields, function(idx, field) {
field.closest('.form--field, .form--grouping')[method]();
});
},
hide = function() { toggleVisibility('hide', arguments); },
show = function() { toggleVisibility('show', arguments); },
toggleFormat = function() {
var searchable = $('#searchable_container'),
unsearchable = function() { searchable.attr('checked', false).hide(); };
// defaults (reset these fields before doing anything else)
$.each([spanDefaultBool, spanDefaultTextSingle], function(idx, element) {
deactivate(element);
});
show(defaultValueFields);
activate(spanDefaultTextMulti);
switch (format.val()) {
case 'list':
hide(lengthField, regexpField);
show(searchable);
activate(possibleValues);
break;
case 'bool':
activate(spanDefaultBool);
deactivate(spanDefaultTextMulti);
deactivate(possibleValues);
hide(lengthField, regexpField, searchable);
unsearchable();
break;
case 'date':
activate(spanDefaultTextSingle);
deactivate(spanDefaultTextMulti);
deactivate(possibleValues);
hide(lengthField, regexpField);
unsearchable();
break;
case 'float':
case 'int':
activate(spanDefaultTextSingle);
deactivate(spanDefaultTextMulti);
deactivate(possibleValues);
show(lengthField, regexpField);
unsearchable();
break;
case 'user':
case 'version':
deactivate(defaultValueFields);
deactivate(possibleValues);
hide(lengthField, regexpField, defaultValueFields);
unsearchable();
break;
default:
show(lengthField, regexpField, searchable);
deactivate(possibleValues);
break;
}
};
// assign the switch format function to the select field
format.on('change', toggleFormat).trigger('change');
});
$(function() {
var localeSelectors = $('.locale_selector');
localeSelectors.change(function () {
var lang = $(this).val(),
span = $(this).closest('.translation');
span.attr('lang', lang);
}).trigger('change');
});
}(jQuery));

@ -0,0 +1,53 @@
//-- 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.
//++
(function($) {
$(function() {
/*
* See /app/views/timelog/_date_range.html.erb
*/
if ($('#date-range').length < 1) {
return;
}
var intervalInputs = $('#to, #from'),
// select
period = $('#period'),
// radio buttons
periodOptionList = $('#period_type_list'),
periodOptionInterval = $('#period_type_interval');
var activateRadiobutton = function(radioButton) {
return function() {
radioButton.attr('checked', true);
};
};
intervalInputs.on('click focus', activateRadiobutton(periodOptionInterval));
period.on('click focus', activateRadiobutton(periodOptionList));
});
}(jQuery));

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -206,11 +206,6 @@ jsToolBar.prototype = {
}
this.toolNodes = {}; // vide les raccourcis DOM/**/
var h = document.createElement('div');
h.className = 'help';
h.innerHTML = this.help_link;
this.toolbar.appendChild(h);
// Draw toolbar elements
var b, tool, newTool;
@ -231,6 +226,7 @@ jsToolBar.prototype = {
}
}
}
this.toolbar.appendChild(this.help_link);
},
singleTag: function(stag,etag) {

@ -1,196 +0,0 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 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.
//++
//= require mousetrap
(function($){
var accessibleListSelector = "table.list, table.keyboard-accessible-list";
var accessibleRowSelector = "table.list tr, table.keyboard-accessible-list tr";
var menu_sidebar = function() {
return $('div#menu-sidebar');
};
var we_are_in_project = function() {
return menu_sidebar().size() === 1;
};
var show_help_modal = function(){
var relative_url_root = jQuery('body').data('relative_url_root');
var template_path = relative_url_root + 'help/keyboard_shortcuts';
modalHelperInstance.createModal(template_path);
};
var go_overview = function(){
if (we_are_in_project()) {
menu_sidebar().find('.overview')[0].click();
}
};
var go_my_page = function(){
var my_page = $('.account-nav .my-page');
if (my_page.size() === 1) {
my_page[0].click();
}
};
var go_work_packages = function(){
if (we_are_in_project()) {
menu_sidebar().find('.work-packages')[0].click();
}
};
var go_timelines = function(){
if (we_are_in_project()) {
menu_sidebar().find('.timelines')[0].click();
}
};
var go_wiki = function(){
if (we_are_in_project()) {
menu_sidebar().find('.Wiki')[0].click();
}
};
var go_activity = function(){
if (we_are_in_project()) {
menu_sidebar().find('.activity')[0].click();
}
};
var go_calendar = function(){
if (we_are_in_project()) {
menu_sidebar().find('.calendar')[0].click();
}
};
var go_news = function(){
if (we_are_in_project()) {
menu_sidebar().find('.news')[0].click();
}
};
var go_edit = function(){
edit_link = $('[accesskey=3]')[0];
if (edit_link !== undefined) {
edit_link.click();
}
};
var open_more_menu = function(){
more_menu = $('[accesskey=7]')[0];
if (more_menu !== undefined) {
more_menu.click();
}
};
var go_preview = function(){
preview_link = $('[accesskey=1]')[0];
if (preview_link !== undefined) {
preview_link.click();
}
};
var new_work_package = function(){
if (we_are_in_project()) {
menu_sidebar().find('.new-work-package')[0].click();
}
};
var search_project = function(){
$('#project-search-container').parents('li.drop-down').click();
};
var search_global = function(){
$('#search_wrap .search_field').focus();
};
var find_list_in_page = function(){
var dom_lists, focus_elements;
focus_elements = [];
dom_lists = $(accessibleListSelector);
dom_lists.find('tbody tr').each(function(index, tr){
var first_link = $(tr).find('a:visible')[0];
if ( first_link !== undefined ) { focus_elements.push(first_link); }
});
return focus_elements;
};
var focus_item_offset = function(offset){
var list, index;
list = find_list_in_page();
if (list === null) { return; }
index = list.indexOf($(document.activeElement).parents(accessibleRowSelector).find('a:visible')[0]);
$(list[(index+offset+list.length) % list.length]).focus();
};
var focus_next_item = function(){
focus_item_offset(1);
};
var focus_previous_item = function(){
focus_item_offset(-1);
};
Mousetrap.bind('?', function(){ show_help_modal(); return false; });
Mousetrap.bind('g o', function(){ go_overview(); return false; });
Mousetrap.bind('g m', function(){ go_my_page(); return false; });
Mousetrap.bind('g w p', function(){ go_work_packages(); return false; });
Mousetrap.bind('g w i', function(){ go_wiki(); return false; });
Mousetrap.bind('g a', function(){ go_activity(); return false; });
Mousetrap.bind('g c', function(){ go_calendar(); return false; });
Mousetrap.bind('g n', function(){ go_news(); return false; });
Mousetrap.bind('g t', function(){ go_timelines(); return false; });
Mousetrap.bind('g e', function(){ go_edit(); return false; });
Mousetrap.bind('g p', function(){ go_preview(); return false; });
Mousetrap.bind('n w p', function(){ new_work_package(); return false; });
Mousetrap.bind('j', function(){ focus_next_item(); return false; });
Mousetrap.bind('k', function(){ focus_previous_item(); return false; });
Mousetrap.bind('m', function(){ open_more_menu(); return false; });
Mousetrap.bind('p', function(){ search_project(); return false; });
Mousetrap.bind('s', function(){ search_global(); return false; });
jQuery(function(){
// simulated hover effect on table lists when using the keyboard
var tables = jQuery(accessibleListSelector);
if (tables.size() === 0) { return; }
tables.on('blur', 'tr *', function(){
jQuery(this).parents(accessibleRowSelector).removeClass('keyboard_hover');
});
tables.on('focus', 'tr *', function(){
jQuery(this).parents(accessibleRowSelector).addClass('keyboard_hover');
});
});
})(jQuery);

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
<%#-- copyright
OpenProject is a project management system.
Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -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.
//++
(function($) {
$(function() {
/*
* @see /app/views/search/index.html.erb
*/
if ($('#search-filter').length < 1) {
return;
}
$('#search-input').focus();
});
}(jQuery));

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
<%#-- copyright
OpenProject is a project management system.
Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
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.

@ -1,6 +1,6 @@
<%#-- copyright
OpenProject is a project management system.
Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.
@ -75,7 +75,7 @@ function toggleFieldset(el) {
}
jQuery(document).ready(function() {
jQuery('fieldset.header_collapsible').each(function(index) {
jQuery('fieldset.form--fieldset.-collapsible').each(function() {
var fieldset = getFieldset(this);
setFieldsetToggleState(fieldset);

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.
@ -32,10 +32,10 @@
ModalHelper.prototype.create = function(projectId) {
var modalHelper = this;
var url = modalHelper.options.url_prefix +
modalHelper.options.project_prefix +
"/" +
projectId +
'/work_packages/new';
modalHelper.options.project_prefix +
"/" +
projectId +
'/work_packages/new';
//create the modal by using the html the url gives us.
modalHelper.createModal(url);

@ -1,6 +1,6 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2014 the OpenProject Foundation (OPF)
// 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.
@ -93,7 +93,7 @@ jQuery(document).ready(function($) {
[
$("#reporting_reporting_to_project_id"),
$("#project_association_select_project_b_id")
$("#project_association_project_b_id")
].forEach(function (item) {
// Stuff borrowed from Core application.js Project Jump Box
$(item).autocomplete({
@ -147,24 +147,22 @@ jQuery(document).ready(function($) {
});
});
$("#content").find("input").each(function (index, e) {
e = $(e);
if (
((e.attr("type") === "text" || e.attr("type") === "hidden") && e.val() !== "" && !e.hasClass("select2-input")) ||
(e.attr("type") === "checkbox" && e.attr("checked"))
) {
showFieldSet(e);
}
});
var fields = $("#content").find("input")
.not("[type='radio']")
.not("[class^='select2-']")
.not(".button")
.not("[type='hidden']");
$('#content').find('.cf_boolean_select').each(function (index, field) {
field = $(field);
if (field.val() !== '') {
showFieldSet(field);
fields.each(function(idx, element) {
var el = $(element);
if (el.is(":checked") && el.is("[type='checkbox']")) {
showFieldSet(el);
}
if (el.is("[type='text']") && el.val() !== "") {
showFieldSet(el);
}
});
function showFieldSet(field) {
field.closest("fieldset").removeClass('collapsed').children("div").show();
field.closest("fieldset").removeClass("collapsed").children("div").show();
}
});

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

Loading…
Cancel
Save