mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Merge workflow copy modes into one unified form. wp/72383
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# -- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
# ++
|
||||
|
||||
module Workflows::PageHeaders
|
||||
class CopyComponent < BaseComponent
|
||||
options :title
|
||||
|
||||
def page_breadcrumb
|
||||
{ href: workflows_path, text: t(:label_workflow_plural) }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -42,33 +42,19 @@ module Workflows::PageHeaders
|
||||
type.name
|
||||
end
|
||||
|
||||
def add_action_buttons(header) # rubocop:disable Metrics/AbcSize
|
||||
def add_action_buttons(header)
|
||||
header.with_action_button(
|
||||
data: { controller: "async-dialog" },
|
||||
tag: :a,
|
||||
mobile_icon: :copy,
|
||||
mobile_label: t(:label_copy_workflow_from_type),
|
||||
mobile_label: t(:button_copy),
|
||||
size: :medium,
|
||||
href: new_workflow_copy_from_type_path(type),
|
||||
aria: { label: helpers.t(:label_copy_workflow_from_type) },
|
||||
title: helpers.t(:label_copy_workflow_from_type)
|
||||
href: new_workflow_copy_path(type, source_role_id: role&.id),
|
||||
aria: { label: helpers.t(:button_copy) },
|
||||
title: helpers.t(:button_copy)
|
||||
) do |button|
|
||||
button.with_leading_visual_icon(icon: :copy)
|
||||
t(:label_copy_workflow_from_type)
|
||||
end
|
||||
|
||||
header.with_action_button(
|
||||
data: { controller: "async-dialog" },
|
||||
tag: :a,
|
||||
mobile_icon: :copy,
|
||||
mobile_label: t(:label_copy_workflow_from_role),
|
||||
size: :medium,
|
||||
href: new_workflow_copy_from_role_path(type, source_role_id: role&.id),
|
||||
aria: { label: helpers.t(:label_copy_workflow_from_role) },
|
||||
title: helpers.t(:label_copy_workflow_from_role)
|
||||
) do |button|
|
||||
button.with_leading_visual_icon(icon: :copy)
|
||||
t(:label_copy_workflow_from_role)
|
||||
t(:button_copy)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -54,16 +54,10 @@ See COPYRIGHT and LICENSE files for more details.
|
||||
item.with_leading_visual_icon(icon: :pencil)
|
||||
end
|
||||
menu.with_divider
|
||||
menu.with_item(label:t("label_copy_workflow_from_type"),
|
||||
menu.with_item(label: t("button_copy"),
|
||||
content_arguments: { data: { controller: "async-dialog" }},
|
||||
tag: :a,
|
||||
href: new_workflow_copy_from_type_path(type)) do |item|
|
||||
item.with_leading_visual_icon(icon: :copy)
|
||||
end
|
||||
menu.with_item(label:t("label_copy_workflow_from_role"),
|
||||
content_arguments: { data: { controller: "async-dialog" }},
|
||||
tag: :a,
|
||||
href: new_workflow_copy_from_role_path(type)) do |item|
|
||||
href: new_workflow_copy_path(type)) do |item|
|
||||
item.with_leading_visual_icon(icon: :copy)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,10 +37,7 @@ class Workflows::Copies::FromRolesController < ApplicationController
|
||||
|
||||
before_action :set_source_type
|
||||
before_action :set_source_role
|
||||
before_action :set_all_roles
|
||||
before_action :set_target_roles, only: %i[create]
|
||||
|
||||
def new; end
|
||||
before_action :set_target_roles
|
||||
|
||||
def create
|
||||
if @source_type.nil? || @source_role.nil?
|
||||
@@ -74,10 +71,6 @@ class Workflows::Copies::FromRolesController < ApplicationController
|
||||
@source_role = eligible_roles.find_by(id: params[:source_role_id])
|
||||
end
|
||||
|
||||
def set_all_roles
|
||||
@all_roles = eligible_roles
|
||||
end
|
||||
|
||||
def set_target_roles
|
||||
@target_roles = eligible_roles.find_by(id: params[:target_role_ids])
|
||||
end
|
||||
|
||||
@@ -36,10 +36,7 @@ class Workflows::Copies::FromTypesController < ApplicationController
|
||||
before_action :require_admin
|
||||
|
||||
before_action :set_source_type
|
||||
before_action :set_other_types
|
||||
before_action :set_target_type, only: %i[create]
|
||||
|
||||
def new; end
|
||||
before_action :set_target_type
|
||||
|
||||
def create
|
||||
if @source_type.nil?
|
||||
@@ -71,10 +68,6 @@ class Workflows::Copies::FromTypesController < ApplicationController
|
||||
@source_type = ::Type.find(params[:workflow_type_id])
|
||||
end
|
||||
|
||||
def set_other_types
|
||||
@other_types = ::Type.where.not(id: @source_type.id).order(:position)
|
||||
end
|
||||
|
||||
def set_target_type
|
||||
@target_type = ::Type.find(params[:target_type_id])
|
||||
end
|
||||
|
||||
+30
-15
@@ -27,25 +27,40 @@
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
#
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Workflows::Copies::FromTypeForm, type: :forms do
|
||||
include_context "with rendered form"
|
||||
class Workflows::CopiesController < ApplicationController
|
||||
include OpTurbo::ComponentStream
|
||||
|
||||
let(:model) { false }
|
||||
let(:params) { { source_type:, other_types: } }
|
||||
let(:source_type) { create(:type) }
|
||||
let(:other_types) { create_list(:type, 4) }
|
||||
layout "admin"
|
||||
|
||||
it "renders the Target type select list" do
|
||||
expect(page).to have_select "Target type", required: true do |select|
|
||||
options_text = select.all("option").map(&:text)
|
||||
expect(options_text).to match_array(other_types.map(&:name))
|
||||
end
|
||||
before_action :require_admin
|
||||
|
||||
before_action :set_source_type
|
||||
before_action :set_source_role
|
||||
before_action :set_other_types
|
||||
before_action :set_all_roles
|
||||
|
||||
def new; end
|
||||
|
||||
private
|
||||
|
||||
def set_source_type
|
||||
@source_type = ::Type.find(params[:workflow_type_id])
|
||||
end
|
||||
|
||||
it "renders submit button" do
|
||||
expect(page).to have_button "Copy", class: "Button--primary"
|
||||
def set_source_role
|
||||
@source_role = eligible_roles.find_by(id: params[:source_role_id])
|
||||
end
|
||||
|
||||
def set_other_types
|
||||
@other_types = ::Type.where.not(id: @source_type.id).order(:position)
|
||||
end
|
||||
|
||||
def set_all_roles
|
||||
@all_roles = eligible_roles
|
||||
end
|
||||
|
||||
def eligible_roles
|
||||
@eligible_roles ||= Workflow.eligible_roles
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
class Workflows::Copies::Form < ApplicationForm
|
||||
def initialize(source_type:, source_role:, other_types:, all_roles:, append_to: nil)
|
||||
super()
|
||||
@source_type = source_type
|
||||
@source_role = source_role
|
||||
@other_types = other_types
|
||||
@all_roles = all_roles
|
||||
@append_to = append_to
|
||||
end
|
||||
|
||||
form do |copy|
|
||||
another_type_at_first = @source_role.nil?
|
||||
copy.advanced_radio_button_group(name: :mode) do |radio_group|
|
||||
radio_group.radio_button(
|
||||
value: "from_type",
|
||||
checked: another_type_at_first,
|
||||
label: helpers.t("workflows.copies.form.mode.from_type.label"),
|
||||
caption: helpers.t("workflows.copies.form.mode.from_type.caption"),
|
||||
data: {
|
||||
target_name: "mode",
|
||||
"show-when-value-selected-target": "cause"
|
||||
}
|
||||
)
|
||||
radio_group.radio_button(
|
||||
value: "from_role",
|
||||
checked: !another_type_at_first,
|
||||
label: helpers.t("workflows.copies.form.mode.from_role.label"),
|
||||
caption: helpers.t("workflows.copies.form.mode.from_role.caption"),
|
||||
data: {
|
||||
target_name: "mode",
|
||||
"show-when-value-selected-target": "cause"
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
copy.group(
|
||||
hidden: !another_type_at_first,
|
||||
data: {
|
||||
target_name: "mode",
|
||||
value: "from_type",
|
||||
"show-when-value-selected-target": "effect"
|
||||
}
|
||||
) do |from_type|
|
||||
target_label = helpers.t("workflows.copies.form.target_type_id.label")
|
||||
from_type.select_list(name: :target_type_id, label: target_label, required: true) do |target_list|
|
||||
@other_types.each do |other_type|
|
||||
target_list.option(label: other_type.name, value: other_type.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
copy.group(
|
||||
hidden: another_type_at_first,
|
||||
data: {
|
||||
target_name: "mode",
|
||||
value: "from_role",
|
||||
"show-when-value-selected-target": "effect"
|
||||
}
|
||||
) do |from_role|
|
||||
source_label = helpers.t("workflows.copies.form.source_role_id.label")
|
||||
required = another_type_at_first
|
||||
disabled = !another_type_at_first
|
||||
from_role.select_list(name: :source_role_id, label: source_label, required:, disabled:) do |source_role_list|
|
||||
@all_roles.each do |role|
|
||||
source_role_list.option(label: role.name, value: role.id, selected: role == @source_role)
|
||||
end
|
||||
end
|
||||
from_role.autocompleter(
|
||||
name: "target_role_ids",
|
||||
required: true,
|
||||
include_blank: false,
|
||||
label: helpers.t("workflows.copies.form.target_role_ids.label"),
|
||||
autocomplete_options: {
|
||||
multiple: true,
|
||||
decorated: true,
|
||||
closeOnSelect: false,
|
||||
appendTo: @append_to,
|
||||
data: {
|
||||
"test-selector": "target_roles_autocomplete"
|
||||
}
|
||||
}
|
||||
) do |target_list|
|
||||
@all_roles.each do |role|
|
||||
target_list.option(label: role.name, value: role.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,67 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
class Workflows::Copies::FromRoleForm < ApplicationForm
|
||||
def initialize(source_type:, source_role:, all_roles:, append_to: nil)
|
||||
super()
|
||||
@source_type = source_type
|
||||
@source_role = source_role
|
||||
@all_roles = all_roles
|
||||
@append_to = append_to
|
||||
end
|
||||
|
||||
form do |copy|
|
||||
source_label = helpers.t("workflows.copies.from_role_form.source_role")
|
||||
copy.select_list(name: :source_role_id, label: source_label, required: true) do |source_role_list|
|
||||
@all_roles.each do |role|
|
||||
source_role_list.option(label: role.name, value: role.id, selected: role == @source_role)
|
||||
end
|
||||
end
|
||||
copy.autocompleter(
|
||||
name: "target_role_ids",
|
||||
required: true,
|
||||
include_blank: false,
|
||||
label: helpers.t("workflows.copies.from_role_form.target_roles"),
|
||||
autocomplete_options: {
|
||||
multiple: true,
|
||||
decorated: true,
|
||||
closeOnSelect: false,
|
||||
appendTo: @append_to,
|
||||
data: {
|
||||
"test-selector": "target_roles_autocomplete"
|
||||
}
|
||||
}
|
||||
) do |target_list|
|
||||
@all_roles.each do |role|
|
||||
target_list.option(label: role.name, value: role.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,46 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
class Workflows::Copies::FromTypeForm < ApplicationForm
|
||||
def initialize(source_type:, other_types:)
|
||||
super()
|
||||
@source_type = source_type
|
||||
@other_types = other_types
|
||||
end
|
||||
|
||||
form do |copy|
|
||||
target_label = helpers.t("workflows.copies.from_type_form.target_type")
|
||||
copy.select_list(name: :target_type_id, label: target_label, required: true) do |target_list|
|
||||
@other_types.each do |other_type|
|
||||
target_list.option(label: other_type.name, value: other_type.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,55 +0,0 @@
|
||||
<%#-- copyright
|
||||
OpenProject is an open source project management software.
|
||||
Copyright (C) the OpenProject GmbH
|
||||
|
||||
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 COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
<% title = t(".title", source_type: @source_type.name) %>
|
||||
|
||||
<%= turbo_stream.dialog do
|
||||
render(Primer::Alpha::Dialog.new(title:)) do |d|
|
||||
d.with_header(variant: :large)
|
||||
d.with_body do
|
||||
settings_primer_form_with(url: workflow_copy_from_type_path(@source_type), id: "copy_from_type") do |f|
|
||||
render(Primer::Alpha::Banner.new(scheme: :warning, mb: 4)) do |banner|
|
||||
t(".warning")
|
||||
end +
|
||||
render(Workflows::Copies::FromTypeForm.new(f, source_type: @source_type, other_types: @other_types))
|
||||
end
|
||||
end
|
||||
d.with_footer do
|
||||
render(Primer::Beta::Button.new(
|
||||
scheme: :primary,
|
||||
tag: :button,
|
||||
type: :submit,
|
||||
form: "copy_from_type",
|
||||
data: { turbo: true }
|
||||
)) do
|
||||
t(:button_copy)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
%>
|
||||
+35
-11
@@ -26,27 +26,51 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
See COPYRIGHT and LICENSE files for more details.
|
||||
|
||||
++#%>
|
||||
<% title = t(".title", source_type: @source_type.name) %>
|
||||
|
||||
<% dialog_id = "copy_from_type_dialog" %>
|
||||
<%= turbo_stream.dialog do
|
||||
render(Primer::Alpha::Dialog.new(title:, size: :medium_portrait, id: dialog_id)) do |d|
|
||||
title = t(".title", source_type: @source_type.name)
|
||||
dialog_id = "copy_from_type_dialog"
|
||||
another_type_at_first = @source_role.nil?
|
||||
|
||||
render(Primer::Alpha::Dialog.new(title:, size: :large, id: dialog_id, data: { controller: "show-when-value-selected" })) do |d|
|
||||
d.with_header(variant: :large)
|
||||
d.with_body(classes: "workflow-status-dialog-body") do
|
||||
settings_primer_form_with(url: workflow_copy_from_role_path(@source_type), id: "copy_from_role") do |f|
|
||||
render(Primer::Alpha::Banner.new(scheme: :warning, mb: 4)) do |banner|
|
||||
t(".warning")
|
||||
end +
|
||||
render(Workflows::Copies::FromRoleForm.new(f, source_type: @source_type, source_role: @source_role, all_roles: @all_roles, append_to: "##{dialog_id}"))
|
||||
settings_primer_form_with(id: "copy_form") do |f|
|
||||
render(Workflows::Copies::Form.new(f, source_type: @source_type, source_role: @source_role, other_types: @other_types, all_roles: @all_roles, append_to: "##{dialog_id}"))
|
||||
end
|
||||
end
|
||||
d.with_footer do
|
||||
render(Primer::Beta::Button.new(data: { "close-dialog-id": dialog_id })) { "Cancel" } +
|
||||
|
||||
render(Primer::Beta::Button.new(
|
||||
hidden: !another_type_at_first,
|
||||
scheme: :primary,
|
||||
tag: :button,
|
||||
type: :submit,
|
||||
form: "copy_from_role",
|
||||
data: { turbo: true }
|
||||
form: "copy_form",
|
||||
formaction: workflow_copy_from_type_path(@source_type),
|
||||
data: {
|
||||
target_name: "mode",
|
||||
value: "from_type",
|
||||
"show-when-value-selected-target": "effect",
|
||||
turbo: true
|
||||
}
|
||||
)) do
|
||||
t(:button_copy)
|
||||
end +
|
||||
|
||||
render(Primer::Beta::Button.new(
|
||||
hidden: another_type_at_first,
|
||||
scheme: :primary,
|
||||
tag: :button,
|
||||
type: :submit,
|
||||
form: "copy_form",
|
||||
formaction: workflow_copy_from_role_path(@source_type, source_role_id: @source_role&.id),
|
||||
data: {
|
||||
target_name: "mode",
|
||||
value: "from_role",
|
||||
"show-when-value-selected-target": "effect",
|
||||
turbo: true
|
||||
}
|
||||
)) do
|
||||
t(:button_copy)
|
||||
end
|
||||
+16
-13
@@ -1393,19 +1393,22 @@ en:
|
||||
|
||||
workflows:
|
||||
copies:
|
||||
from_role_form:
|
||||
source_role: "Source role"
|
||||
target_roles: "Target roles"
|
||||
from_roles:
|
||||
new:
|
||||
title: "Copy workflow of \"%{source_type}\" between roles"
|
||||
warning: "This action will replace existing workflows of the selected target roles."
|
||||
from_type_form:
|
||||
target_type: "Target type"
|
||||
from_types:
|
||||
new:
|
||||
title: "Copy workflow from \"%{source_type}\" to another type"
|
||||
warning: "This action will replace existing workflows of all the roles of the selected target type."
|
||||
form:
|
||||
source_role_id:
|
||||
label: "Source role"
|
||||
target_role_ids:
|
||||
label: "Target roles"
|
||||
target_type_id:
|
||||
label: "Target type"
|
||||
mode:
|
||||
from_role:
|
||||
label: "Copy to other roles"
|
||||
caption: "Copy the current workflow to one or more roles inside the same work package type. If the selected role has already a workflow the current one will be overwritten."
|
||||
from_type:
|
||||
label: "Copy to another type"
|
||||
caption: "Copy the current workflow to another work packages type. If the selected type has already a workflow the current one will be overwritten."
|
||||
new:
|
||||
title: "Copy workflow of \"%{source_type}\""
|
||||
form:
|
||||
matrix_caption: "Workflow matrix"
|
||||
matrix_caption_assignee: "Workflow matrix for assignee"
|
||||
|
||||
+5
-3
@@ -804,9 +804,11 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
resources :workflows, only: %i[index edit update], param: :type_id do
|
||||
resource :copy, only: %i[], module: "workflows/copies" do
|
||||
resource :from_type, only: %i[new create]
|
||||
resource :from_role, only: %i[new create]
|
||||
resource :copy, only: %i[new], module: :workflows do
|
||||
scope module: :copies do
|
||||
resource :from_type, only: %i[create]
|
||||
resource :from_role, only: %i[create]
|
||||
end
|
||||
end
|
||||
collection do
|
||||
get :status_dialog
|
||||
|
||||
@@ -137,7 +137,7 @@ primer_form_with(
|
||||
data: {
|
||||
target_name: "frequency",
|
||||
value: "foo"
|
||||
"show-when-value-selected-target": "cause"
|
||||
"show-when-value-selected-target": "effect"
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -65,14 +65,12 @@ RSpec.describe Workflows::TableComponent, type: :component do
|
||||
expect(rendered_component).to have_css("li", text: types.first.name) do |row|
|
||||
expect(row).to have_link(types.first.name, href: edit_workflow_path(types.first))
|
||||
expect(row).to have_link("Edit", href: edit_workflow_path(types.first))
|
||||
expect(row).to have_link("Copy to another type", href: new_workflow_copy_from_type_path(types.first))
|
||||
expect(row).to have_link("Copy to other roles", href: new_workflow_copy_from_role_path(types.first))
|
||||
expect(row).to have_link("Copy", href: new_workflow_copy_path(types.first))
|
||||
end
|
||||
expect(rendered_component).to have_css("li", text: types.second.name) do |row|
|
||||
expect(row).to have_link(types.second.name, href: edit_workflow_path(types.second))
|
||||
expect(row).to have_link("Edit", href: edit_workflow_path(types.second))
|
||||
expect(row).to have_link("Copy to another type", href: new_workflow_copy_from_type_path(types.second))
|
||||
expect(row).to have_link("Copy to other roles", href: new_workflow_copy_from_role_path(types.second))
|
||||
expect(row).to have_link("Copy", href: new_workflow_copy_path(types.second))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,58 +53,12 @@ RSpec.describe Workflows::Copies::FromRolesController do
|
||||
build_stubbed_list(:project_role, 2)
|
||||
end
|
||||
|
||||
let!(:source_role) { nil }
|
||||
|
||||
before do
|
||||
allow(eligible_roles).to receive(:find_by).and_return(source_role)
|
||||
end
|
||||
|
||||
current_user { build_stubbed(:admin) }
|
||||
|
||||
describe "#new" do
|
||||
let(:params) do
|
||||
{ workflow_type_id: source_type.id.to_s, source_role_id: source_role&.id }
|
||||
end
|
||||
|
||||
before do
|
||||
get :new, params:
|
||||
end
|
||||
|
||||
it "is a success" do
|
||||
expect(response)
|
||||
.to have_http_status(:ok)
|
||||
end
|
||||
|
||||
it "renders the correct template" do
|
||||
expect(response)
|
||||
.to render_template :new
|
||||
end
|
||||
|
||||
it "assigns the source type" do
|
||||
expect(assigns[:source_type])
|
||||
.to eq source_type
|
||||
end
|
||||
|
||||
it "does not assign any source role" do
|
||||
expect(assigns[:source_role])
|
||||
.to be_nil
|
||||
end
|
||||
|
||||
it "assigns the eligible roles" do
|
||||
expect(assigns[:all_roles])
|
||||
.to match_array(all_roles)
|
||||
end
|
||||
|
||||
describe "when the source role is specified" do
|
||||
let!(:source_role) { all_roles.sample }
|
||||
|
||||
it "assigns the source role" do
|
||||
expect(assigns[:source_role])
|
||||
.to eq source_role
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
let!(:source_role) { all_roles.sample }
|
||||
let!(:target_roles) do
|
||||
|
||||
@@ -53,36 +53,6 @@ RSpec.describe Workflows::Copies::FromTypesController do
|
||||
|
||||
current_user { build_stubbed(:admin) }
|
||||
|
||||
describe "#new" do
|
||||
let(:params) do
|
||||
{ workflow_type_id: source_type.id.to_s }
|
||||
end
|
||||
|
||||
before do
|
||||
get :new, params:
|
||||
end
|
||||
|
||||
it "is a success" do
|
||||
expect(response)
|
||||
.to have_http_status(:ok)
|
||||
end
|
||||
|
||||
it "renders the correct template" do
|
||||
expect(response)
|
||||
.to render_template :new
|
||||
end
|
||||
|
||||
it "assigns the source_type" do
|
||||
expect(assigns[:source_type])
|
||||
.to eq source_type
|
||||
end
|
||||
|
||||
it "assigns the source_role" do
|
||||
expect(assigns[:other_types])
|
||||
.to match_array(other_types)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
let!(:target_type) do
|
||||
other_types.last.tap do |stub|
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Workflows::CopiesController do
|
||||
let!(:source_type) do
|
||||
build_stubbed(:type) do |stub|
|
||||
allow(Type)
|
||||
.to receive(:find)
|
||||
.with(stub.id.to_s)
|
||||
.and_return(stub)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:other_types) do
|
||||
build_stubbed_list(:type, 2).tap do |stubs|
|
||||
where_double = instance_double(ActiveRecord::QueryMethods::WhereChain)
|
||||
not_double = instance_double(ActiveRecord::Relation)
|
||||
|
||||
allow(Type).to receive(:where).and_return(where_double)
|
||||
allow(where_double).to receive(:not).and_return(not_double)
|
||||
allow(not_double).to receive(:order).and_return(stubs)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:eligible_roles) do
|
||||
instance_double(ActiveRecord::Relation, to_a: all_roles).tap do |relation|
|
||||
allow(Role)
|
||||
.to receive(:where)
|
||||
.with(type: ProjectRole.name)
|
||||
.and_return(relation)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:all_roles) do
|
||||
build_stubbed_list(:project_role, 2)
|
||||
end
|
||||
|
||||
let!(:source_role) { nil }
|
||||
|
||||
before do
|
||||
allow(eligible_roles).to receive(:find_by).and_return(source_role)
|
||||
end
|
||||
|
||||
current_user { build_stubbed(:admin) }
|
||||
|
||||
describe "#new" do
|
||||
let(:params) do
|
||||
{ workflow_type_id: source_type.id.to_s, source_role_id: source_role&.id }
|
||||
end
|
||||
|
||||
before do
|
||||
get :new, params:, format: :turbo_stream
|
||||
end
|
||||
|
||||
it "is a success" do
|
||||
expect(response)
|
||||
.to have_http_status(:ok)
|
||||
end
|
||||
|
||||
it "renders the correct template" do
|
||||
expect(response)
|
||||
.to render_template :new
|
||||
end
|
||||
|
||||
it "assigns the source type" do
|
||||
expect(assigns[:source_type])
|
||||
.to eq source_type
|
||||
end
|
||||
|
||||
it "assigns the other types" do
|
||||
expect(assigns[:other_types])
|
||||
.to match_array(other_types)
|
||||
end
|
||||
|
||||
it "does not assign any source role" do
|
||||
expect(assigns[:source_role])
|
||||
.to be_nil
|
||||
end
|
||||
|
||||
it "assigns the eligible roles" do
|
||||
expect(assigns[:all_roles])
|
||||
.to match_array(all_roles)
|
||||
end
|
||||
|
||||
describe "when the source role is specified" do
|
||||
let!(:source_role) { all_roles.sample }
|
||||
|
||||
it "assigns the source role" do
|
||||
expect(assigns[:source_role])
|
||||
.to eq source_role
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe "Workflow copy from role" do
|
||||
RSpec.describe "Workflow copy from role", :js do
|
||||
let!(:type) { create(:type) }
|
||||
let!(:roles) { create_list(:project_role, 3) }
|
||||
let(:admin) { create(:admin) }
|
||||
@@ -39,45 +39,42 @@ RSpec.describe "Workflow copy from role" do
|
||||
|
||||
current_user { admin }
|
||||
|
||||
before do
|
||||
visit new_workflow_copy_from_role_path(type)
|
||||
shared_examples "a copy-to-other-roles dialog" do |with_source_role:|
|
||||
it "permits to select a source role and target source roles" do
|
||||
unless with_source_role
|
||||
choose "Copy to other roles"
|
||||
|
||||
expect(page).to have_select("Source role", text: roles.first.name)
|
||||
select(roles.last.name, from: "Source role")
|
||||
end
|
||||
|
||||
target_roles_autocompleter.select_option roles.first.name, roles.second.name
|
||||
target_roles_autocompleter.close_autocompleter
|
||||
|
||||
click_button "Copy"
|
||||
|
||||
expect(page).to have_css(".flash-success", text: "Successful update.")
|
||||
end
|
||||
end
|
||||
|
||||
it "permits to select a source role and target source roles", :js do
|
||||
expect(page).to have_select("Source role", text: roles.first.name)
|
||||
select(roles.last.name, from: "Source role")
|
||||
describe "from the workflows index page" do
|
||||
before do
|
||||
visit workflows_path
|
||||
within "li", text: type.name do
|
||||
find("button[aria-haspopup=true]").click
|
||||
click_link "Copy"
|
||||
end
|
||||
end
|
||||
|
||||
target_roles_autocompleter.select_option roles.first.name, roles.second.name
|
||||
target_roles_autocompleter.close_autocompleter
|
||||
|
||||
click_button "Copy"
|
||||
|
||||
expect(page).to have_css(".flash-success", text: "Successful update.")
|
||||
it_behaves_like "a copy-to-other-roles dialog", with_source_role: false
|
||||
end
|
||||
|
||||
it "allows to go back to Workflow index page" do
|
||||
visit workflows_path
|
||||
within "li", text: type.name do
|
||||
click_link "Copy to other roles"
|
||||
describe "from the workflows edit page" do
|
||||
before do
|
||||
visit edit_workflow_path(type)
|
||||
click_link "Copy"
|
||||
end
|
||||
|
||||
within ".Banner--warning" do
|
||||
click_link "Cancel"
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Workflow"
|
||||
expect(page).to have_current_path(workflows_path)
|
||||
end
|
||||
|
||||
it "allows to go back to Workflow edit page" do
|
||||
visit edit_workflow_path(type)
|
||||
click_link "Copy to other roles"
|
||||
|
||||
within ".Banner--warning" do
|
||||
click_link "Cancel"
|
||||
end
|
||||
|
||||
expect(page).to have_heading type.name
|
||||
expect(page).to have_current_path(edit_workflow_path(type))
|
||||
it_behaves_like "a copy-to-other-roles dialog", with_source_role: true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,48 +30,46 @@
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe "Workflow copy from type" do
|
||||
let(:types) { create_list(:type, 3) }
|
||||
let(:type) { types.first }
|
||||
RSpec.describe "Workflow copy from type", :js do
|
||||
let!(:types) { create_list(:type, 3) }
|
||||
let!(:type) { types.first }
|
||||
let(:admin) { create(:admin) }
|
||||
|
||||
current_user { admin }
|
||||
|
||||
before do
|
||||
visit new_workflow_copy_from_type_path(type)
|
||||
shared_examples "a copy-to-another-type dialog" do |with_source_role:|
|
||||
it "permits to select a target type" do
|
||||
if with_source_role
|
||||
choose "Copy to another type"
|
||||
end
|
||||
|
||||
expect(page).to have_select("Target type", text: types.second.name)
|
||||
select(types.last.name, from: "Target type")
|
||||
|
||||
click_button "Copy"
|
||||
|
||||
expect(page).to have_css(".flash-success", text: "Successful update.")
|
||||
end
|
||||
end
|
||||
|
||||
it "permits to select another type", :js do
|
||||
expect(page).to have_select("Target type", text: types.second.name)
|
||||
select(types.last.name, from: "Target type")
|
||||
click_button "Copy"
|
||||
describe "from the workflows index page" do
|
||||
before do
|
||||
visit workflows_path
|
||||
within "li", text: type.name do
|
||||
find("button[aria-haspopup=true]").click
|
||||
click_link "Copy"
|
||||
end
|
||||
end
|
||||
|
||||
expect(page).to have_css(".flash-success", text: "Successful update.")
|
||||
it_behaves_like "a copy-to-another-type dialog", with_source_role: false
|
||||
end
|
||||
|
||||
it "allows to go back to Workflow index page" do
|
||||
visit workflows_path
|
||||
within "li", text: type.name do
|
||||
click_link "Copy to another type"
|
||||
describe "from the workflows edit page" do
|
||||
before do
|
||||
visit edit_workflow_path(type)
|
||||
click_link "Copy"
|
||||
end
|
||||
|
||||
within ".Banner--warning" do
|
||||
click_link "Cancel"
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Workflow"
|
||||
expect(page).to have_current_path(workflows_path)
|
||||
end
|
||||
|
||||
it "allows to go back to Workflow edit page" do
|
||||
visit edit_workflow_path(type)
|
||||
click_link "Copy to another type"
|
||||
|
||||
within ".Banner--warning" do
|
||||
click_link "Cancel"
|
||||
end
|
||||
|
||||
expect(page).to have_heading type.name
|
||||
expect(page).to have_current_path(edit_workflow_path(type))
|
||||
it_behaves_like "a copy-to-another-type dialog", with_source_role: true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -372,24 +372,6 @@ RSpec.describe "Workflow edit" do
|
||||
end
|
||||
end
|
||||
|
||||
it "allows navigating to Workflow copy-from-type page" do
|
||||
within ".PageHeader-actions" do
|
||||
click_on "Copy to another type"
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Copy workflow"
|
||||
expect(page).to have_current_path(new_workflow_copy_from_type_path(type))
|
||||
end
|
||||
|
||||
it "allows navigating to Workflow copy-from-role page" do
|
||||
within ".PageHeader-actions" do
|
||||
click_on "Copy to other roles"
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Copy workflow"
|
||||
expect(page).to have_current_path(new_workflow_copy_from_role_path(type, source_role_id: role.id))
|
||||
end
|
||||
|
||||
context "with status dialog", :js do
|
||||
before do
|
||||
visit_workflow_edit(role:)
|
||||
@@ -579,4 +561,12 @@ RSpec.describe "Workflow edit" do
|
||||
expect(page).to have_text("Add statuses to start configuring workflows for this role")
|
||||
end
|
||||
end
|
||||
|
||||
it "allows navigating to any Copy page", :js do
|
||||
within ".PageHeader-actions" do
|
||||
click_on "Copy"
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Copy workflow"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,34 +74,18 @@ RSpec.describe "Workflows index" do
|
||||
expect(page).to have_current_path(edit_workflow_path(some_type))
|
||||
end
|
||||
|
||||
it "allows navigating to any copy-from-type page" do
|
||||
it "allows navigating to any Copy page", :js do
|
||||
expect(page).to have_heading("Workflows")
|
||||
|
||||
some_type = types.sample
|
||||
within "ul.Box-list" do
|
||||
within "li", text: some_type.name do
|
||||
find("button[aria-haspopup=true]").click
|
||||
click_link "Copy to another type"
|
||||
click_link "Copy"
|
||||
end
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Copy workflow"
|
||||
expect(page).to have_current_path(new_workflow_copy_from_type_path(some_type))
|
||||
end
|
||||
|
||||
it "allows navigating to any copy-from-role page" do
|
||||
expect(page).to have_heading("Workflows")
|
||||
|
||||
some_type = types.sample
|
||||
within "ul.Box-list" do
|
||||
within "li", text: some_type.name do
|
||||
find("button[aria-haspopup=true]").click
|
||||
click_link "Copy to other roles"
|
||||
end
|
||||
end
|
||||
|
||||
expect(page).to have_heading "Copy workflow"
|
||||
expect(page).to have_current_path(new_workflow_copy_from_role_path(some_type))
|
||||
end
|
||||
|
||||
it "allows navigating to Workflow summary page" do
|
||||
|
||||
@@ -68,8 +68,9 @@ RSpec.describe "Configuring the workflow for work package sharing", :js,
|
||||
# On the copy workflow form, select the already existing workflow for copying
|
||||
within "li", text: type.name do
|
||||
find("button[aria-haspopup=true]").click
|
||||
click_link "Copy to other roles"
|
||||
click_link "Copy"
|
||||
end
|
||||
choose "Copy to other roles"
|
||||
select role.name, from: "source_role_id"
|
||||
target_roles_autocompleter.select_option work_package_role.name
|
||||
target_roles_autocompleter.close_autocompleter
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
#
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Workflows::Copies::Form, type: :forms do
|
||||
include_context "with rendered form"
|
||||
|
||||
let(:model) { false }
|
||||
let(:params) { { source_type:, source_role:, other_types:, all_roles: } }
|
||||
let(:source_type) { create(:type) }
|
||||
let(:other_types) { create_list(:type, 4) }
|
||||
let(:all_roles) { create_list(:project_role, 4) }
|
||||
|
||||
shared_examples "a copy form with conditional fields" do |another_type_at_first:|
|
||||
it "renders radio buttons to choose the mode" do
|
||||
expect(page).to have_field("Copy to another type", checked: another_type_at_first)
|
||||
expect(page).to have_field("Copy to other roles", checked: !another_type_at_first)
|
||||
end
|
||||
|
||||
it "renders the Target type select list" do
|
||||
expect(page).to have_select "Target type", required: true, visible: another_type_at_first do |select|
|
||||
options_text = select.all("option", visible: another_type_at_first).map(&:text)
|
||||
expect(options_text).to match_array(other_types.map(&:name))
|
||||
end
|
||||
end
|
||||
|
||||
it "renders the Source role select list" do
|
||||
required = another_type_at_first
|
||||
disabled = visible = !another_type_at_first
|
||||
expect(page).to have_select "Source role", required:, disabled:, visible: do |select|
|
||||
options_text = select.all("option", visible: !another_type_at_first).map(&:text)
|
||||
expect(options_text).to match_array(all_roles.map(&:name))
|
||||
end
|
||||
end
|
||||
|
||||
it "renders the Target roles autocompleter" do
|
||||
data_attributes = "[data-test-selector=\"target_roles_autocomplete\"][data-multiple=\"true\"]"
|
||||
expect(page).to have_css "opce-autocompleter#{data_attributes}", visible: !another_type_at_first do |autocompleter|
|
||||
options_text = JSON.parse(autocompleter["data-items"]).map { |item| item["name"] }
|
||||
expect(options_text).to match_array(all_roles.map(&:name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the source role is not specified" do
|
||||
let(:source_role) { nil }
|
||||
|
||||
it_behaves_like "a copy form with conditional fields", another_type_at_first: true
|
||||
end
|
||||
|
||||
describe "when the source role is specified" do
|
||||
let(:source_role) { all_roles.sample }
|
||||
|
||||
it_behaves_like "a copy form with conditional fields", another_type_at_first: false
|
||||
|
||||
it "renders the Source role select list with read-only source" do
|
||||
expect(page).to have_select "Source role", disabled: true do |select|
|
||||
selected_option_text = select.all("option[selected=selected]").map(&:text)
|
||||
expect(selected_option_text).to contain_exactly(source_role.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,71 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# 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 COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
#
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Workflows::Copies::FromRoleForm, type: :forms do
|
||||
include_context "with rendered form"
|
||||
|
||||
let(:model) { false }
|
||||
let(:params) { { source_type:, source_role:, all_roles: } }
|
||||
let(:source_type) { create(:type) }
|
||||
let(:all_roles) { create_list(:project_role, 4) }
|
||||
let(:source_role) { nil }
|
||||
|
||||
it "renders the Source role select list" do
|
||||
expect(page).to have_select "Source role", required: true do |select|
|
||||
options_text = select.all("option").map(&:text)
|
||||
expect(options_text).to match_array(all_roles.map(&:name))
|
||||
end
|
||||
end
|
||||
|
||||
it "renders the Target roles autocompleter" do
|
||||
data_attributes = "[data-test-selector=\"target_roles_autocomplete\"][data-multiple=\"true\"]"
|
||||
expect(page).to have_css "opce-autocompleter#{data_attributes}" do |autocompleter|
|
||||
options_text = JSON.parse(autocompleter["data-items"]).map { |item| item["name"] }
|
||||
expect(options_text).to match_array(all_roles.map(&:name))
|
||||
end
|
||||
end
|
||||
|
||||
it "renders submit button" do
|
||||
expect(page).to have_button "Copy", class: "Button--primary"
|
||||
end
|
||||
|
||||
describe "when the source type is specified" do
|
||||
let(:source_role) { all_roles.sample }
|
||||
|
||||
it "renders the Source role select list with selected source" do
|
||||
expect(page).to have_select "Source role", required: true do |select|
|
||||
selected_option_text = select.all("option[selected=selected]").map(&:text)
|
||||
expect(selected_option_text).to contain_exactly(source_role.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -36,16 +36,14 @@ RSpec.describe "workflows routes" do
|
||||
it { expect(get("/workflows/42/edit")).to route_to("workflows#edit", type_id: "42") }
|
||||
it { expect(patch("/workflows/42")).to route_to("workflows#update", type_id: "42") }
|
||||
|
||||
it { expect(get("/workflows/42/copy/from_type/new")).to route_to("workflows/copies/from_types#new", workflow_type_id: "42") }
|
||||
it { expect(post("/workflows/42/copy/from_type")).to route_to("workflows/copies/from_types#create", workflow_type_id: "42") }
|
||||
|
||||
it { expect(get("/workflows/42/copy/from_role/new")).to route_to("workflows/copies/from_roles#new", workflow_type_id: "42") }
|
||||
it { expect(get("/workflows/42/copy/new")).to route_to("workflows/copies#new", workflow_type_id: "42") }
|
||||
|
||||
it do
|
||||
expect(get("/workflows/42/copy/from_role/new?source_role_id=23"))
|
||||
.to route_to("workflows/copies/from_roles#new", workflow_type_id: "42", source_role_id: "23")
|
||||
expect(get("/workflows/42/copy/new?source_role_id=23"))
|
||||
.to route_to("workflows/copies#new", workflow_type_id: "42", source_role_id: "23")
|
||||
end
|
||||
|
||||
it { expect(post("/workflows/42/copy/from_type")).to route_to("workflows/copies/from_types#create", workflow_type_id: "42") }
|
||||
it { expect(post("/workflows/42/copy/from_role")).to route_to("workflows/copies/from_roles#create", workflow_type_id: "42") }
|
||||
|
||||
it { expect(get("/workflows/summary")).to route_to("workflows/summaries#show") }
|
||||
|
||||
Reference in New Issue
Block a user