enable child work package creation in split view

pull/3997/head
Jens Ulferts 9 years ago
parent 4e2f3a1b7a
commit c7f780e797
  1. 2
      frontend/app/components/work-packages/directives/wp-create-form/wp-create-form.directive.html
  2. 2
      frontend/app/routing.js
  3. 12
      frontend/app/work_packages/view_models/children-relations-handler.js
  4. 1
      frontend/app/work_packages/view_models/index.js
  5. 31
      spec/features/work_packages/create_child_spec.rb
  6. 34
      spec/support/pages/abstract_work_package.rb
  7. 67
      spec/support/pages/abstract_work_package_create.rb
  8. 73
      spec/support/pages/full_work_package.rb
  9. 41
      spec/support/pages/full_work_package_create.rb
  10. 7
      spec/support/pages/page.rb
  11. 16
      spec/support/pages/split_work_package.rb
  12. 34
      spec/support/pages/split_work_package_create.rb

@ -1,6 +1,6 @@
<div cg-busy="vm.loaderPromise" class="work-packages--details-content -create-mode">
<div ng-if="vm.workPackage">
<h2>{{ ::I18n.t('js.work_packages.create.header') }}</h2>
<h2>{{ vm.getHeading() }}</h2>
<div class="work-packages--create--title">
<work-package-field field-name="'subject'" tabindex="0"></work-package-field>

@ -185,7 +185,7 @@ angular.module('openproject')
}
})
.state('work-packages.list.new', {
url: '/create_new?type',
url: '/create_new?type&parent_id',
templateUrl: '/components/routes/partials/work-packages.list.new.html',
reloadOnSearch: false
})

