From 678b0bc1871d6720d6537acbadcc7746c1b3390c Mon Sep 17 00:00:00 2001 From: Hagen Schink Date: Tue, 18 Mar 2014 10:33:58 +0100 Subject: [PATCH 01/40] Adds spec --- .../work_package_custom_fields_spec.rb | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/models/work_package/work_package_custom_fields_spec.rb b/spec/models/work_package/work_package_custom_fields_spec.rb index c15b10811a..55762b1141 100644 --- a/spec/models/work_package/work_package_custom_fields_spec.rb +++ b/spec/models/work_package/work_package_custom_fields_spec.rb @@ -229,5 +229,27 @@ describe WorkPackage do it { should eq('true') } end end + + describe "custom field type 'text'" do + let(:value) { "text" * 1024 } + let(:custom_field) { FactoryGirl.create(:work_package_custom_field, + name: 'Test Text', + field_format: 'text', + is_required: true) } + + include_context "project with required custom field" + + it_behaves_like "work package with required custom field" + + describe 'value' do + before do + change_custom_field_value(work_package, value) + end + + subject { work_package.journals.first.customizable_journals.first.value } + + it { expect(subject).to eq(value) } + end + end end end From 733c063797349fea50c5ab7f4460f3a779f03c1b Mon Sep 17 00:00:00 2001 From: Hagen Schink Date: Tue, 18 Mar 2014 10:35:27 +0100 Subject: [PATCH 02/40] Fix customizable journal's value column --- ...3_fix_customizable_journal_value_column.rb | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 db/migrate/20130813062523_fix_customizable_journal_value_column.rb diff --git a/db/migrate/20130813062523_fix_customizable_journal_value_column.rb b/db/migrate/20130813062523_fix_customizable_journal_value_column.rb new file mode 100644 index 0000000000..abbf2487de --- /dev/null +++ b/db/migrate/20130813062523_fix_customizable_journal_value_column.rb @@ -0,0 +1,38 @@ +#-- encoding: UTF-8 +#-- 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. +#++ + +class FixCustomizableJournalValueColumn < ActiveRecord::Migration + def up + change_column :customizable_journals, :value, :text + end + + def down + change_column :customizable_journals, :value, :string + end +end From 201a3dcd47e6782c178673adffb2e61409666960 Mon Sep 17 00:00:00 2001 From: Ion Biziiac Date: Tue, 18 Mar 2014 15:27:58 +0200 Subject: [PATCH 03/40] Fixes referencing work packages in news --- app/views/news/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/news/index.html.erb b/app/views/news/index.html.erb index e5c0ee36bb..131b5e4382 100644 --- a/app/views/news/index.html.erb +++ b/app/views/news/index.html.erb @@ -38,7 +38,7 @@ See doc/COPYRIGHT.rdoc for more details. <%= "(#{l(:label_x_comments, :count => news.comments_count)})" if news.comments_count > 0 %>

<%= authoring news.created_on, news.author %>

- <%= textilizable(news.summary.present? ? news.summary : truncate(news.description)) %> + <%= textilizable(news.summary.present? ? news.summary : truncate(news.description), :object => news) %>
<% end %> <% end %> From 1cf217d3e76e30146e62b3f1135edb890deb0e9e Mon Sep 17 00:00:00 2001 From: Ion Biziiac Date: Tue, 18 Mar 2014 15:28:20 +0200 Subject: [PATCH 04/40] Fixes referencing work packages in forums --- app/views/messages/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index 3be927943f..2a64927552 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -56,7 +56,7 @@ See doc/COPYRIGHT.rdoc for more details.

<%= authoring @topic.created_on, @topic.author %>

