Skip to content

[pull] dev from opf:dev #352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 15, 2025
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ GEM
awesome_nested_set (3.8.0)
activerecord (>= 4.0.0, < 8.1)
aws-eventstream (1.3.0)
aws-partitions (1.1035.0)
aws-sdk-core (3.215.0)
aws-partitions (1.1037.0)
aws-sdk-core (3.215.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
Expand Down Expand Up @@ -713,7 +713,7 @@ GEM
launchy (3.0.1)
addressable (~> 2.8)
childprocess (~> 5.0)
lefthook (1.10.4)
lefthook (1.10.5)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
letter_opener_web (3.0.0)
Expand Down Expand Up @@ -1109,7 +1109,7 @@ GEM
activesupport (>= 6.1)
sprockets (>= 3.0.0)
ssrf_filter (1.0.8)
stackprof (0.2.26)
stackprof (0.2.27)
store_attribute (2.0.0)
activerecord (>= 6.1)
stringex (2.8.6)
Expand Down
22 changes: 9 additions & 13 deletions app/components/work_package_relations_tab/index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,18 @@ class WorkPackageRelationsTab::IndexComponent < ApplicationComponent
include Turbo::FramesHelper
include OpTurbo::Streamable

attr_reader :work_package, :relations, :children, :directionally_aware_grouped_relations, :relation_to_scroll_to
attr_reader :relations_mediator, :directionally_aware_grouped_relations, :relation_to_scroll_to

delegate :work_package, :relations, :children, :any_relations?, to: :relations_mediator

# Initialize the component with required data
#
# @param work_package [WorkPackage] The work package whose relations are being displayed
# @param relations [Array<Relation>] The relations associated with this work package
# @param children [Array<WorkPackage>] Child work packages
# @param relation_to_scroll_to [Relation, WorkPackage, nil] Optional relation or child to scroll to when rendering
def initialize(work_package:, relations:, children:, relation_to_scroll_to: nil)
def initialize(work_package: nil, relation_to_scroll_to: nil)
super()

@work_package = work_package
@relations = relations
@children = children
@relations_mediator = WorkPackageRelationsTab::RelationsMediator.new(work_package:)
@directionally_aware_grouped_relations = group_relations_by_directional_context
@relation_to_scroll_to = relation_to_scroll_to
end
Expand All @@ -41,13 +39,13 @@ def self.wrapper_key
private

def should_render_add_child?
return false if @work_package.milestone?
return false if work_package.milestone?

helpers.current_user.allowed_in_project?(:manage_subtasks, @work_package.project)
helpers.current_user.allowed_in_project?(:manage_subtasks, work_package.project)
end

def should_render_add_relations?
helpers.current_user.allowed_in_project?(:manage_work_package_relations, @work_package.project)
helpers.current_user.allowed_in_project?(:manage_work_package_relations, work_package.project)
end

def should_render_create_button?
Expand All @@ -60,8 +58,6 @@ def group_relations_by_directional_context
end
end

def any_relations? = relations.any? || children.any?

def render_relation_group(title:, relation_type:, items:, &_block)
render(border_box_container(
padding: :condensed,
Expand Down Expand Up @@ -109,7 +105,7 @@ def render_children_header(border_box, title, items) # rubocop:disable Metrics/A
def render_child_menu_items(menu) # rubocop:disable Metrics/AbcSize
return unless should_render_add_child?

if helpers.current_user.allowed_in_project?(:add_work_packages, @work_package.project)
if helpers.current_user.allowed_in_project?(:add_work_packages, work_package.project)
menu.with_item(
label: t("work_package_relations_tab.relations.new_child"),
href: new_project_work_packages_dialog_path(work_package.project, parent_id: work_package.id),
Expand Down
49 changes: 49 additions & 0 deletions app/components/work_package_relations_tab/relations_mediator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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 WorkPackageRelationsTab::RelationsMediator
attr_reader :work_package

def initialize(work_package:)
@work_package = work_package
end

def relations
@relations ||= work_package.relations.includes(:to, :from).visible
end

def children
@children ||= work_package.children.visible
end

def any_relations?
relations.any? || children.any?
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,7 @@ def set_relation(child:, parent:)
def respond_with_relations_tab_update(service_result, **)
if service_result.success?
@work_package.reload
component = WorkPackageRelationsTab::IndexComponent.new(
work_package: @work_package,
relations: @work_package.relations.visible,
children: @work_package.children.visible,
**
)
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package, **)
replace_via_turbo_stream(component:)
render_success_flash_message_via_turbo_stream(message: I18n.t(:notice_successful_update))

Expand Down
45 changes: 12 additions & 33 deletions app/controllers/work_package_relations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,7 @@ def create
service_result = Relations::CreateService.new(user: current_user)
.call(create_relation_params)

if service_result.success?
@work_package.reload
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package,
relations: @work_package.relations.visible,
children: @work_package.children.visible,
relation_to_scroll_to: service_result.result)
replace_via_turbo_stream(component:)
respond_with_turbo_streams
else
respond_with_turbo_streams(status: :unprocessable_entity)
end
respond_with_relations_tab_update(service_result, relation_to_scroll_to: service_result.result)
end

def update
Expand All @@ -78,41 +68,30 @@ def update
model: @relation)
.call(update_relation_params)

if service_result.success?
@work_package.reload
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package,
relations: @work_package.relations.visible,
children: @work_package.children.visible)
replace_via_turbo_stream(component:)
respond_with_turbo_streams
else
respond_with_turbo_streams(status: :unprocessable_entity)
end
respond_with_relations_tab_update(service_result)
end