@ -29,7 +29,8 @@
module.exports = function(
CommonRelationsHandler,
WorkPackageService,
ApiNotificationsService
ApiNotificationsService,
$state
) {
function ChildrenRelationsHandler(workPackage, children) {
var handler = new CommonRelationsHandler(workPackage, children, undefined);
@ -42,7 +43,14 @@ module.exports = function(
return !!this.workPackage.links.update;
};
handler.addRelation = function() {
window.location = this.workPackage.links.addChild.href;
var params = { parent_id: this.workPackage.props.id,
projectPath: this.workPackage.embedded.project.props.identifier };
if ($state.includes('work-packages.show')) {
$state.go('work-packages.new', params);
}
else {
$state.go('work-packages.list.new', params);
}
};
handler.getRelatedWorkPackage = function(workPackage, relation) { return relation.fetch(); };
handler.removeRelation = function(scope) {

@ -37,6 +37,7 @@ angular.module('openproject.viewModels')
'CommonRelationsHandler',
'WorkPackageService',
'ApiNotificationsService',
'$state',
require('./children-relations-handler')
])
.factory('ParentRelationsHandler', [

@ -105,8 +105,8 @@ RSpec.feature 'Work package create children', js: true, selenium: true do
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.expect_current_path
child_work_package_page.update_attributes Subject: 'Child work package'
@ -121,6 +121,35 @@ RSpec.feature 'Work package create children', js: true, selenium: true do
child_work_package_page = Pages::FullWorkPackage.new(child_work_package)
child_work_package_page.ensure_page_loaded
child_work_package_page.expect_subject
child_work_package_page.expect_current_path
child_work_package_page.expect_parent(original_work_package)
end
scenario 'on split screen page' do
original_work_package_page = Pages::SplitWorkPackage.new(original_work_package, project)
child_work_package_page = original_work_package_page.add_child
child_work_package_page.expect_heading
child_work_package_page.expect_current_path
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::SplitWorkPackage.new(child_work_package, project)
child_work_package_page.ensure_page_loaded
child_work_package_page.expect_subject
child_work_package_page.expect_current_path

@ -75,5 +75,39 @@ 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')
create_page(parent_work_package: work_package)
end
def visit_copy!
page = create_page(original_work_package: work_package)
page.visit!
page
end
private
def create_page(_args)
raise NotImplementedError
end
end
end

@ -0,0 +1,67 @@
#-- 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 'support/pages/page'
module Pages
class AbstractWorkPackageCreate < Page
attr_reader :original_work_package,
:parent_work_package
def initialize(original_work_package: nil, parent_work_package: nil)
# in case of copy, the original work package can be provided
@original_work_package = original_work_package
@parent_work_package = parent_work_package
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|
fill_in(label, with: value)
end
end
def expect_fully_loaded
expect(page).to have_field(I18n.t('js.work_packages.properties.subject'))
end
def save!
click_button I18n.t('js.button_save')
end
end
end

@ -30,75 +30,6 @@ require 'support/pages/page'
module Pages
class FullWorkPackage < Pages::AbstractWorkPackage
attr_reader :work_package
def initialize(work_package)
@work_package = work_package
end
def expect_subject
within(container) do
expect(page).to have_content(work_package.subject)
end
end
def ensure_page_loaded
expect(page).to have_selector('.work-package-details-activities-activity-contents .user',
text: work_package.journals.last.user.name)
end
def expect_attributes(attribute_expectations)
attribute_expectations.each do |label_name, value|
label = label_name.to_s
if label == 'Subject'
expect(page).to have_selector('.attribute-subject', text: value)
elsif label == 'Description'
expect(page).to have_selector('.attribute-description', text: value)
else
expect(page).to have_selector('.attributes-key-value--key', text: label)
dl_element = page.find('.attributes-key-value--key', text: label).parent
expect(dl_element).to have_selector('.attributes-key-value--value-container', text: value)
end
end
end
def expect_activity(user, number: nil)
container = '#work-package-activites-container'
container += " #activity-#{number}" if number
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(original_work_package: work_package)
page.visit!
page
end
private
@ -109,5 +40,9 @@ module Pages
def path(tab = 'activity')
work_package_path(work_package.id, tab)
end
def create_page(args)
Pages::FullWorkPackageCreate.new(args)
end
end
end

@ -29,41 +29,7 @@
require 'support/pages/page'
module Pages
class FullWorkPackageCreate < Page
attr_reader :original_work_package,
:parent_work_package
def initialize(original_work_package: nil, parent_work_package: nil)
# in case of copy, the original work package can be provided
@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|
fill_in(label, with: value)
end
end
def save!
click_button I18n.t('js.button_save')
end
class FullWorkPackageCreate < AbstractWorkPackageCreate
private
def container
@ -72,9 +38,10 @@ module Pages
def path
if original_work_package
work_package_path(work_package) + '/copy'
work_package_path(original_work_package) + '/copy'
elsif parent_work_package
new_project_work_packages_path(parent_work_package.project.identifier)
new_project_work_packages_path(parent_work_package.project.identifier,
parent_id: parent_work_package.id)
end
end
end

@ -75,8 +75,11 @@ module Pages
end
def expect_current_path
current_path = URI.parse(current_url).path
expect(current_path).to eql path
uri = URI.parse(current_url)
expected_path = uri.path
expected_path += '?' + uri.query if uri.query
expect(expected_path).to eql path
end
def path

@ -33,24 +33,17 @@ module Pages
attr_reader :project
def initialize(work_package, project = nil)
@work_package = work_package
super work_package
@project = project
end
def visit_copy!
page = SplitWorkPackageCreate.new(project || work_package.project, work_package)
page.visit!
page
end
private
def container
find('.work-packages--details')
end
def path(tab='overview')
def path(tab = 'overview')
state = "#{work_package.id}/#{tab}"
if project
@ -59,5 +52,10 @@ module Pages
details_work_packages_path(state)
end
end
def create_page(args)
args.merge!(project: project || work_package.project)
SplitWorkPackageCreate.new(args)
end
end
end

@ -29,38 +29,26 @@
require 'support/pages/page'
module Pages
class SplitWorkPackageCreate < Page
attr_reader :work_package,
:project
class SplitWorkPackageCreate < AbstractWorkPackageCreate
attr_reader :project
def initialize(project, work_package = nil)
# in case of copy, the original work package can be provided
@work_package = work_package
def initialize(project:, original_work_package: nil, parent_work_package: nil)
@project = project
end
def expect_fully_loaded
expect(page).to have_field(I18n.t('js.work_packages.properties.subject'))
end
def update_attributes(attribute_map)
# Only designed for text fields for now
attribute_map.each do |label, value|
fill_in(label, with: value)
end
end
def save!
click_button I18n.t('js.button_save')
super(original_work_package: original_work_package,
parent_work_package: parent_work_package)
end
private
def path
if work_package
project_work_packages_path(project) + "/details/#{work_package.id}/copy"
if original_work_package
project_work_packages_path(project) + "/details/#{original_work_package.id}/copy"
else
project_work_packages_path(project) + '/create_new'
path = project_work_packages_path(project) + '/create_new'
path += "?parent_id=#{parent_work_package.id}" if parent_work_package
path
end
end
end

Loading…
Cancel
Save