Merge pull request #18522 from opf/implementation/62709-use-projectlifecyclecomponent-on-project-and-global-administration

Use component for global and project definition administration
This commit is contained in:
Jens Ulferts
2025-04-09 09:57:54 +02:00
committed by GitHub
10 changed files with 62 additions and 109 deletions
@@ -1,8 +0,0 @@
<%= flex_layout(align_items: :center) do |type_container|
type_container.with_column(mr: 1, classes: icon_color_class) do
render Primer::Beta::Octicon.new(icon: icon)
end
type_container.with_column do
render(Primer::Beta::Text.new(**text_options)) { text }
end
end %>
@@ -0,0 +1,15 @@
<%= flex_layout(align_items: :center) do |type_container|
type_container.with_column(classes: icon_color_class, mr: 1) do
render Primer::Beta::Octicon.new(icon: icon)
end
type_container.with_column(test_selector: "project-life-cycle-step-definition-name", classes: "ellipsis") do
if edit_link?
render(Primer::Beta::Link.new(href: phase_href, **phase_text_options)) { phase_text }
else
render(Primer::Beta::Text.new(**phase_text_options)) { phase_text }
end
end
type_container.with_column(ml: 2, classes: "no-wrap") do
render(Primer::Beta::Text.new(**gates_text_options)) { gates_text }
end
end %>
@@ -28,14 +28,18 @@
# See COPYRIGHT and LICENSE files for more details.
# ++
module Projects
class LifeCycleComponent < ApplicationComponent
class PhaseDefinitionComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
# TODO: This component is currently not in use! It should be a shared component
# between the Projects::Settings::LifeCycleSteps::StepComponent and the
# Settings::ProjectLifeCycleStepDefinitions::RowComponent.
# It should hold the icon, definition name and gate text information.
def text
def phase_text
model.name
end
def phase_href
edit_admin_settings_project_phase_definition_path(model)
end
def gates_text
if model.start_gate? && model.finish_gate?
I18n.t("settings.project_phase_definitions.both_gate")
elsif model.start_gate?
@@ -52,14 +56,22 @@ module Projects
end
def icon_color_class
helpers.hl_inline_class("project_phase_definition", model)
helpers.hl_inline_class("project_phase_definition", model.id)
end
def text_options
def gates_text_options
# The tag: :div is is a hack to fix the line height difference
# caused by font_size: :small. That line height difference
# would otherwise lead to the text being not on the same height as the icon
{ color: :muted, font_size: :small, tag: :div }.merge(options)
{ color: :muted, font_size: :small, tag: :div }.merge(options[:gates_text_options] || {})
end
def phase_text_options
{ font_weight: :bold }.merge(options[:phase_text_options] || {})
end
def edit_link?
options[:edit_link]
end
end
end
@@ -3,16 +3,14 @@
align_items: :center,
justify_content: :space_between
) do |step_container|
step_container.with_column(flex_layout: true, mr: 2, classes: "min-width-0") do |title_container|
title_container.with_column(pt: 1, mr: 1, classes: icon_color_class) do
render Primer::Beta::Octicon.new(icon: icon)
end
title_container.with_column(pt: 1, mr: 2, classes: "ellipsis") do
render(Primer::Beta::Text.new(classes: "filter-target-visible-text")) { definition.name }
end
title_container.with_column(pt: 1, classes: "no-wrap") do
render(Primer::Beta::Text.new(**gate_text_options)) { gate_info }
end
step_container.with_column(mr: 2, classes: "min-width-0") do
render(
Projects::PhaseDefinitionComponent.new(
definition,
edit_link: User.current.admin?,
phase_text_options: { classes: "filter-target-visible-text" }
)
)
end
# py: 1 quick fix: prevents the row from bouncing as the toggle switch currently changes height while toggling
step_container.with_column(py: 1, mr: 2) do
@@ -37,32 +37,6 @@ module Projects
options :definition,
:active?
# TODO: Remove these helper methods once the Projects::LifeCycleComponent
# has been refactored.
def icon
:"op-phase"
end
def icon_color_class
helpers.hl_inline_class("project_phase_definition", definition)
end
def gate_info
if definition.start_gate? && definition.finish_gate?
I18n.t("settings.project_phase_definitions.both_gate")
elsif definition.start_gate?
I18n.t("settings.project_phase_definitions.start_gate")
elsif definition.finish_gate?
I18n.t("settings.project_phase_definitions.finish_gate")
else
I18n.t("settings.project_phase_definitions.no_gate")
end
end
def gate_text_options
{ color: :muted, font_size: :small }.merge(options)
end
def toggle_aria_label
I18n.t("projects.settings.life_cycle.step.use_in_project", step: definition.name)
end
@@ -39,28 +39,14 @@ See COPYRIGHT and LICENSE files for more details.
)
end
end
title_container.with_column(classes: icon_color_class) do
render Primer::Beta::Octicon.new(icon: icon)
end
title_container.with_column(classes: "ellipsis", test_selector: "project-life-cycle-step-definition-name") do
render(
if allowed_to_customize_life_cycle?
Primer::Beta::Link.new(
classes: "filter-target-visible-text",
href: edit_admin_settings_project_phase_definition_path(definition),
font_weight: :bold
)
else
Primer::Beta::Text.new(
font_weight: :bold
)
end
) do
definition.name
end
end
title_container.with_column do
render(Primer::Beta::Text.new(**gate_text_options)) { gate_info }
render(
Projects::PhaseDefinitionComponent.new(
definition,
edit_link: allowed_to_customize_life_cycle?,
phase_text_options: { classes: "filter-target-visible-text" }
)
)
end
title_container.with_column(classes: "no-wrap") do
render(Primer::Beta::Text.new) { t("project.count", count: definition.project_count) }
@@ -39,32 +39,6 @@ module Settings
options :first?,
:last?
# TODO: Remove these helper classes once the Projects::LifeCycleComponent
# has been refactored.
def icon
:"op-phase"
end
def icon_color_class
helpers.hl_inline_class("project_phase_definition", definition)
end
def gate_info
if definition.start_gate? && definition.finish_gate?
I18n.t("settings.project_phase_definitions.both_gate")
elsif definition.start_gate?
I18n.t("settings.project_phase_definitions.start_gate")
elsif definition.finish_gate?
I18n.t("settings.project_phase_definitions.finish_gate")
else
I18n.t("settings.project_phase_definitions.no_gate")
end
end
def gate_text_options
{ color: :muted, font_size: :small }.merge(options)
end
private
def move_action(menu:, move_to:, label:, icon:)
@@ -1,6 +0,0 @@
<!-- Depends on having the color defined in the highlighting/styles.css.erb file. -->
<style>
.__hl_inline_life_cycle_step_definition_1 { color: red; }
</style>
<%= render(::Projects::LifeCycleComponent.new(model)) %>
@@ -31,12 +31,14 @@
module OpenProject
module Projects
# @logical_path OpenProject/Projects
class LifeCycleComponentPreview < Lookbook::Preview
class PhaseDefinitionComponentPreview < Lookbook::Preview
# @param edit_link [boolean]
# @param start_gate [boolean]
# @param finish_gate [boolean]
def phase(start_gate: false, finish_gate: false)
def phase(edit_link: false, start_gate: false, finish_gate: false)
model = Project::PhaseDefinition.new(id: 1, name: "The first phase", start_gate:, finish_gate:)
render_with_template(locals: { model: })
render_with_template(locals: { model:, edit_link: })
end
end
end
@@ -0,0 +1,6 @@
<!-- Depends on having the color defined in the highlighting/styles.css.erb file. -->
<style>
.__hl_inline_project_phase_definition_1 { color: red; }
</style>
<%= render(::Projects::PhaseDefinitionComponent.new(model, edit_link:)) %>