def destroy
service_result = Relations::DeleteService.new(user: current_user, model: @relation).call

respond_with_relations_tab_update(service_result)
end

private

def respond_with_relations_tab_update(service_result, **)
if service_result.success?
@children = WorkPackage.where(parent_id: @work_package.id).visible
@relations = @work_package
.relations
.reload
.includes(:to, :from)
.visible

component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package,
relations: @relations,
children: @children)
@work_package.reload
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package, **)
replace_via_turbo_stream(component:)
render_success_flash_message_via_turbo_stream(message: I18n.t(:notice_successful_update))

respond_with_turbo_streams
else
respond_with_turbo_streams(status: :unprocessable_entity)
end
end

private

def set_work_package
@work_package = WorkPackage.find(params[:work_package_id])
end
Expand Down
12 changes: 1 addition & 11 deletions app/controllers/work_package_relations_tab_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,7 @@ class WorkPackageRelationsTabController < ApplicationController
before_action :authorize_global

def index
@children = WorkPackage.where(parent_id: @work_package.id).visible
@relations = @work_package
.relations
.visible
.includes(:to, :from)

component = WorkPackageRelationsTab::IndexComponent.new(
work_package: @work_package,
relations: @relations,
children: @children
)
component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package)

respond_to do |format|
format.html do
Expand Down
6 changes: 0 additions & 6 deletions app/views/work_package_relations_tab/_index.html.erb

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def send_delete_request
send_delete_request

expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new)
.with(work_package:, relations: [], children: [])
.with(work_package:)
expect(controller).to have_received(:replace_via_turbo_stream)
.with(component: an_instance_of(WorkPackageRelationsTab::IndexComponent))
end
Expand Down
6 changes: 3 additions & 3 deletions spec/controllers/work_package_relations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
new_relation = Relation.last

expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new)
.with(work_package:, relations: [relation, new_relation], children:, relation_to_scroll_to: new_relation)
.with(work_package:, relation_to_scroll_to: new_relation)
expect(controller).to have_received(:replace_via_turbo_stream)
.with(component: an_instance_of(WorkPackageRelationsTab::IndexComponent))
end
Expand All @@ -142,7 +142,7 @@
expect(response).to be_successful

expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new)
.with(work_package:, relations: [relation], children:)
.with(work_package:)
expect(controller).to have_received(:replace_via_turbo_stream)
.with(component: an_instance_of(WorkPackageRelationsTab::IndexComponent))
end
Expand All @@ -160,7 +160,7 @@
expect(response).to be_successful

expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new)
.with(work_package:, relations: [], children:)
.with(work_package:)
expect(controller).to have_received(:replace_via_turbo_stream)
.with(component: an_instance_of(WorkPackageRelationsTab::IndexComponent))
expect { relation.reload }.to raise_error(ActiveRecord::RecordNotFound)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,8 @@

it "renders the relations tab" do
get("index", params: { work_package_id: work_package.id }, as: :turbo_stream)
expect(WorkPackageRelationsTab::IndexComponent).to have_received(:new).with(
work_package:,
relations:,
children:
)
expect(WorkPackageRelationsTab::IndexComponent)
.to have_received(:new).with(work_package:)

expect(response).to be_successful
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

require "spec_helper"

RSpec.shared_examples "work package relations tab", :js, :selenium do
RSpec.shared_examples "work package relations tab", :js, :with_cuprite do
include_context "ng-select-autocomplete helpers"

let(:user) { create(:admin) }
Expand Down
Loading