Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1886d1e
[#58161] Global stage administration
toy Dec 4, 2024
df017fe
add menu entry
toy Dec 4, 2024
905ce22
make life cycle step definitions default to order by position
toy Dec 4, 2024
5310980
routing
toy Dec 11, 2024
fea5dad
index header
toy Dec 4, 2024
aee3c30
add form and new/edit actions
toy Dec 11, 2024
1af2048
Project::LifeCycleStepDefinition.with_project_count
toy Dec 11, 2024
425eda7
basic index - list definitions
toy Dec 11, 2024
c676588
show project count in index
toy Dec 12, 2024
7b239c8
cleanup row component
toy Dec 12, 2024
418374f
add menu, handle moving and destroying
toy Dec 12, 2024
3255e23
{,row-,column-}gap-? classes
toy Dec 12, 2024
946b6a8
handle drag-n-drop ordering, except for expected turbo stream response
toy Dec 12, 2024
1cb482e
simplify ApplicationRecord.most_recently_changed
toy Dec 13, 2024
5b26a8a
highlight_css_updated_at should depend on Project::LifeCycleStepDefin…
toy Dec 13, 2024
8288304
rename border box filter bulkActionContainer target to hideWhenFiltering
toy Dec 13, 2024
1d75e20
hide movement controls when filtering
toy Dec 13, 2024
68ba0a1
require enterprise token
toy Dec 13, 2024
d4c732d
combine subheaders with filter and buttons
toy Dec 16, 2024
2079b57
fix title for form
toy Dec 16, 2024
ddec167
handle responses for destroy/move/drop using turbo streams
toy Dec 16, 2024
f028c7d
no need for global error messages for life cycle step definition form
toy Dec 17, 2024
b7be7f8
move allowed_to_customize_life_cycle? to a module
toy Dec 17, 2024
d1c7c87
make both life cycle project settings and definitions list behave whe…
toy Dec 17, 2024
375752c
change heading description
toy Dec 17, 2024
23270b8
fix color input size, after it was enabled by #17482
toy Dec 18, 2024
73fecde
rename update_flash_message_via_turbo_stream to render_flash_message_…
toy Dec 18, 2024
9f066c6
add render_success_flash_message_via_turbo_stream helper method
toy Dec 18, 2024
bd09315
banner with schema success when successfully destroying definition
toy Dec 18, 2024
8eebf55
use render_error_flash_message_via_turbo_stream where scheme: :danger…
toy Dec 18, 2024
9aa7332
remove placeholder route for project_life_cycle_step_definitions and …
toy Dec 18, 2024
ea9f972
use double quotes
toy Dec 19, 2024
d9e750c
feature spec for all actions except moving using handler
toy Dec 19, 2024
1977224
feature spec for moving using handler
toy Jan 6, 2025
8469741
add frozen string literal magic comment
toy Jan 6, 2025
9f6ad47
Using American English
toy Jan 7, 2025
63ecbe0
ensure not showing admin without feature flag set
toy Jan 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ group :test do
gem "capybara_accessible_selectors", git: "https://github.com/citizensadvice/capybara_accessible_selectors", tag: "v0.12.0"
gem "capybara-screenshot", "~> 1.0.17"
gem "cuprite", "~> 0.15.0"
gem "ferrum", github: "toy/ferrum", ref: "mouse-events-buttons-property-0.15"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job fixing the bug within ferrum. As soon as a new version with your merged PR is released, we can use the original gem once again. 🚀 Do you happen to know when they plan to release a new version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, I only saw that allowing ferrum dependency to be 0.16.* was merged in cuprite.

Not required for this PR, but I created rubycdp/cuprite#288 to scroll to destination when dragging.

gem "rspec-wait"
gem "selenium-devtools"
gem "selenium-webdriver", "~> 4.20"
Expand Down
17 changes: 12 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ GIT
parallel_tests (>= 3.3.0, < 5)
rspec (>= 3.10)

GIT
remote: https://github.com/toy/ferrum.git
revision: 889b29926f017530a0e087b1db0bc02747e437b1
ref: mouse-events-buttons-property-0.15
specs:
ferrum (0.15)
addressable (~> 2.5)
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (~> 0.7)

PATH
remote: modules/auth_plugins
specs:
Expand Down Expand Up @@ -558,11 +569,6 @@ GEM
faraday-net_http (3.4.0)
net-http (>= 0.5.0)
fastimage (2.3.1)
ferrum (0.15)
addressable (~> 2.5)
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (~> 0.7)
ffi (1.17.1)
flamegraph (0.9.5)
fog-aws (3.30.0)
Expand Down Expand Up @@ -1255,6 +1261,7 @@ DEPENDENCIES
escape_utils (~> 1.3)
factory_bot (~> 6.5.0)
factory_bot_rails (~> 6.4.4)
ferrum!
ffi (~> 1.15)
flamegraph
fog-aws
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
end
end
header_container.with_column(flex_layout: true, justify_content: :flex_end) do |actions_container|
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'bulkActionContainer' }) do
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'hideWhenFiltering' }) do
render(Primer::Beta::Button.new(
tag: :a,
href: enable_all_project_settings_life_cycle_steps_path(project_id: project),
Expand All @@ -45,7 +45,7 @@
t('projects.settings.actions.label_enable_all')
end
end
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'bulkActionContainer' }) do
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'hideWhenFiltering' }) do
render(Primer::Beta::Button.new(
tag: :a,
href: disable_all_project_settings_life_cycle_steps_path(project_id: project),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<%=
flex_layout(align_items: :center,
justify_content: :space_between) do |step_container|
step_container.with_column(flex_layout: true) do |title_container|
title_container.with_column(pt: 1, mr: 3) do
step_container.with_column(flex_layout: true, mr: 2, classes: "min-width-0") do |title_container|
title_container.with_column(pt: 1, mr: 3, classes: "ellipsis") do
render(Primer::Beta::Text.new(classes: 'filter-target-visible-text')) { definition.name }
end
title_container.with_column(pt: 1) do
title_container.with_column(pt: 1, classes: "no-wrap") do
render(Projects::LifeCycleTypeComponent.new(definition))
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
end
end
section_header_container.with_column(flex_layout: true, justify_content: :flex_end) do |actions_container|
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'bulkActionContainer' }) do
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'hideWhenFiltering' }) do
render(Primer::Beta::Button.new(
tag: :a,
href: enable_all_of_section_project_settings_project_custom_fields_path(
Expand All @@ -32,7 +32,7 @@
t('projects.settings.actions.label_enable_all')
end
end
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'bulkActionContainer' }) do
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': 'hideWhenFiltering' }) do
render(Primer::Beta::Button.new(
tag: :a,
href: disable_all_of_section_project_settings_project_custom_fields_path(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<%#-- 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.

++#%>

<%= render Primer::OpenProject::PageHeader.new do |header|
header.with_title { t("settings.project_life_cycle_step_definitions.#{heading_scope}.heading") }
header.with_description { t("settings.project_life_cycle_step_definitions.new.description") }
header.with_breadcrumbs(breadcrumbs_items)
end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 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 Settings
module ProjectLifeCycleStepDefinitions
class FormHeaderComponent < ApplicationComponent
options :heading_scope

def breadcrumbs_items
[
{
href: admin_index_path,
text: t("label_administration")
},
{
href: admin_settings_project_custom_fields_path,
text: t("label_project_plural")
},
{
href: admin_settings_project_life_cycle_step_definitions_path,
text: t("settings.project_life_cycle_step_definitions.heading")
},
t("settings.project_life_cycle_step_definitions.#{heading_scope}.heading")
]
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<%#-- 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.

++#%>

<%=
component_wrapper do
flex_layout(data: wrapper_data_attributes) do |flex|
flex.with_row do
if allowed_to_customize_life_cycle?
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_filter_input(
name: "border-box-filter",
label: t("settings.project_life_cycle_step_definitions.filter.label"),
visually_hide_label: true,
placeholder: t("settings.project_life_cycle_step_definitions.filter.label"),
leading_visual: {
icon: :search,
size: :small
},
show_clear_button: true,
data: {
action: "input->projects--settings--border-box-filter#filterLists",
"projects--settings--border-box-filter-target": "filter"
}
)
subheader.with_action_component do
render(Primer::Alpha::ActionMenu.new(
anchor_align: :end)
) do |menu|
menu.with_show_button(
scheme: :primary,
aria: { label: I18n.t("settings.project_life_cycle_step_definitions.label_add_description") },
) do |button|
button.with_leading_visual_icon(icon: :plus)
button.with_trailing_action_icon(icon: :"triangle-down")
I18n.t("settings.project_life_cycle_step_definitions.label_add")
end

menu.with_item(
label: I18n.t("settings.project_life_cycle_step_definitions.label_add_stage"),
href: new_stage_admin_settings_project_life_cycle_step_definitions_path
) do |item|
item.with_leading_visual_icon(icon: "git-commit")
end

menu.with_item(
label: I18n.t("settings.project_life_cycle_step_definitions.label_add_gate"),
href: new_gate_admin_settings_project_life_cycle_step_definitions_path
) do |item|
item.with_leading_visual_icon(icon: "diamond")
end
end
end
end
else
render EnterpriseEdition::BannerComponent.new(:customize_life_cycle, mb: 3)
end
end

flex.with_row do
render(border_box_container(mb: 3, data: drop_target_config)) do |component|
component.with_header(font_weight: :bold, py: 2) do
flex_layout(justify_content: :space_between, align_items: :center) do |header_container|
header_container.with_column do
render(Primer::Beta::Text.new(font_weight: :bold)) do
I18n.t("settings.project_life_cycle_step_definitions.section_header")
end
end
end
end
if definitions.empty?
component.with_row do
render(Primer::Beta::Text.new(color: :subtle)) do
t("settings.project_life_cycle_step_definitions.non_defined")
end
end
else
definitions.each do |definition|
component.with_row(
data: {
"projects--settings--border-box-filter-target": "searchItem",
test_selector: "project-life-cycle-step-definition",
**draggable_item_config(definition)
}
) do
render(Settings::ProjectLifeCycleStepDefinitions::RowComponent.new(
definition,
first?: definition == definitions.first,
last?: definition == definitions.last,
))
end
end
end
end
end
flex.with_row(display: :none, data: { "projects--settings--border-box-filter-target": "noResultsText" }) do
render Primer::Beta::Text.new do
I18n.t("js.autocompleter.notFoundText")
end
end
end
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 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 Settings
module ProjectLifeCycleStepDefinitions
class IndexComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable
include Projects::LifeCycleDefinitionHelper

options :definitions

private

def wrapper_data_attributes
{
controller: "projects--settings--border-box-filter generic-drag-and-drop",
"application-target": "dynamic"
}
end

def drop_target_config
{
"is-drag-and-drop-target": true,
"target-container-accessor": "& > ul",
"target-allowed-drag-type": "life-cycle-step-definition"
}
end

def draggable_item_config(definition)
{
"draggable-type": "life-cycle-step-definition",
"drop-url": drop_admin_settings_project_life_cycle_step_definition_path(definition)
}
end
end
end
end
Loading
Loading