-
{{ ::I18n.t('js.work_packages.create.header') }}
+
{{ vm.getHeading() }}
diff --git a/frontend/app/components/work-packages/services/work-package.service.js b/frontend/app/components/work-packages/services/work-package.service.js
index 29715c6d82..925fcc2b1e 100644
--- a/frontend/app/components/work-packages/services/work-package.service.js
+++ b/frontend/app/components/work-packages/services/work-package.service.js
@@ -122,6 +122,17 @@ function WorkPackageService($http, PathHelper, WorkPackagesHelper, HALAPIResourc
return WorkPackageService.initializeWorkPackage(projectIdentifier, initialData);
},
+ initializeWorkPackageWithParent: function(parentWorkPackage) {
+ var projectIdentifier = parentWorkPackage.embedded.project.props.identifier;
+
+ var initialData = {
+ parentId: String(parentWorkPackage.props.id)
+ };
+
+ return WorkPackageService.initializeWorkPackage(projectIdentifier, initialData);
+ },
+
+
getWorkPackage: function(id) {
var path = PathHelper.apiV3WorkPackagePath(id),
resource = HALAPIResource.setup(path);
diff --git a/frontend/app/routing.js b/frontend/app/routing.js
index aa908112d5..6cfbc06951 100644
--- a/frontend/app/routing.js
+++ b/frontend/app/routing.js
@@ -83,7 +83,7 @@ angular.module('openproject')
})
.state('work-packages.new', {
- url: '/{projects}/{projectPath}/work_packages/new?type',
+ url: '/{projects}/{projectPath}/work_packages/new?type&parent_id',
templateUrl: '/components/routes/partials/work-packages.new.html',
controllerAs: 'vm',
reloadOnSearch: false
diff --git a/spec/factories/issue_priority_factory.rb b/spec/factories/issue_priority_factory.rb
index 9165c676d7..dd0fe09daa 100644
--- a/spec/factories/issue_priority_factory.rb
+++ b/spec/factories/issue_priority_factory.rb
@@ -30,4 +30,8 @@ FactoryGirl.define do
factory :issue_priority do
sequence(:name) { |n| "IssuePriority #{n}" }
end
+
+ factory :default_priority, parent: :issue_priority do
+ is_default true
+ end
end
diff --git a/spec/features/work_packages/create_child_spec.rb b/spec/features/work_packages/create_child_spec.rb
new file mode 100644
index 0000000000..45ff6de5f6
--- /dev/null
+++ b/spec/features/work_packages/create_child_spec.rb
@@ -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.
+#++
+
+require 'spec_helper'
+
+RSpec.feature 'Work package create children', js: true, selenium: true do
+ let(:user) do
+ FactoryGirl.create(:user,
+ member_in_project: project,
+ member_through_role: create_role)
+ end
+ let(:work_flow) do
+ FactoryGirl.create(:workflow,
+ role: create_role,
+ type_id: original_work_package.type_id,
+ old_status: original_work_package.status,
+ new_status: FactoryGirl.create(:status))
+ end
+
+ let(:create_role) do
+ FactoryGirl.create(:role,
+ permissions: [:view_work_packages,
+ :add_work_packages,
+ :edit_work_packages,
+ :manage_subtasks])
+ end
+ let(:project) { FactoryGirl.create(:project) }
+ let(:original_work_package) do
+ FactoryGirl.build(:work_package,
+ project: project,
+ assigned_to: assignee,
+ responsible: responsible,
+ fixed_version: version,
+ priority: default_priority,
+ author: author,
+ status: default_status)
+ end
+ let(:default_priority) do
+ FactoryGirl.build(:default_priority)
+ end
+ let(:default_status) do
+ FactoryGirl.build(:default_status)
+ end
+ let(:role) { FactoryGirl.build(:role, permissions: [:view_work_packages]) }
+ let(:assignee) do
+ FactoryGirl.build(:user,
+ firstname: 'An',
+ lastname: 'assignee',
+ member_in_project: project,
+ member_through_role: role)
+ end
+ let(:responsible) do
+ FactoryGirl.build(:user,
+ firstname: 'The',
+ lastname: 'responsible',
+ member_in_project: project,
+ member_through_role: role)
+ end
+ let(:author) do
+ FactoryGirl.build(:user,
+ firstname: 'The',
+ lastname: 'author',
+ member_in_project: project,
+ member_through_role: role)
+ end
+ let(:version) do
+ FactoryGirl.build(:version,
+ project: project)
+ end
+
+ before do
+ login_as(user)
+ allow(user.pref).to receive(:warn_on_leaving_unsaved?).and_return(false)
+ original_work_package.save!
+ work_flow.save!
+ end
+
+ scenario 'on fullscreen page' do
+ original_work_package_page = Pages::FullWorkPackage.new(original_work_package)
+
+ child_work_package_page = original_work_package_page.add_child
+
+ child_work_package_page.expect_current_path
+ child_work_package_page.expect_heading
+
+ child_work_package_page.update_attributes Subject: 'Child work package'
+
+ child_work_package_page.save!
+
+ expect(page).to have_selector('.notification-box--content',
+ text: I18n.t('js.notice_successful_create'))
+
+ child_work_package = WorkPackage.order(created_at: 'desc').first
+
+ expect(child_work_package).to_not eql original_work_package
+
+ child_work_package_page = Pages::FullWorkPackage.new(child_work_package)
+
+ child_work_package_page.expect_subject
+ child_work_package_page.expect_current_path
+
+ child_work_package_page.expect_parent(original_work_package)
+ end
+end
diff --git a/spec/support/pages/full_work_package.rb b/spec/support/pages/full_work_package.rb
index fe11dd195c..fc92eaeec9 100644
--- a/spec/support/pages/full_work_package.rb
+++ b/spec/support/pages/full_work_package.rb
@@ -72,8 +72,29 @@ module Pages
expect(page).to have_selector(container + ' .user', text: user.name)
end
+ def expect_parent(parent = nil)
+ parent ||= work_package.parent
+
+ expect(parent).to_not be_nil
+
+ visit_tab!('relations')
+
+ expect(page).to have_selector(".relation[title=#{I18n.t('js.relation_labels.parent')}] a",
+ text: "##{parent.id} #{parent.subject}")
+ end
+
+ def add_child
+ visit_tab!('relations')
+
+ page.find('.relation a', text: I18n.t('js.relation_labels.children')).click
+
+ click_button I18n.t('js.relation_buttons.add_child')
+
+ Pages::FullWorkPackageCreate.new(parent_work_package: work_package)
+ end
+
def visit_copy!
- page = FullWorkPackageCreate.new(work_package)
+ page = FullWorkPackageCreate.new(original_work_package: work_package)
page.visit!
page
@@ -85,7 +106,7 @@ module Pages
find('.work-packages--show-view')
end
- def path(tab='activity')
+ def path(tab = 'activity')
work_package_path(work_package.id, tab)
end
end
diff --git a/spec/support/pages/full_work_package_create.rb b/spec/support/pages/full_work_package_create.rb
index f62e641acb..a468b14a77 100644
--- a/spec/support/pages/full_work_package_create.rb
+++ b/spec/support/pages/full_work_package_create.rb
@@ -30,17 +30,29 @@ require 'support/pages/page'
module Pages
class FullWorkPackageCreate < Page
- attr_reader :work_package
+ attr_reader :original_work_package,
+ :parent_work_package
- def initialize(work_package = nil)
+ def initialize(original_work_package: nil, parent_work_package: nil)
# in case of copy, the original work package can be provided
- @work_package = work_package
+ @original_work_package = original_work_package
+ @parent_work_package = parent_work_package
end
def expect_fully_loaded
expect(page).to have_field(I18n.t('js.work_packages.properties.subject'))
end
+ def expect_heading
+ if parent_work_package
+ expect(page).to have_selector('h2', text: I18n.t('js.work_packages.create.header_with_parent',
+ type: parent_work_package.type,
+ id: parent_work_package.id))
+ else
+ expect(page).to have_selector('h2', text: I18n.t('js.work_packages.create.header'))
+ end
+ end
+
def update_attributes(attribute_map)
# Only designed for text fields for now
attribute_map.each do |label, value|
@@ -59,7 +71,11 @@ module Pages
end
def path
- work_package_path(work_package) + '/copy' if work_package
+ if original_work_package
+ work_package_path(work_package) + '/copy'
+ elsif parent_work_package
+ new_project_work_packages_path(parent_work_package.project.identifier)
+ end
end
end
end