-<%= textilizable(@topic.content, :attachments => @topic.attachments) %> +<%= textilizable(@topic.content, :object => @topic, :attachments => @topic.attachments) %>
<%= link_to_attachments @topic, :author => false %>
From b75777ae5383154e60c7ad81a8c03dd7cc43fbe9 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 18 Mar 2014 17:47:47 +0100 Subject: [PATCH 05/40] Fix total sums for work package custom field columns --- app/controllers/work_packages_controller.rb | 36 ++++++++++++--------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index b5435272e2..c6cea26141 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -285,32 +285,34 @@ class WorkPackagesController < ApplicationController column_names = params[:column_names] project = Project.find_visible(current_user, params[:id]) work_packages = project.work_packages - sums = column_names.map do |column_name| - column_is_numeric?(column_name) ? fetch_column_data(column_name, work_packages).map{|c| c.nil? ? 0 : c}.sum : nil + fetch_column_data(column_name, work_packages).map{|c| c.nil? ? 0 : c}.compact.sum if column_is_numeric?(column_name) end render json: sums end def fetch_columns_data(column_names, work_packages) - columns = column_names.map do |column_name| + column_names.map do |column_name| fetch_column_data(column_name, work_packages) end end def fetch_column_data(column_name, work_packages) - column = if column_name =~ /cf_(.*)/ - work_packages.map do |work_package| - value = work_package.custom_values.find_by_custom_field_id($1) and value.nil? ? {} : value.attributes - end - else - work_packages.map do |work_package| - # Note: Doing as_json here because if we just take the value.attributes then we can't get any methods later. - # Name and subject are the default properties that the front end currently looks for to summarize an object. - value = work_package.send(column_name) and value.is_a?(ActiveRecord::Base) ? value.as_json( only: "id", methods: [:name, :subject] ) : value - end + if column_name =~ /cf_(.*)/ + custom_field = CustomField.find($1) + work_packages.map do |work_package| + custom_value = work_package.custom_values.find_by_custom_field_id($1) + custom_field.cast_value custom_value.try(:value) + end + else + work_packages.map do |work_package| + # Note: Doing as_json here because if we just take the value.attributes then we can't get any methods later. + # Name and subject are the default properties that the front end currently looks for to summarize an object. + value = work_package.send(column_name) + value.is_a?(ActiveRecord::Base) ? value.as_json( only: "id", methods: [:name, :subject] ) : value end + end end def column_is_numeric?(column_name) @@ -319,7 +321,12 @@ class WorkPackagesController < ApplicationController end def column_type(column_name) - column_name =~ /cf_(.*)/ ? CustomField.find($1).field_format.to_sym : (c = WorkPackage.columns_hash[column_name] and c.nil? ? :none : c.type) + if column_name =~ /cf_(.*)/ + CustomField.find($1).field_format.to_sym + else + column = WorkPackage.columns_hash[column_name] + column.nil? ? :none : column.type + end end @@ -525,7 +532,6 @@ class WorkPackagesController < ApplicationController def push_query_and_results_via_gon(results, work_packages) get_query_and_results_as_json(results, work_packages).each_pair do |name, value| - # binding.pry if name == :query gon.send "#{name}=", value end # TODO later versions of gon support gon.push {Hash} - on the other hand they make it harder to deliver data to gon inside views From d39af8d0159025e1e81c396c3dbbedc760d93388 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 18 Mar 2014 17:47:59 +0100 Subject: [PATCH 06/40] Don't request columns sums when columns are removed --- .../work_packages/work-package-total-sums-directive.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/work-package-total-sums-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-total-sums-directive.js index ea1c253a2b..9431004bab 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-package-total-sums-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-package-total-sums-directive.js @@ -15,9 +15,9 @@ angular.module('openproject.workPackages.directives') }); } - scope.$watch('columns.length', function() { + scope.$watch('columns.length', function(length, formerLength) { // map columns to sums if the column data is a number - fetchSums(); + if(length >= formerLength) fetchSums(); }); } }; From 67c0eaa0f3dd7cbe025082f2b04b140ca37e6d0c Mon Sep 17 00:00:00 2001 From: slawa Date: Wed, 12 Mar 2014 10:29:38 +0200 Subject: [PATCH 07/40] Respect sticky date in message order --- app/controllers/boards_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 7f27694949..efc9dcd949 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -58,16 +58,18 @@ class BoardsController < ApplicationController 'replies' => "#{Message.table_name}.replies_count", 'updated_on' => "#{Message.table_name}.updated_on" - @topics = @board.topics.order(["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', ')) + @topics = @board.topics.order(["#{Message.table_name}.sticked_on ASC", sort_clause].compact.join(', ')) .includes(:author, { :last_reply => :author }) .page(params[:page]) .per_page(per_page_param) + + @message = Message.new render :action => 'show', :layout => !request.xhr? } format.atom { - @messages = @board.messages.order('created_on DESC') + @messages = @board.messages.order(["#{Message.table_name}.sticked_on ASC", sort_clause].compact.join(', ')) .includes(:author, :board) .limit(Setting.feeds_limit.to_i) From 42c2f1f24abd8950f5baa802ec9400cd2ec3b45c Mon Sep 17 00:00:00 2001 From: slawa Date: Wed, 12 Mar 2014 10:31:27 +0200 Subject: [PATCH 08/40] Save sticky date if sticky is set --- app/controllers/messages_controller.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 172fee399b..e0d9db69fd 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -76,6 +76,10 @@ class MessagesController < ApplicationController @message.safe_attributes = params[:message] + if params[:message]['sticky'] == "1" + @message.update_attribute(:sticked_on,Time.now) + end + @message.attach_files(params[:attachments]) if @message.save From ffbf6d351085cbb8718a011ef5007d8af23f3238 Mon Sep 17 00:00:00 2001 From: slawa Date: Wed, 12 Mar 2014 10:32:29 +0200 Subject: [PATCH 09/40] Respect sticky in default order --- app/models/board.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/board.rb b/app/models/board.rb index 608b551064..6b8fd1b75b 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -31,8 +31,8 @@ class Board < ActiveRecord::Base include ActiveModel::ForbiddenAttributesProtection belongs_to :project - has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" - has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC" + has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL" , :order => "#{Message.table_name}.sticky DESC" + has_many :messages, :dependent => :destroy , :order => "#{Message.table_name}.sticky DESC" belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id acts_as_list :scope => :project_id acts_as_watchable From 0b302a3f460aa9a7872d2072229ff87c535c7e19 Mon Sep 17 00:00:00 2001 From: slawa Date: Wed, 12 Mar 2014 10:35:23 +0200 Subject: [PATCH 10/40] Add new colum sticked_on Using data from this column will help us to put sticky messages on top of messages list --- ...120609_add_sticked_on_field_to_messages.rb | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 db/migrate/20140311120609_add_sticked_on_field_to_messages.rb diff --git a/db/migrate/20140311120609_add_sticked_on_field_to_messages.rb b/db/migrate/20140311120609_add_sticked_on_field_to_messages.rb new file mode 100644 index 0000000000..252824a6a5 --- /dev/null +++ b/db/migrate/20140311120609_add_sticked_on_field_to_messages.rb @@ -0,0 +1,34 @@ +#-- encoding: UTF-8 +#-- 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. +#++ + +class AddStickedOnFieldToMessages < ActiveRecord::Migration + def change + add_column :messages, :sticked_on, :datetime, default: nil, null: true + end +end From 5cc6e26b10c7d840a4afeeaf0d19d19bec52ece3 Mon Sep 17 00:00:00 2001 From: slawa Date: Wed, 12 Mar 2014 13:49:36 +0200 Subject: [PATCH 11/40] Add cuke --- features/messages/message.feature | 39 ++++++++++++++++------- features/step_definitions/common_steps.rb | 3 ++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/features/messages/message.feature b/features/messages/message.feature index 944a66c812..a8448fab49 100644 --- a/features/messages/message.feature +++ b/features/messages/message.feature @@ -27,23 +27,24 @@ #++ Feature: Issue textile quickinfo links + Background: Given there is 1 project with the following: - | name | parent | - | identifier | parent | + | name | parent | + | identifier | parent | And I am working in project "parent" And there is a board "development discussion" for project "parent" And there is a role "member" And the role "member" may have the following rights: - | manage_boards | - | add_messages | - | edit_messages | - | edit_own_messages | - | delete_messages | - | delete_messages | - | delete_own_messages | + | manage_boards | + | add_messages | + | edit_messages | + | edit_own_messages | + | delete_messages | + | delete_messages | + | delete_own_messages | And there is 1 user with the following: - | login | bob| + | login | bob | And the user "bob" is a "member" in the project "parent" And I am already logged in as "bob" @@ -65,7 +66,7 @@ Feature: Issue textile quickinfo links Scenario: Message's reply count is two Given the board "development discussion" has the following messages: | message #1 | - And "message #1" has the following replies: + And "message #1" has the following replies: | reply #1 | | reply #2 | When I go to the message page of message "message #1" @@ -85,4 +86,18 @@ Feature: Issue textile quickinfo links And I fill in "Here you find the most frequently asked questions" for "message_content" When I click on the first button matching "Create" Then there should be an error message - Then the "message_content" field should contain "Here you find the most frequently asked questions" \ No newline at end of file + Then the "message_content" field should contain "Here you find the most frequently asked questions" + + Scenario: Sticky message on top of messages list + Given the board "development discussion" has the following messages: + | message #1 | + | message #2 | + | message #3 | + When I go to the boards page of the project called "parent" + And I follow "New message" + And I fill in "How to?" for "message_subject" + And I fill in "How to st-up project on local mashine." for "message_content" + And I check "Sticky" + When I click on the first button matching "Create" + And I go to the boards page of the project called "parent" + Then "How to?" should be the first row in table diff --git a/features/step_definitions/common_steps.rb b/features/step_definitions/common_steps.rb index 86749af4c1..caf53eae25 100644 --- a/features/step_definitions/common_steps.rb +++ b/features/step_definitions/common_steps.rb @@ -75,3 +75,6 @@ Then(/^I should see the following fields:$/) do |table| end end +Then(/^"([^"]*)" should be the first row in table$/) do |name| + should have_selector("table.list tbody tr td", :text => Regexp.new("#{name}")) +end \ No newline at end of file From c8a15571f2a94b4d9954ced329bdb3f9820b7e3d Mon Sep 17 00:00:00 2001 From: slawa Date: Fri, 14 Mar 2014 15:20:37 +0200 Subject: [PATCH 12/40] Reset sticky date when sticky option is reset --- app/models/message.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/models/message.rb b/app/models/message.rb index f8e6e0dfff..34dafd79d7 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -85,11 +85,21 @@ class Message < ActiveRecord::Base validate :validate_unlocked_root, :on => :create + before_save :set_sticked_on_date + # Can not reply to a locked topic def validate_unlocked_root errors.add :base, 'Topic is locked' if root.locked? && self != root end + def set_sticked_on_date + if sticky? + self.sticked_on = Time.now + else + self.sticked_on = nil + end + end + def update_last_reply_in_parent if parent parent.reload.update_attribute(:last_reply_id, self.id) From a070cee3d7117b1535e0ca1f1529ace8df4cc4d3 Mon Sep 17 00:00:00 2001 From: slawa Date: Tue, 18 Mar 2014 10:28:36 +0200 Subject: [PATCH 13/40] Fix sticky date set --- app/controllers/messages_controller.rb | 12 ++++-------- app/models/message.rb | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index e0d9db69fd..5a8db93ccd 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -50,10 +50,10 @@ class MessagesController < ApplicationController page = 1 + offset / REPLIES_PER_PAGE end - @replies = @topic.children.includes(:author, :attachments, {:board => :project}) - .order("#{Message.table_name}.created_on ASC") - .page(page) - .per_page(per_page_param) + @replies = @topic.children.includes(:author, :attachments, {:board => :project}) + .order("#{Message.table_name}.created_on ASC") + .page(page) + .per_page(per_page_param) @reply = Message.new(:subject => "RE: #{@message.subject}") render :action => "show", :layout => !request.xhr? @@ -76,10 +76,6 @@ class MessagesController < ApplicationController @message.safe_attributes = params[:message] - if params[:message]['sticky'] == "1" - @message.update_attribute(:sticked_on,Time.now) - end - @message.attach_files(params[:attachments]) if @message.save diff --git a/app/models/message.rb b/app/models/message.rb index 34dafd79d7..0b63063e00 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -94,7 +94,7 @@ class Message < ActiveRecord::Base def set_sticked_on_date if sticky? - self.sticked_on = Time.now + self.sticked_on = sticked_on.nil? ? Time.now : sticked_on else self.sticked_on = nil end From f6c7308ad295789d3d29f6ab7fa6563e73fa5a07 Mon Sep 17 00:00:00 2001 From: slawa Date: Mon, 17 Mar 2014 17:44:17 +0200 Subject: [PATCH 14/40] Add specs --- spec/controllers/boards_controller_spec.rb | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/spec/controllers/boards_controller_spec.rb b/spec/controllers/boards_controller_spec.rb index dde736a008..59f5ff4184 100644 --- a/spec/controllers/boards_controller_spec.rb +++ b/spec/controllers/boards_controller_spec.rb @@ -175,4 +175,63 @@ describe BoardsController do end end + + describe :sticky do + + let!(:message1) { FactoryGirl.create(:message, board: board) } + let!(:message2) { FactoryGirl.create(:message, board: board) } + let!(:sticked_message1) { FactoryGirl.create(:message, board_id: board.id, subject: "How to", + content: "How to install this cool app", sticky: "1", sticked_on: Time.now - 2.minute) } + + let!(:sticked_message2) { FactoryGirl.create(:message, board_id: board.id, subject: "FAQ", + content: "Frequestly asked question", sticky: "1", sticked_on: Time.now - 1.minute) } + + describe "all sticky messages" do + before do + @controller.should_receive(:authorize) + get :show, project_id: project.id, id: board.id + end + + it { expect(response).to render_template 'show' } + it "should be displayed on top" do + expect(assigns[:topics][0].id).to eq(sticked_message1.id) + end + end + + describe "edit a sticky message" do + before(:each) do + sticked_message1.sticky = 0 + sticked_message1.save! + end + + describe "when sticky is unset from message" do + before do + @controller.should_receive(:authorize) + get :show, project_id: project.id, id: board.id + end + + it "it should not be displayed as sticky message" do + + expect(sticked_message1.sticked_on).to be_nil + expect(assigns[:topics][0].id).to_not eq(sticked_message1.id) + end + end + + describe "when sticky is set back to message" do + before do + sticked_message1.sticky = 1 + sticked_message1.save! + + @controller.should_receive(:authorize) + get :show, project_id: project.id, id: board.id + end + + it "it should not be displayed on first position" do + expect(assigns[:topics][0].id).to eq(sticked_message2.id) + end + end + + end + + end end From f0300c07d2aa903e6002ef98fbb6c016ae1e9109 Mon Sep 17 00:00:00 2001 From: Hagen Schink Date: Wed, 19 Mar 2014 08:34:44 +0100 Subject: [PATCH 15/40] Adds changelog entry --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 5891702879..21556e9f01 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -29,6 +29,7 @@ See doc/COPYRIGHT.rdoc for more details. # Changelog +* `#284` Fix: Sticky does not apply to forum * `#2393` Fix: No warning when leaving site without saving * `#2401` Fix: New target version cannot be created from work package view * `#3267` Fix: Link in Breadcrumbs links to global work packages From 359597c9134c9298f9909c881c1f93f5003af4b3 Mon Sep 17 00:00:00 2001 From: Hagen Schink Date: Wed, 19 Mar 2014 09:13:27 +0100 Subject: [PATCH 16/40] Fix test --- app/controllers/boards_controller.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index efc9dcd949..4dc50b1283 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -51,13 +51,13 @@ class BoardsController < ApplicationController end def show + sort_init 'updated_on', 'desc' + sort_update 'created_on' => "#{Message.table_name}.created_on", + 'replies' => "#{Message.table_name}.replies_count", + 'updated_on' => "#{Message.table_name}.updated_on" + respond_to do |format| format.html { - sort_init 'updated_on', 'desc' - sort_update 'created_on' => "#{Message.table_name}.created_on", - 'replies' => "#{Message.table_name}.replies_count", - 'updated_on' => "#{Message.table_name}.updated_on" - @topics = @board.topics.order(["#{Message.table_name}.sticked_on ASC", sort_clause].compact.join(', ')) .includes(:author, { :last_reply => :author }) .page(params[:page]) From 1d37e4fac38160bbc61376dda28509ac4bde37ec Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 18 Mar 2014 17:58:14 +0100 Subject: [PATCH 17/40] Check for settings for building sums of column values --- app/controllers/work_packages_controller.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index c6cea26141..ee67a46182 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -286,7 +286,7 @@ class WorkPackagesController < ApplicationController project = Project.find_visible(current_user, params[:id]) work_packages = project.work_packages sums = column_names.map do |column_name| - fetch_column_data(column_name, work_packages).map{|c| c.nil? ? 0 : c}.compact.sum if column_is_numeric?(column_name) + fetch_column_data(column_name, work_packages).map{|c| c.nil? ? 0 : c}.compact.sum if column_should_be_summed_up?(column_name) end render json: sums @@ -315,6 +315,11 @@ class WorkPackagesController < ApplicationController end end + def column_should_be_summed_up?(column_name) + # see ::Query::Sums mix in + column_is_numeric?(column_name) && Setting.work_package_list_summable_columns.include?(column_name.to_s) + end + def column_is_numeric?(column_name) # TODO RS: We want to leave out ids even though they are numeric [:integer, :float].include? column_type(column_name) From b91da317a3ae9758731bc503c91216926ac44e1e Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 11:12:10 +0100 Subject: [PATCH 18/40] Format date and datetime fields in work packages table --- .../work-package-column-directive.js | 2 +- .../components/work-packages-helper.js | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js index 8ddbdceab0..ea1e993ce9 100644 --- a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js @@ -18,7 +18,7 @@ angular.module('openproject.uiComponents') scope.$watch('workPackage', updateColumnData, true); function updateColumnData() { - scope.displayText = WorkPackagesHelper.getColumnValue(scope.workPackage, scope.column) || defaultText; + scope.displayText = WorkPackagesHelper.getFormattedColumnValue(scope.workPackage, scope.column) || defaultText; scope.displayType = defaultType; // Example of how we can look to the provided meta data to format the column diff --git a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js index ea414047f9..dd34ca7031 100644 --- a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js +++ b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js @@ -1,6 +1,6 @@ angular.module('openproject.uiComponents') -.factory('WorkPackagesHelper', [function() { +.factory('WorkPackagesHelper', ['dateFilter', function(dateFilter) { var WorkPackagesHelper = { getRowObjectContent: function(object, option) { var content = object[option]; @@ -41,7 +41,7 @@ angular.module('openproject.uiComponents') switch(customField.field_format) { case 'int': - return parseInt(customValue.value); + return parseInt(customValue.value, 10); case 'float': return parseFloat(customValue.value); default: @@ -49,14 +49,33 @@ angular.module('openproject.uiComponents') } }, - getColumnValue: function(rowObject, column) { + getFormattedColumnValue: function(rowObject, column) { + var value; + if (column.custom_field) { - return WorkPackagesHelper.getRowObjectCustomValue(rowObject, column.custom_field); + value = WorkPackagesHelper.getRowObjectCustomValue(rowObject, column.custom_field); } else { - return WorkPackagesHelper.getRowObjectContent(rowObject, column.name); + value = WorkPackagesHelper.getRowObjectContent(rowObject, column.name); + } + + return WorkPackagesHelper.formatValue(value, column.meta_data.data_type); + }, + + formatValue: function(value, dataType) { + switch(dataType) { + case 'datetime': + return dateFilter(WorkPackagesHelper.parseDateTime(value), 'medium'); + case 'date': + return dateFilter(value, 'mediumDate'); + default: + return value; } }, + parseDateTime: function(value) { + return new Date(Date.parse(value.replace(/(A|P)M$/, ''))); + }, + projectRowsToColumn: function(rows, column) { return rows.map(function(row){ return WorkPackagesHelper.getColumnValue(row.object, column); From e0221b36923e7fa4dd746e43f2dbe8ce168ae739 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 11:29:03 +0100 Subject: [PATCH 19/40] Include fixed version in work packages table --- app/controllers/work_packages_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index 4d478a12d3..0d84b3255d 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -654,7 +654,8 @@ class WorkPackagesController < ApplicationController responsible: { only: :id, methods: :name }, status: { only: :name }, type: { only: :name }, - parent: { only: :subject } + parent: { only: :subject }, + fixed_version: { only: :name } }.slice(*selected_columns.map(&:name)) selected_associations.merge!(custom_values: { only: [:custom_field_id, :value] }) if selected_columns.any? {|c| c.is_a? QueryCustomFieldColumn} From 53b726b0f0a18d40d11dd9a03df768efecf44c60 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 12:21:01 +0100 Subject: [PATCH 20/40] Render fixed version as link in work packages table --- .../work-package-column-directive.js | 29 ++++++++++--------- .../angular/helpers/components/path-helper.js | 3 ++ app/controllers/work_packages_controller.rb | 7 +++-- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js index ea1e993ce9..53b0add98d 100644 --- a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js @@ -31,20 +31,21 @@ angular.module('openproject.uiComponents') } function getLinkFor(link_meta){ - switch (link_meta.model_type){ - case 'work_package': - url = PathHelper.workPackagePath(scope.workPackage.id); - break; - case 'user': - if (scope.workPackage[scope.column.name]) url = PathHelper.userPath(scope.workPackage[scope.column.name].id); - break; - case 'project': - if (scope.workPackage.project) url = PathHelper.projectPath(scope.workPackage.project.identifier); - break; - default: - url = ""; - }; - return url; + if (link_meta.model_type === 'work_package') { + return PathHelper.workPackagePath(scope.workPackage.id); + } else if (scope.workPackage[scope.column.name]) { + switch (link_meta.model_type) { + case 'user': + return PathHelper.userPath(scope.workPackage[scope.column.name].id); + case 'version': + return PathHelper.versionPath(scope.workPackage[scope.column.name].id); + case 'project': + return PathHelper.projectPath(scope.workPackage.project.identifier); + default: + return ''; + } + + } } } diff --git a/app/assets/javascripts/angular/helpers/components/path-helper.js b/app/assets/javascripts/angular/helpers/components/path-helper.js index 3d0e3f3c95..d5646abc72 100644 --- a/app/assets/javascripts/angular/helpers/components/path-helper.js +++ b/app/assets/javascripts/angular/helpers/components/path-helper.js @@ -23,6 +23,9 @@ angular.module('openproject.uiComponents') }, workPackagesSumsPath: function(projectIdentifier) { return PathHelper.projectPath(projectIdentifier) + '/column_sums'; + }, + versionPath: function(versionId) { + return '/versions/' + versionId; } }; diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index 0d84b3255d..2b9bfeebbc 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -603,7 +603,7 @@ class WorkPackagesController < ApplicationController # Needs to be things like user link,project link, datetime { data_type: column_data_type(column), - link: !!(link_meta()[column.name]) ? link_meta()[column.name] : { display: false } + link: !!(link_meta[column.name]) ? link_meta()[column.name] : { display: false } } end @@ -617,7 +617,8 @@ class WorkPackagesController < ApplicationController assigned_to: { display: true, model_type: "user" }, responsible: { display: true, model_type: "user" }, author: { display: true, model_type: "user" }, - project: { display: true, model_type: "project" } + project: { display: true, model_type: "project" }, + fixed_version: { display: true, model_type: "version" } } end @@ -655,7 +656,7 @@ class WorkPackagesController < ApplicationController status: { only: :name }, type: { only: :name }, parent: { only: :subject }, - fixed_version: { only: :name } + fixed_version: { only: [:name, :id] } }.slice(*selected_columns.map(&:name)) selected_associations.merge!(custom_values: { only: [:custom_field_id, :value] }) if selected_columns.any? {|c| c.is_a? QueryCustomFieldColumn} From ef409772f21490ab081ebae4c4c74848981e7a5b Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 16:27:05 +0100 Subject: [PATCH 21/40] Add progress bar directive --- .../components/progress-bar-directive.js | 24 +++++++++++++++++++ public/templates/components/progress_bar.html | 8 +++++++ 2 files changed, 32 insertions(+) create mode 100644 app/assets/javascripts/angular/directives/components/progress-bar-directive.js create mode 100644 public/templates/components/progress_bar.html diff --git a/app/assets/javascripts/angular/directives/components/progress-bar-directive.js b/app/assets/javascripts/angular/directives/components/progress-bar-directive.js new file mode 100644 index 0000000000..14c7fc29e6 --- /dev/null +++ b/app/assets/javascripts/angular/directives/components/progress-bar-directive.js @@ -0,0 +1,24 @@ +// TODO move to UI components +angular.module('openproject.uiComponents') + +.directive('progressBar', [function() { + return { + restrict: 'EA', + replace: true, + scope: { + progress: '=', + width: '@', + legend: '@' + }, + templateUrl: '/templates/components/progress_bar.html', + link: function(scope) { + // apply defaults + scope.progress = scope.progress || 0; + scope.width = scope.width || '100px'; + scope.legend = scope.legend || ''; + + scope.scaleLength = 100; + scope.progress = Math.round(scope.progress); + } + }; +}]); diff --git a/public/templates/components/progress_bar.html b/public/templates/components/progress_bar.html new file mode 100644 index 0000000000..444bf879f9 --- /dev/null +++ b/public/templates/components/progress_bar.html @@ -0,0 +1,8 @@ + + + + + + + +
From a8c3563b5e4cb96fd11cde1c7bdaced654c2e2c3 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 16:28:54 +0100 Subject: [PATCH 22/40] Render work package columns of type integer as progress bar --- .../directives/components/work-package-column-directive.js | 5 +++-- public/templates/components/work_package_column.html | 4 ++++ public/templates/work_packages/work_packages_table.html | 7 +++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js index 53b0add98d..284b682b88 100644 --- a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js @@ -7,7 +7,8 @@ angular.module('openproject.uiComponents') replace: true, scope: { workPackage: '=', - column: '=' + column: '=', + displayType: '=' }, templateUrl: '/templates/components/work_package_column.html', link: function(scope, element, attributes) { @@ -19,7 +20,7 @@ angular.module('openproject.uiComponents') function updateColumnData() { scope.displayText = WorkPackagesHelper.getFormattedColumnValue(scope.workPackage, scope.column) || defaultText; - scope.displayType = defaultType; + scope.displayType = scope.displayType || defaultType; // Example of how we can look to the provided meta data to format the column // This relies on the meta being sent from the server diff --git a/public/templates/components/work_package_column.html b/public/templates/components/work_package_column.html index 57c15f5e16..8269f3294f 100644 --- a/public/templates/components/work_package_column.html +++ b/public/templates/components/work_package_column.html @@ -2,5 +2,9 @@ {{ displayText }} + + {{ displayText }} diff --git a/public/templates/work_packages/work_packages_table.html b/public/templates/work_packages/work_packages_table.html index 7d834dcefc..0956fa3581 100644 --- a/public/templates/work_packages/work_packages_table.html +++ b/public/templates/work_packages/work_packages_table.html @@ -108,8 +108,11 @@ {{row.object.id}} - - + + From d9ed3df59ea02b8ca13435597cdfdb6c0ce6a398 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 14 Mar 2014 17:13:23 +0100 Subject: [PATCH 23/40] Add legend to progress bar directive --- app/assets/stylesheets/default/main.css.erb | 1 + public/templates/components/progress_bar.html | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/default/main.css.erb b/app/assets/stylesheets/default/main.css.erb index 375feb6c1e..381be607bf 100644 --- a/app/assets/stylesheets/default/main.css.erb +++ b/app/assets/stylesheets/default/main.css.erb @@ -575,6 +575,7 @@ div.tooltip:hover span.tip, div.tooltip.hover span.tip { #content table.progress td.done { background: #DEF0DE none repeat scroll 0%; } #content table.progress td.open { background: #FFF none repeat scroll 0%; } p.pourcent {font-size: 80%;} +p.progress-bar-legend {font-size: 80%; float: left;} p.progress-info {clear: left; font-style: italic; font-size: 80%;} /***** Tabs *****/ diff --git a/public/templates/components/progress_bar.html b/public/templates/components/progress_bar.html index 444bf879f9..9a4d084f88 100644 --- a/public/templates/components/progress_bar.html +++ b/public/templates/components/progress_bar.html @@ -1,8 +1,11 @@ - - - - - - - -
+
+ + + + + + + +
+

{{legend}} Total progress

+
From 6f8026fdeab62066b081efa5c9f085c4f4340b34 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 09:07:08 +0100 Subject: [PATCH 24/40] Only display done ration as progress bar in work packages table --- .../components/work-package-column-directive.js | 4 +++- public/templates/components/work_package_column.html | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js index 284b682b88..ba844d2284 100644 --- a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js @@ -15,12 +15,14 @@ angular.module('openproject.uiComponents') var defaultText = ''; var defaultType = 'text'; + scope.displayType = scope.displayType || defaultType; + if (scope.column.name === 'done_ratio') scope.displayType = 'progress_bar'; + // Set text to be displayed scope.$watch('workPackage', updateColumnData, true); function updateColumnData() { scope.displayText = WorkPackagesHelper.getFormattedColumnValue(scope.workPackage, scope.column) || defaultText; - scope.displayType = scope.displayType || defaultType; // Example of how we can look to the provided meta data to format the column // This relies on the meta being sent from the server diff --git a/public/templates/components/work_package_column.html b/public/templates/components/work_package_column.html index 8269f3294f..9401a309ea 100644 --- a/public/templates/components/work_package_column.html +++ b/public/templates/components/work_package_column.html @@ -1,10 +1,12 @@ - - {{ displayText }} - - + {{ displayText }} + + + {{ displayText }} + From 461789191a5c0583df4cbd95148bdde547139655 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 11:35:37 +0100 Subject: [PATCH 25/40] Refactor some angular module dependencies, add services module --- .../components/work-package-column-directive.js | 2 +- .../angular/helpers/components/custom-field-helper.js | 2 +- .../angular/helpers/components/path-helper.js | 2 +- .../helpers/components/work-packages-helper.js | 2 +- app/assets/javascripts/angular/openproject-app.js | 11 ++++++----- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js index ba844d2284..c5b76fa7df 100644 --- a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/components/work-package-column-directive.js @@ -1,5 +1,5 @@ // TODO move to UI components -angular.module('openproject.uiComponents') +angular.module('openproject.workPackages.directives') .directive('workPackageColumn', ['PathHelper', 'WorkPackagesHelper', function(PathHelper, WorkPackagesHelper){ return { diff --git a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js index 8824717ebb..9204087697 100644 --- a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js +++ b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js @@ -1,4 +1,4 @@ -angular.module('openproject.uiComponents') +angular.module('openproject.helpers') .constant('CUSTOM_FIELD_PREFIX', 'cf_') .service('CustomFieldHelper', ['CUSTOM_FIELD_PREFIX', 'I18n', function(CUSTOM_FIELD_PREFIX, I18n) { diff --git a/app/assets/javascripts/angular/helpers/components/path-helper.js b/app/assets/javascripts/angular/helpers/components/path-helper.js index d5646abc72..3fc39e8cad 100644 --- a/app/assets/javascripts/angular/helpers/components/path-helper.js +++ b/app/assets/javascripts/angular/helpers/components/path-helper.js @@ -1,5 +1,5 @@ // TODO forward rails routes -angular.module('openproject.uiComponents') +angular.module('openproject.helpers') .service('PathHelper', [function() { PathHelper = { diff --git a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js index dd34ca7031..36a9679a00 100644 --- a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js +++ b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js @@ -1,4 +1,4 @@ -angular.module('openproject.uiComponents') +angular.module('openproject.workPackages.helpers') .factory('WorkPackagesHelper', ['dateFilter', function(dateFilter) { var WorkPackagesHelper = { diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index dc3a1c5c17..ed8d9f0584 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -1,21 +1,22 @@ // global angular.module('openproject.services', ['openproject.uiComponents']); +angular.module('openproject.helpers', ['openproject.services']); angular.module('openproject.models', []); // timelines angular.module('openproject.timelines', ['openproject.timelines.controllers', 'openproject.timelines.directives', 'openproject.uiComponents']); -angular.module('openproject.timelines.models', []); +angular.module('openproject.timelines.models', ['openproject.helpers']); angular.module('openproject.timelines.helpers', []); angular.module('openproject.timelines.controllers', ['openproject.timelines.models']); angular.module('openproject.timelines.services', ['openproject.timelines.models', 'openproject.timelines.helpers']); -angular.module('openproject.timelines.directives', ['openproject.timelines.models', 'openproject.timelines.services', 'openproject.uiComponents']); +angular.module('openproject.timelines.directives', ['openproject.timelines.models', 'openproject.timelines.services', 'openproject.uiComponents', 'openproject.helpers']); // work packages -angular.module('openproject.workPackages', ['openproject.workPackages.controllers', 'openproject.workPackages.filters', 'openproject.workPackages.directives']); -angular.module('openproject.workPackages.helpers', ['openproject.uiComponents']); +angular.module('openproject.workPackages', ['openproject.workPackages.controllers', 'openproject.workPackages.filters', 'openproject.workPackages.directives', 'openproject.uiComponents']); +angular.module('openproject.workPackages.helpers', ['openproject.helpers']); angular.module('openproject.workPackages.filters', ['openproject.workPackages.helpers']); angular.module('openproject.workPackages.controllers', ['openproject.models', 'openproject.workPackages.helpers', 'openproject.services']); -angular.module('openproject.workPackages.directives', ['openproject.uiComponents', 'openproject.services']); +angular.module('openproject.workPackages.directives', ['openproject.helpers', 'openproject.workPackages.helpers', 'openproject.services']); // main app var openprojectApp = angular.module('openproject', ['ui.select2', 'ui.date', 'openproject.uiComponents', 'openproject.timelines', 'openproject.workPackages', 'ngAnimate']); From 8a4b7bffb2941a519a47aeabf6f5e7f16c1694e8 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 11:37:25 +0100 Subject: [PATCH 26/40] Move work package column directive to module folder --- .../work-package-column-directive.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/assets/javascripts/angular/directives/{components => work_packages}/work-package-column-directive.js (100%) diff --git a/app/assets/javascripts/angular/directives/components/work-package-column-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js similarity index 100% rename from app/assets/javascripts/angular/directives/components/work-package-column-directive.js rename to app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js From f29ed3579dee74c2002244e1a326f4d8cee3083a Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 13:19:34 +0100 Subject: [PATCH 27/40] Move work package column directive template --- .../directives/work_packages/work-package-column-directive.js | 2 +- .../{components => work_packages}/work_package_column.html | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename public/templates/{components => work_packages}/work_package_column.html (100%) diff --git a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js index c5b76fa7df..919a442795 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js @@ -10,7 +10,7 @@ angular.module('openproject.workPackages.directives') column: '=', displayType: '=' }, - templateUrl: '/templates/components/work_package_column.html', + templateUrl: '/templates/work_packages/work_package_column.html', link: function(scope, element, attributes) { var defaultText = ''; var defaultType = 'text'; diff --git a/public/templates/components/work_package_column.html b/public/templates/work_packages/work_package_column.html similarity index 100% rename from public/templates/components/work_package_column.html rename to public/templates/work_packages/work_package_column.html From b9c1403e325797bc3eca9b811b0dbc2e5fbab8a9 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 13:21:43 +0100 Subject: [PATCH 28/40] Generalize custom field formatting for work package and timeline tables (WIP) TODO load user names for work package columns --- .../helpers/components/custom-field-helper.js | 7 +++++- .../components/work-packages-helper.js | 22 +++++-------------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js index 9204087697..0f38d7fe04 100644 --- a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js +++ b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js @@ -2,6 +2,7 @@ angular.module('openproject.helpers') .constant('CUSTOM_FIELD_PREFIX', 'cf_') .service('CustomFieldHelper', ['CUSTOM_FIELD_PREFIX', 'I18n', function(CUSTOM_FIELD_PREFIX, I18n) { + CustomFieldHelper = { isCustomFieldKey: function(key) { return key.substr(0, CUSTOM_FIELD_PREFIX.length) === CUSTOM_FIELD_PREFIX; @@ -23,9 +24,13 @@ angular.module('openproject.helpers') case 'bool': return CustomFieldHelper.booleanCustomFieldValue(value); case 'user': - if (users[value]) + if (users && users[value]) return users[value].name; break; + case 'int': + return parseInt(value, 10); + case 'float': + return parseFloat(value); default: return value; } diff --git a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js index 36a9679a00..df2b0fedeb 100644 --- a/app/assets/javascripts/angular/helpers/components/work-packages-helper.js +++ b/app/assets/javascripts/angular/helpers/components/work-packages-helper.js @@ -1,6 +1,6 @@ angular.module('openproject.workPackages.helpers') -.factory('WorkPackagesHelper', ['dateFilter', function(dateFilter) { +.factory('WorkPackagesHelper', ['dateFilter', 'CustomFieldHelper', function(dateFilter, CustomFieldHelper) { var WorkPackagesHelper = { getRowObjectContent: function(object, option) { var content = object[option]; @@ -33,19 +33,8 @@ angular.module('openproject.workPackages.helpers') return customValue.custom_field_id === customField.id; }).first(); - return WorkPackagesHelper.getCustomValue(customField, customValue); - }, - - getCustomValue: function(customField, customValue) { - if (!customValue) return ''; - - switch(customField.field_format) { - case 'int': - return parseInt(customValue.value, 10); - case 'float': - return parseFloat(customValue.value); - default: - return customValue.value; + if(customValue) { + return CustomFieldHelper.formatCustomFieldValue(customValue.value, customField.field_format); } }, @@ -53,12 +42,11 @@ angular.module('openproject.workPackages.helpers') var value; if (column.custom_field) { - value = WorkPackagesHelper.getRowObjectCustomValue(rowObject, column.custom_field); + return WorkPackagesHelper.getRowObjectCustomValue(rowObject, column.custom_field); } else { value = WorkPackagesHelper.getRowObjectContent(rowObject, column.name); + return WorkPackagesHelper.formatValue(value, column.meta_data.data_type); } - - return WorkPackagesHelper.formatValue(value, column.meta_data.data_type); }, formatValue: function(value, dataType) { From 2acbac2941c49c8940fece55792e0c38cdfe86df Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 18:53:12 +0100 Subject: [PATCH 29/40] Sketch loading of custom field user data with a user service --- .../work-package-column-directive.js | 35 +++++++++++---- .../helpers/components/custom-field-helper.js | 6 ++- .../helpers/components/function-decorators.js | 18 ++++++++ .../angular/helpers/components/path-helper.js | 7 ++- .../javascripts/angular/openproject-app.js | 2 +- .../angular/services/user-service.js | 43 +++++++++++++++++++ 6 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 app/assets/javascripts/angular/helpers/components/function-decorators.js create mode 100644 app/assets/javascripts/angular/services/user-service.js diff --git a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js index 919a442795..a635624a5d 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js @@ -1,7 +1,7 @@ // TODO move to UI components angular.module('openproject.workPackages.directives') -.directive('workPackageColumn', ['PathHelper', 'WorkPackagesHelper', function(PathHelper, WorkPackagesHelper){ +.directive('workPackageColumn', ['PathHelper', 'WorkPackagesHelper', 'UserService', function(PathHelper, WorkPackagesHelper, UserService){ return { restrict: 'EA', replace: true, @@ -12,17 +12,21 @@ angular.module('openproject.workPackages.directives') }, templateUrl: '/templates/work_packages/work_package_column.html', link: function(scope, element, attributes) { - var defaultText = ''; - var defaultType = 'text'; + scope.displayType = scope.displayType || 'text'; - scope.displayType = scope.displayType || defaultType; - if (scope.column.name === 'done_ratio') scope.displayType = 'progress_bar'; + // custom display types + if (scope.column.name === 'done_ratio') { + scope.displayType = 'progress_bar'; + } // Set text to be displayed - scope.$watch('workPackage', updateColumnData, true); + scope.$watch('workPackage', setColumnData, true); + + function setColumnData() { + // retrieve column value from work package + scope.displayText = WorkPackagesHelper.getFormattedColumnValue(scope.workPackage, scope.column) || ''; - function updateColumnData() { - scope.displayText = WorkPackagesHelper.getFormattedColumnValue(scope.workPackage, scope.column) || defaultText; + if (scope.column.meta_data.data_type === 'user') loadUserName(); // Example of how we can look to the provided meta data to format the column // This relies on the meta being sent from the server @@ -30,7 +34,22 @@ angular.module('openproject.workPackages.directives') scope.displayType = 'link'; scope.url = getLinkFor(scope.column.meta_data.link); } + } + + function loadUserName() { + if (scope.user) return; + var userId = scope.displayText; + + if(userId) { + scope.user = UserService.registerUserId(userId); + + scope.$watch('user', function(user) { + // triggered when user data is loaded + // TODO replace watcher as soon as data is loaded via a promise chain + scope.displayText = user.name; + }, true); + } } function getLinkFor(link_meta){ diff --git a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js index 0f38d7fe04..ed4c6fbb45 100644 --- a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js +++ b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js @@ -24,8 +24,12 @@ angular.module('openproject.helpers') case 'bool': return CustomFieldHelper.booleanCustomFieldValue(value); case 'user': - if (users && users[value]) + if (users && users[value]) { return users[value].name; + } else { + // return user id + return value; + } break; case 'int': return parseInt(value, 10); diff --git a/app/assets/javascripts/angular/helpers/components/function-decorators.js b/app/assets/javascripts/angular/helpers/components/function-decorators.js new file mode 100644 index 0000000000..584c828624 --- /dev/null +++ b/app/assets/javascripts/angular/helpers/components/function-decorators.js @@ -0,0 +1,18 @@ +// TODO move to UI components +angular.module('openproject.helpers') + +.service('FunctionDecorators', ['$timeout', function($timeout) { + var currentRun; + + return { + withDelay: function(delay, callback, params) { + $timeout.cancel(currentRun); + + currentRun = $timeout(function() { + return callback.apply(this, params); + }, delay); + + return currentRun; + } + }; +}]); diff --git a/app/assets/javascripts/angular/helpers/components/path-helper.js b/app/assets/javascripts/angular/helpers/components/path-helper.js index 3fc39e8cad..57abcbedec 100644 --- a/app/assets/javascripts/angular/helpers/components/path-helper.js +++ b/app/assets/javascripts/angular/helpers/components/path-helper.js @@ -3,6 +3,8 @@ angular.module('openproject.helpers') .service('PathHelper', [function() { PathHelper = { + apiPrefix: '/api/v2', + projectPath: function(projectIdentifier) { return '/projects/' + projectIdentifier; }, @@ -15,8 +17,11 @@ angular.module('openproject.helpers') projectWorkPackagesPath: function(projectIdentifier) { return PathHelper.projectPath(projectIdentifier) + PathHelper.workPackagesPath(); }, + usersPath: function() { + return '/users'; + }, userPath: function(id) { - return '/users/' + id; + return PathHelper.usersPath() + id; }, workPackagesColumnDataPath: function() { return PathHelper.workPackagesPath() + '/column_data'; diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index ed8d9f0584..a6e24ebde5 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -1,5 +1,5 @@ // global -angular.module('openproject.services', ['openproject.uiComponents']); +angular.module('openproject.services', ['openproject.uiComponents', 'openproject.helpers']); angular.module('openproject.helpers', ['openproject.services']); angular.module('openproject.models', []); diff --git a/app/assets/javascripts/angular/services/user-service.js b/app/assets/javascripts/angular/services/user-service.js new file mode 100644 index 0000000000..3dcc9e1a9e --- /dev/null +++ b/app/assets/javascripts/angular/services/user-service.js @@ -0,0 +1,43 @@ +angular.module('openproject.services') + +.service('UserService', ['$http', 'PathHelper', 'FunctionDecorators', function($http, PathHelper, FunctionDecorators) { + var registeredUserIds = [], cachedUsers = {}; + + UserService = { + registerUserId: function(id) { + var user = cachedUsers[id]; + if (user) return user; + + registeredUserIds.push(id); + cachedUsers[id] = { name: '', firstname: '', lastname: '' }; // create an empty object and fill its values on load + + FunctionDecorators.withDelay(10, UserService.loadRegisteredUsers); + + return cachedUsers[id]; + }, + + loadRegisteredUsers: function() { + if (registeredUserIds.length > 0) { + return $http.get(PathHelper.apiPrefix + PathHelper.usersPath(), { + params: { 'ids[]': registeredUserIds } + }).then(function(response){ + UserService.storeUsers(response.data.users); + return cachedUsers; + }); + } + }, + + storeUsers: function(users) { + // writes user data to object stubs providing a mechanism for wiring up user data to the scope + angular.forEach(users, function(user) { + var cachedUser = cachedUsers[user.id]; + + cachedUser.firstname = user.firstname; + cachedUser.lastname = user.lastname; + cachedUser.name = user.name; + }); + } + }; + + return UserService; +}]); From e4263ca718fa3c714152d5ccd45ae1e19ab7fc89 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 18:56:08 +0100 Subject: [PATCH 30/40] Dry up usage of withDelay function wrapper --- .../work_packages/query-filter-directive.js | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/query-filter-directive.js b/app/assets/javascripts/angular/directives/work_packages/query-filter-directive.js index e565f78e1b..811afe98ed 100644 --- a/app/assets/javascripts/angular/directives/work_packages/query-filter-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/query-filter-directive.js @@ -1,6 +1,6 @@ angular.module('openproject.workPackages.directives') -.directive('queryFilter', ['WorkPackagesTableHelper', 'WorkPackageService', '$timeout', function(WorkPackagesTableHelper, WorkPackageService, $timeout) { +.directive('queryFilter', ['WorkPackagesTableHelper', 'WorkPackageService', 'FunctionDecorators', function(WorkPackagesTableHelper, WorkPackageService, FunctionDecorators) { return { restrict: 'A', @@ -24,23 +24,9 @@ angular.module('openproject.workPackages.directives') } }, true); - - var currentRun; - // TODO move to some application helper - function withDelay(delay, callback, params){ - $timeout.cancel(currentRun); - - currentRun = $timeout(function() { - return callback.apply(this, params); - }, delay); - - return currentRun; - } - function applyFiltersWithDelay() { - return withDelay(800, scope.updateResults); + return FunctionDecorators.withDelay(800, scope.updateResults); } - } }; }]); From 451431eb4fb4ae3da281bcab1bbb27b89f09750c Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 17 Mar 2014 18:59:52 +0100 Subject: [PATCH 31/40] Move svg helper to angular helpers module --- app/assets/javascripts/angular/helpers/svg-helper.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/angular/helpers/svg-helper.js b/app/assets/javascripts/angular/helpers/svg-helper.js index 271f93cb6f..ebb5b224ac 100644 --- a/app/assets/javascripts/angular/helpers/svg-helper.js +++ b/app/assets/javascripts/angular/helpers/svg-helper.js @@ -37,7 +37,9 @@ // │ OpenProject timelines module. │ // ╰───────────────────────────────────────────────────────────────╯ -openprojectApp.factory('SvgHelper', [function() { +angular.module('openproject.helpers') + +.factory('SvgHelper', [function() { var SvgHelper = function(node) { this.root = this.provideNode('svg').attr({ From 95567e2e1d5c0340bf65f8d75e1b0e43f1f6749c Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 18 Mar 2014 10:39:41 +0100 Subject: [PATCH 32/40] Fix non-assignable expression issue --- .../directives/work_packages/work-package-column-directive.js | 2 +- .../angular/helpers/components/custom-field-helper.js | 1 + public/templates/work_packages/work_packages_table.html | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js index a635624a5d..d3692aacc7 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js @@ -8,7 +8,7 @@ angular.module('openproject.workPackages.directives') scope: { workPackage: '=', column: '=', - displayType: '=' + displayType: '@' }, templateUrl: '/templates/work_packages/work_package_column.html', link: function(scope, element, attributes) { diff --git a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js index ed4c6fbb45..bff12a84f4 100644 --- a/app/assets/javascripts/angular/helpers/components/custom-field-helper.js +++ b/app/assets/javascripts/angular/helpers/components/custom-field-helper.js @@ -25,6 +25,7 @@ angular.module('openproject.helpers') return CustomFieldHelper.booleanCustomFieldValue(value); case 'user': if (users && users[value]) { + // try to look up users return users[value].name; } else { // return user id diff --git a/public/templates/work_packages/work_packages_table.html b/public/templates/work_packages/work_packages_table.html index 0956fa3581..0447037e84 100644 --- a/public/templates/work_packages/work_packages_table.html +++ b/public/templates/work_packages/work_packages_table.html @@ -112,7 +112,7 @@ + display-type="{{column.meta_data.data_type}}"/> From 8c038e063dda391322cebe1cb2c3ee28cd60cf1f Mon Sep 17 00:00:00 2001 From: Ion Biziiac Date: Wed, 19 Mar 2014 14:52:21 +0200 Subject: [PATCH 33/40] Fixes referencing work packages in news#show --- app/views/news/show.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/news/show.html.erb b/app/views/news/show.html.erb index 117dd0a7ab..6a1c1790bd 100644 --- a/app/views/news/show.html.erb +++ b/app/views/news/show.html.erb @@ -64,7 +64,7 @@ See doc/COPYRIGHT.rdoc for more details.

<% unless @news.summary.blank? %><%=h @news.summary %>
<% end %> <%= authoring @news.created_on, @news.author %>

-<%= textilizable(@news.description) %> +<%= textilizable(@news.description, :object => @news) %>

@@ -82,7 +82,7 @@ See doc/COPYRIGHT.rdoc for more details. :alt => l(:button_delete) %>

<%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %>

- <%= textilizable(comment.comments) %> + <%= textilizable(comment.comments, :object => comment) %> <% end %> From c22377d812b310847afaf7b577d3fb6068475ab2 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Wed, 19 Mar 2014 13:55:27 +0100 Subject: [PATCH 34/40] Simplify watcher in work package column directive --- .../work_packages/work-package-column-directive.js | 8 +++----- app/assets/javascripts/angular/services/user-service.js | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js index d3692aacc7..560fe10acb 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-package-column-directive.js @@ -37,18 +37,16 @@ angular.module('openproject.workPackages.directives') } function loadUserName() { - if (scope.user) return; - var userId = scope.displayText; if(userId) { scope.user = UserService.registerUserId(userId); - scope.$watch('user', function(user) { + scope.$watch('user.name', function(userName) { // triggered when user data is loaded // TODO replace watcher as soon as data is loaded via a promise chain - scope.displayText = user.name; - }, true); + scope.displayText = userName; + }); } } diff --git a/app/assets/javascripts/angular/services/user-service.js b/app/assets/javascripts/angular/services/user-service.js index 3dcc9e1a9e..e0fba4cdb7 100644 --- a/app/assets/javascripts/angular/services/user-service.js +++ b/app/assets/javascripts/angular/services/user-service.js @@ -11,7 +11,8 @@ angular.module('openproject.services') registeredUserIds.push(id); cachedUsers[id] = { name: '', firstname: '', lastname: '' }; // create an empty object and fill its values on load - FunctionDecorators.withDelay(10, UserService.loadRegisteredUsers); + FunctionDecorators.withDelay(10, UserService.loadRegisteredUsers); // HACK + // TODO hook into a given promise chain to post-load user data, or if ngView is used trigger load on $viewContentLoaded return cachedUsers[id]; }, From 9bbd35901c89f1868df0a670fdcfaa6ac76b94fa Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Wed, 19 Mar 2014 15:42:54 +0100 Subject: [PATCH 35/40] Fix scope setup of sort header directive Formerly sortable was read as a string and "false" evaluated to true. Also we can directly configure the scope to set up necessary variables. --- .../timelines/timeline-column-name-directive.js | 1 - .../directives/work_packages/sort-header-directive.js | 9 ++++----- .../templates/work_packages/work_packages_table.html | 11 +++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/angular/directives/timelines/timeline-column-name-directive.js b/app/assets/javascripts/angular/directives/timelines/timeline-column-name-directive.js index de86e6d57d..4f7cfc9dcb 100644 --- a/app/assets/javascripts/angular/directives/timelines/timeline-column-name-directive.js +++ b/app/assets/javascripts/angular/directives/timelines/timeline-column-name-directive.js @@ -19,7 +19,6 @@ angular.module('openproject.timelines.directives') } else { element.html(I18n.t(scope.localePrefix + '.' + scope.columnName)); } - } }; }]); diff --git a/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js b/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js index c7ecaeb8ca..f7b774f4fb 100644 --- a/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js @@ -7,7 +7,9 @@ angular.module('openproject.workPackages.directives') templateUrl: '/templates/work_packages/sort_header.html', scope: { query: '=', - column: '=', + headerName: '=', + headerTitle: '=', + sortable: '=', updateResults: '&' }, link: function(scope, element, attributes) { @@ -32,11 +34,8 @@ angular.module('openproject.workPackages.directives') } else { scope.fullTitle = (I18n.t('js.label_sort_by') + ' \"' + scope.headerTitle + '\"'); } - } + }; - scope.headerName = attributes['headerName']; - scope.headerTitle = attributes['headerTitle']; - scope.sortable = attributes['sortable']; scope.currentSortDirection = scope.query.sortation.getDisplayedSortDirectionOfHeader(scope.headerName); scope.setFullTitle(); } diff --git a/public/templates/work_packages/work_packages_table.html b/public/templates/work_packages/work_packages_table.html index 0447037e84..e36d6f1551 100644 --- a/public/templates/work_packages/work_packages_table.html +++ b/public/templates/work_packages/work_packages_table.html @@ -13,18 +13,17 @@ From 18687104e5b004f17a8f064113a47f33f1b66805 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Wed, 19 Mar 2014 16:04:26 +0100 Subject: [PATCH 36/40] Just set up one watcher on work package table sortation --- .../directives/work_packages/sort-header-directive.js | 6 ------ .../work_packages/work-packages-table-directive.js | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js b/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js index f7b774f4fb..f7a9cd566e 100644 --- a/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/sort-header-directive.js @@ -13,12 +13,6 @@ angular.module('openproject.workPackages.directives') updateResults: '&' }, link: function(scope, element, attributes) { - scope.$watch('query.sortation', function(oldValue, newValue) { - if (newValue !== oldValue) { - scope.updateResults(); - } - }); - scope.performSort = function(){ targetSortation = scope.query.sortation.getTargetSortationOfHeader(scope.headerName); scope.query.setSortation(targetSortation); diff --git a/app/assets/javascripts/angular/directives/work_packages/work-packages-table-directive.js b/app/assets/javascripts/angular/directives/work_packages/work-packages-table-directive.js index 9724768676..e596c3a130 100644 --- a/app/assets/javascripts/angular/directives/work_packages/work-packages-table-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/work-packages-table-directive.js @@ -32,6 +32,11 @@ angular.module('openproject.workPackages.directives') }); }; + scope.$watch('query.sortation.sortElements', function(oldValue, newValue) { + if (newValue !== oldValue) { + scope.updateResults(); + } + }); } }; }]); From 97a247a7ef02adc4fafd4d62824612ee9e351571 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Wed, 19 Mar 2014 16:16:31 +0100 Subject: [PATCH 37/40] Update Copyright headers in new JS/Angular sources Missed in bed4636 and previous merge commits. Signed-off-by: Alex Coles --- .../javascripts/angular/helpers/filter-query-string-builder.js | 2 +- .../javascripts/angular/models/timelines/mixins/constants.js | 2 +- app/assets/javascripts/angular/models/timelines/mixins/ui.js | 2 +- app/assets/javascripts/angular/models/timelines/project_type.js | 2 +- .../javascripts/angular/services/timeline-loader-service.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/angular/helpers/filter-query-string-builder.js b/app/assets/javascripts/angular/helpers/filter-query-string-builder.js index 2bb17d0e7d..60db0a0faa 100644 --- a/app/assets/javascripts/angular/helpers/filter-query-string-builder.js +++ b/app/assets/javascripts/angular/helpers/filter-query-string-builder.js @@ -1,6 +1,6 @@ //-- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +// 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. diff --git a/app/assets/javascripts/angular/models/timelines/mixins/constants.js b/app/assets/javascripts/angular/models/timelines/mixins/constants.js index f7e044d3c4..ac4682f1a5 100644 --- a/app/assets/javascripts/angular/models/timelines/mixins/constants.js +++ b/app/assets/javascripts/angular/models/timelines/mixins/constants.js @@ -1,6 +1,6 @@ // //-- copyright // // OpenProject is a project management system. -// // Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +// // 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. diff --git a/app/assets/javascripts/angular/models/timelines/mixins/ui.js b/app/assets/javascripts/angular/models/timelines/mixins/ui.js index 2365918ece..f7e91ae8a9 100644 --- a/app/assets/javascripts/angular/models/timelines/mixins/ui.js +++ b/app/assets/javascripts/angular/models/timelines/mixins/ui.js @@ -1,6 +1,6 @@ //-- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +// 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. diff --git a/app/assets/javascripts/angular/models/timelines/project_type.js b/app/assets/javascripts/angular/models/timelines/project_type.js index 75d2094194..3653c7ec74 100644 --- a/app/assets/javascripts/angular/models/timelines/project_type.js +++ b/app/assets/javascripts/angular/models/timelines/project_type.js @@ -1,6 +1,6 @@ //-- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +// 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. diff --git a/app/assets/javascripts/angular/services/timeline-loader-service.js b/app/assets/javascripts/angular/services/timeline-loader-service.js index 4037c7a127..27e2700ef4 100644 --- a/app/assets/javascripts/angular/services/timeline-loader-service.js +++ b/app/assets/javascripts/angular/services/timeline-loader-service.js @@ -1,6 +1,6 @@ //-- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +// 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. From e85f78e2d994de60229664d8310a8a91b761dbd0 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Wed, 19 Mar 2014 16:31:16 +0100 Subject: [PATCH 38/40] Update Copyright headers in new/moved features Signed-off-by: Alex Coles --- .../planning_element_management.feature.disabled | 2 +- features/search/pagination.feature | 2 +- features/work_packages/index_move_columns.feature | 2 +- features/work_packages/index_sums.feature | 2 +- features/work_packages/work_packages_new.feature | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/planning_elements/planning_element_management.feature.disabled b/features/planning_elements/planning_element_management.feature.disabled index 3b33943f9e..94cae35636 100644 --- a/features/planning_elements/planning_element_management.feature.disabled +++ b/features/planning_elements/planning_element_management.feature.disabled @@ -1,7 +1,7 @@ #-- copyright # OpenProject is a project management system. # -# Copyright (C) 2012-2013 the OpenProject Team +# Copyright (C) 2012-2014 the OpenProject Team # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License version 3. diff --git a/features/search/pagination.feature b/features/search/pagination.feature index 44af42bb00..2bb4ceaa31 100644 --- a/features/search/pagination.feature +++ b/features/search/pagination.feature @@ -1,6 +1,6 @@ #-- copyright # OpenProject is a project management system. -# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +# 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. diff --git a/features/work_packages/index_move_columns.feature b/features/work_packages/index_move_columns.feature index 3972ca392e..bf4ff65b0b 100644 --- a/features/work_packages/index_move_columns.feature +++ b/features/work_packages/index_move_columns.feature @@ -1,6 +1,6 @@ #-- copyright # OpenProject is a project management system. -# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +# 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. diff --git a/features/work_packages/index_sums.feature b/features/work_packages/index_sums.feature index effe20b1b3..f0f19f089f 100644 --- a/features/work_packages/index_sums.feature +++ b/features/work_packages/index_sums.feature @@ -1,6 +1,6 @@ #-- copyright # OpenProject is a project management system. -# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +# 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. diff --git a/features/work_packages/work_packages_new.feature b/features/work_packages/work_packages_new.feature index 4c51e6c6e6..648a572392 100644 --- a/features/work_packages/work_packages_new.feature +++ b/features/work_packages/work_packages_new.feature @@ -1,6 +1,6 @@ #-- copyright # OpenProject is a project management system. -# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +# 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. From 22cc1d359aa338cc3544cc11b55dac866960abcd Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Wed, 19 Mar 2014 18:12:43 +0100 Subject: [PATCH 39/40] Fix sums for integer columns --- app/controllers/work_packages_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index ee67a46182..bdf2e7e7c3 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -322,7 +322,7 @@ class WorkPackagesController < ApplicationController def column_is_numeric?(column_name) # TODO RS: We want to leave out ids even though they are numeric - [:integer, :float].include? column_type(column_name) + [:int, :float].include? column_type(column_name) end def column_type(column_name) From 96dc511b40a6a8748af609655a6bc567aabbdfe0 Mon Sep 17 00:00:00 2001 From: Hagen Schink Date: Thu, 20 Mar 2014 07:55:45 +0100 Subject: [PATCH 40/40] Adds changelog entry --- doc/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 21556e9f01..9b9b2df972 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -35,6 +35,7 @@ See doc/COPYRIGHT.rdoc for more details. * `#3267` Fix: Link in Breadcrumbs links to global work packages * `#3395` Fix: After error message values are gone during creation of message * `#3531` Fix: Type 'None' cannot be configured via admin settings +* `#4040` Fix: Referencing work packages with ### in news, forums and meetings does not work * `#4087` Ignore type list flash when activating flash messages * `#4097` Fix accesskeys * `#4118` Fix: Add missing labels