mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
remove old implementation of editing project attributes in the sidebar
This commit is contained in:
@@ -1,3 +1,2 @@
|
||||
@import "./overviews/project_custom_fields/show_component.sass"
|
||||
@import "./overviews/project_phases/item_component.sass"
|
||||
@import "./overviews/overview_grid_component.sass"
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
<%=
|
||||
render(
|
||||
Primer::Alpha::Dialog.new(
|
||||
title: dialog_title,
|
||||
classes: "Overlay--size-large-portrait",
|
||||
size: :large,
|
||||
id: dialog_id
|
||||
)
|
||||
) do |d|
|
||||
d.with_header(variant: :large)
|
||||
d.with_body(classes: "Overlay-body_autocomplete_height") do
|
||||
render(body_component)
|
||||
end
|
||||
d.with_footer do
|
||||
component_collection do |footer_collection|
|
||||
footer_collection.with_component(
|
||||
Primer::Beta::Button.new(
|
||||
data: {
|
||||
"close-dialog-id": dialog_id
|
||||
}
|
||||
)
|
||||
) do
|
||||
close_button_title
|
||||
end
|
||||
|
||||
footer_buttons(footer_collection)
|
||||
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.
|
||||
#++
|
||||
|
||||
module Overviews
|
||||
module ProjectCustomFields
|
||||
class DialogComponent < ApplicationComponent
|
||||
include ApplicationHelper
|
||||
include OpTurbo::Streamable
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
def initialize(project:, project_custom_field:)
|
||||
super
|
||||
@project = project
|
||||
@project_custom_field = project_custom_field
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dialog_title
|
||||
@project_custom_field.project_custom_field_section.name
|
||||
end
|
||||
|
||||
def dialog_id
|
||||
"project-custom-field-dialog-#{@project_custom_field.id}"
|
||||
end
|
||||
|
||||
def wrapper_id
|
||||
"##{dialog_id}"
|
||||
end
|
||||
|
||||
def body_component
|
||||
fail NoMethodError, "Must be overridden in subclass"
|
||||
end
|
||||
|
||||
def close_button_title
|
||||
fail NoMethodError, "Must be overridden in subclass"
|
||||
end
|
||||
|
||||
def footer_buttons(footer_collection)
|
||||
# noop
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
<%= helpers.angular_component_tag "opce-custom-modal-overlay" %>
|
||||
<%=
|
||||
component_wrapper do
|
||||
primer_form_with(
|
||||
id: "project-custom-field-edit-form",
|
||||
model: @project,
|
||||
method: :put,
|
||||
data: { turbo: true, turbo_stream: true, "test-selector": "async-dialog-content" },
|
||||
url: project_custom_field_path(project_id: @project.id, id: @project_custom_field.id)
|
||||
) do |f|
|
||||
if @project_custom_field.hierarchical_list?
|
||||
form_field_name = "project[custom_field_values][]"
|
||||
concat(
|
||||
render_inline_form(f) do |hidden_form|
|
||||
hidden_form.hidden(name: form_field_name, value: "", scope_name_to_model: false)
|
||||
end
|
||||
)
|
||||
|
||||
concat(
|
||||
render(
|
||||
Primer::OpenProject::FilterableTreeView.new(
|
||||
form_arguments: { builder: f, name: "custom_field_values" },
|
||||
include_sub_items_check_box_arguments: { hidden: true },
|
||||
filter_mode_control_arguments: { hidden: true }
|
||||
)
|
||||
) do |tree_view|
|
||||
current_values = Array(@project.custom_value_for(@project_custom_field)).map(&:value)
|
||||
checked_fn = lambda { |item| current_values.include?(item.id.to_s) }
|
||||
item_formatter = standard_tree_view_item_formatter
|
||||
label_fn = lambda { |item| item_formatter.format(item:) }
|
||||
|
||||
item_options = {
|
||||
expanded_fn: ->(*) { true },
|
||||
label_fn:,
|
||||
checked_fn:,
|
||||
select_variant: @project_custom_field.multi_value? ? :multiple : :single
|
||||
}
|
||||
|
||||
populate_tree_view(tree_view, @project_custom_field, item_options:)
|
||||
end
|
||||
)
|
||||
|
||||
if @project_custom_field.has_comment?
|
||||
concat(
|
||||
f.fields_for(:custom_comments) do |builder|
|
||||
render(
|
||||
CustomFields::CommentField.new(
|
||||
builder,
|
||||
custom_field: @project_custom_field,
|
||||
object: @project
|
||||
)
|
||||
)
|
||||
end
|
||||
)
|
||||
end
|
||||
else
|
||||
render(
|
||||
Projects::CustomFields::Form.new(
|
||||
f,
|
||||
project: @project,
|
||||
custom_field: @project_custom_field,
|
||||
wrapper_id:
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
%>
|
||||
@@ -1,53 +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 Overviews
|
||||
module ProjectCustomFields
|
||||
class EditComponent < ApplicationComponent
|
||||
include ApplicationHelper
|
||||
include OpTurbo::Streamable
|
||||
include OpPrimer::ComponentHelpers
|
||||
include CustomFieldHierarchyTreeViewHelper
|
||||
|
||||
attr_reader :wrapper_id
|
||||
|
||||
def initialize(project:, project_custom_field:, wrapper_id: nil)
|
||||
super
|
||||
@project = project
|
||||
@project_custom_field = project_custom_field
|
||||
@wrapper_id = wrapper_id
|
||||
end
|
||||
|
||||
def wrapper_uniq_by
|
||||
@project_custom_field.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-65
@@ -1,65 +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 Overviews
|
||||
module ProjectCustomFields
|
||||
class EditDialogComponent < DialogComponent
|
||||
private
|
||||
|
||||
def body_component
|
||||
Overviews::ProjectCustomFields::EditComponent.new(
|
||||
project_custom_field: @project_custom_field,
|
||||
project: @project,
|
||||
wrapper_id:
|
||||
)
|
||||
end
|
||||
|
||||
def close_button_title
|
||||
t("button_cancel")
|
||||
end
|
||||
|
||||
def footer_buttons(footer_collection)
|
||||
footer_collection.with_component(
|
||||
Primer::Beta::Button.new(
|
||||
scheme: :primary,
|
||||
type: :submit,
|
||||
form: "project-custom-field-edit-form",
|
||||
data: {
|
||||
test_selector: "save-project-attributes-button",
|
||||
turbo: true
|
||||
}
|
||||
)
|
||||
) do
|
||||
t("button_save")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -36,75 +36,6 @@ module Overviews
|
||||
def limited_space?
|
||||
@project_custom_field.field_format == "text" &&
|
||||
@project_custom_field.project_custom_field_section&.shown_in_overview_sidebar?
|
||||
|
||||
end
|
||||
|
||||
def show_comment? = false
|
||||
|
||||
def value_wrapper_attributes
|
||||
if allowed_to_edit?
|
||||
if calculated_value? && !has_comment?
|
||||
non_editable_wrapper(id: calculated_value_tooltip_id)
|
||||
else
|
||||
modal_wrapper
|
||||
end
|
||||
elsif has_comment?
|
||||
modal_wrapper
|
||||
else
|
||||
non_editable_wrapper
|
||||
end
|
||||
end
|
||||
|
||||
def allowed_to_edit?
|
||||
User.current.allowed_in_project?(:edit_project_attributes, @project)
|
||||
end
|
||||
|
||||
def modal_wrapper
|
||||
action_label_key = allowed_to_edit? ? :label_edit_x : :label_view_x
|
||||
|
||||
url = if allowed_to_edit?
|
||||
edit_project_custom_field_path(project_id: @project, id: @project_custom_field)
|
||||
else
|
||||
project_custom_field_path(project_id: @project, id: @project_custom_field)
|
||||
end
|
||||
|
||||
{
|
||||
tag: :div,
|
||||
classes: "project-custom-field-clickable",
|
||||
data: {
|
||||
controller: "project-custom-field-modal async-dialog",
|
||||
"project-custom-field-modal-url-value": url,
|
||||
action: "click->project-custom-field-modal#open " \
|
||||
"keydown.enter->project-custom-field-modal#open " \
|
||||
"keydown.space->project-custom-field-modal#open " \
|
||||
"project-custom-field-modal:open-dialog->async-dialog#handleOpenDialog"
|
||||
},
|
||||
aria: {
|
||||
label: [
|
||||
I18n.t(action_label_key, x: @project_custom_field.name),
|
||||
I18n.t(:label_value_x, x: accessible_value_text)
|
||||
].join(", ")
|
||||
},
|
||||
role: "button",
|
||||
tabindex: 0,
|
||||
test_selector: "project-custom-field-modal-button-#{@project_custom_field.id}"
|
||||
}
|
||||
end
|
||||
|
||||
def non_editable_wrapper(**)
|
||||
{
|
||||
tag: :div,
|
||||
classes: "project-custom-field-non-editable",
|
||||
aria: {
|
||||
disabled: true,
|
||||
label: [
|
||||
@project_custom_field.name,
|
||||
I18n.t(:label_value_x, x: accessible_value_text)
|
||||
].join(", ")
|
||||
},
|
||||
tabindex: 0,
|
||||
**
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-1
@@ -5,7 +5,6 @@
|
||||
render(
|
||||
Overviews::ProjectCustomFields::ItemComponent.new(
|
||||
project_custom_field:,
|
||||
project_custom_field_values: attribute_load_service.get_eager_loaded_project_custom_field_values_for(project_custom_field.id),
|
||||
project: @project
|
||||
)
|
||||
)
|
||||
|
||||
@@ -40,11 +40,6 @@ module Overviews
|
||||
@project_custom_fields = project_custom_fields
|
||||
@project = project
|
||||
end
|
||||
|
||||
def attribute_load_service
|
||||
@attribute_load_service ||= ::ProjectCustomFields::LoadService.new(project: @project,
|
||||
project_custom_fields: @project_custom_fields)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+5
-72
@@ -1,73 +1,6 @@
|
||||
<%= render OpenProject::Common::InplaceEditFieldComponent.new(
|
||||
model: @project,
|
||||
attribute: @project_custom_field.attribute_name.to_sym,
|
||||
open_in_dialog: limited_space?,
|
||||
truncated: limited_space?
|
||||
) %>
|
||||
|
||||
<!--
|
||||
<%# if show_special_field? %>
|
||||
<%#=
|
||||
flex_layout(
|
||||
align_items: :flex_start,
|
||||
justify_content: :space_between,
|
||||
classes: "op-project-custom-field-container",
|
||||
data: {
|
||||
test_selector: "project-custom-field-#{@project_custom_field.id}"
|
||||
}
|
||||
) do |custom_field_value_container|
|
||||
# temporarily using inline styles in order to align the content as desired
|
||||
custom_field_value_container.with_row(mb: 1) do
|
||||
render OpenProject::Common::AttributeLabelComponent.new(
|
||||
attribute: @project_custom_field.attribute_name,
|
||||
model: @project,
|
||||
required: required?
|
||||
) do
|
||||
render(Primer::Beta::Text.new(font_weight: :bold)) { @project_custom_field.name }
|
||||
end
|
||||
end
|
||||
|
||||
custom_field_value_container.with_row(w: :full) do
|
||||
render(authorized_edit_wrapper) do
|
||||
if not_set?
|
||||
render(Primer::Beta::Text.new) { t("placeholders.default") }
|
||||
else
|
||||
render_value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
custom_field_value_container.with_row(w: :full) do
|
||||
render OpenProject::Common::AttributeHelpTextCaptionComponent.new(
|
||||
help_text: helpers.help_text_for(
|
||||
@project,
|
||||
@project_custom_field.attribute_name,
|
||||
current_user: helpers.current_user
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
if calculation_error?
|
||||
custom_field_value_container.with_row(w: :full) do
|
||||
render_calculation_error
|
||||
end
|
||||
end
|
||||
|
||||
if show_comment?
|
||||
custom_field_value_container.with_row(w: :full, mt: 1) do
|
||||
render Primer::Alpha::TextArea.new(
|
||||
name: :custom_comment,
|
||||
label: I18n.t("attributes.comment"),
|
||||
value: @project_custom_field.comment_for(@project)&.text,
|
||||
rows: 5,
|
||||
readonly: true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
%>
|
||||
|
||||
<%#= render_calculated_value_tooltip if calculated_value? %>
|
||||
<%# else %>-->
|
||||
|
||||
<%# end %>
|
||||
model: @project,
|
||||
attribute: @project_custom_field.attribute_name.to_sym,
|
||||
open_in_dialog: limited_space?,
|
||||
truncated: limited_space?
|
||||
) %>
|
||||
|
||||
+3
-125
@@ -31,139 +31,17 @@
|
||||
module Overviews
|
||||
module ProjectCustomFields
|
||||
class ShowComponent < ApplicationComponent
|
||||
include ApplicationHelper
|
||||
include CalculatedValues::ErrorsHelper
|
||||
include CustomFieldsHelper
|
||||
include OpPrimer::ComponentHelpers
|
||||
|
||||
delegate :has_comment?, :calculated_value?, to: :@project_custom_field
|
||||
|
||||
def initialize(project_custom_field:, project_custom_field_values:, project:)
|
||||
def initialize(project_custom_field:, project:)
|
||||
super
|
||||
|
||||
@project_custom_field = project_custom_field
|
||||
@project_custom_field_values = Array(project_custom_field_values)
|
||||
@project = project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def show_comment? = @project_custom_field.has_comment?
|
||||
|
||||
def value_wrapper_attributes = {}
|
||||
|
||||
def value_wrapper
|
||||
Primer::Beta::Text.new(**value_wrapper_attributes)
|
||||
end
|
||||
|
||||
def required?
|
||||
@project_custom_field.required? && !@project_custom_field.calculated_value?
|
||||
end
|
||||
|
||||
def not_set?
|
||||
@project_custom_field_values.none?(&:value?)
|
||||
end
|
||||
|
||||
def calculation_error?
|
||||
@project_custom_field.first_calculation_error(@project).present?
|
||||
end
|
||||
|
||||
def render_calculation_error
|
||||
error = @project_custom_field.first_calculation_error(@project)
|
||||
|
||||
render(Primer::OpenProject::FlexLayout.new(align_items: :flex_start,
|
||||
data: {
|
||||
test_selector: "error-cf-#{@project_custom_field.id}"
|
||||
})) do |container|
|
||||
container.with_column do
|
||||
render Primer::Beta::Octicon.new(icon: :"alert-fill", color: :danger)
|
||||
end
|
||||
container.with_column(ml: 2) do
|
||||
render Primer::Beta::Text.new(color: :danger) do
|
||||
calculated_value_error_msg(error)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_calculated_value_tooltip
|
||||
render Primer::Alpha::Tooltip.new(
|
||||
for_id: calculated_value_tooltip_id,
|
||||
type: :description,
|
||||
text: I18n.t("custom_fields.calculated_field_not_editable"),
|
||||
direction: :s
|
||||
)
|
||||
end
|
||||
|
||||
def calculated_value_tooltip_id
|
||||
calculated_value? ? "calculated-field-tooltip-#{@project_custom_field.id}" : nil
|
||||
end
|
||||
|
||||
def render_value
|
||||
case @project_custom_field.field_format
|
||||
when "link"
|
||||
render_link
|
||||
when "text"
|
||||
render_long_text
|
||||
when "user"
|
||||
render_user
|
||||
else
|
||||
render_custom_field_values
|
||||
end
|
||||
end
|
||||
|
||||
def render_long_text
|
||||
render OpenProject::Common::AttributeComponent.new("dialog-cf-#{@project_custom_field.id}",
|
||||
@project_custom_field.name,
|
||||
@project_custom_field_values.first&.value,
|
||||
lines: 3)
|
||||
end
|
||||
|
||||
def render_user
|
||||
if @project_custom_field.multi_value?
|
||||
flex_layout do |avatar_container|
|
||||
@project_custom_field_values.each do |cf_value|
|
||||
avatar_container.with_row do
|
||||
render_avatar(cf_value.typed_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
render_avatar(@project_custom_field_values.first&.typed_value)
|
||||
end
|
||||
end
|
||||
|
||||
def render_avatar(user)
|
||||
render(Users::AvatarComponent.new(user:, size: :mini))
|
||||
end
|
||||
|
||||
def render_link
|
||||
href = @project_custom_field_values.first&.value
|
||||
link = Addressable::URI.parse(href)
|
||||
return href unless link
|
||||
|
||||
target = link.host == Setting.host_without_protocol ? "_top" : "_blank"
|
||||
render(Primer::Beta::Link.new(href:, rel: "noopener noreferrer", target:)) do
|
||||
href
|
||||
end
|
||||
end
|
||||
|
||||
def render_custom_field_values
|
||||
render(Primer::Beta::Text.new) { custom_field_values }
|
||||
end
|
||||
|
||||
def accessible_value_text
|
||||
return I18n.t("placeholders.default") if not_set?
|
||||
|
||||
custom_field_values
|
||||
end
|
||||
|
||||
def custom_field_values
|
||||
return @custom_field_values if defined?(@custom_field_values)
|
||||
|
||||
values = @project_custom_field_values.map { |v| format_value(v.value, @project_custom_field) }
|
||||
|
||||
@custom_field_values = @project_custom_field.multi_value? ? values.join(", ") : values.first
|
||||
def limited_space?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
.project-custom-fields-rich-text-preview
|
||||
:last-child
|
||||
display: inline
|
||||
|
||||
// Style non-editable fields to match hover-input dimensions
|
||||
.project-custom-field-non-editable
|
||||
@include hover-input-base
|
||||
min-height: 1.2em // Ensure consistent height even when empty
|
||||
|
||||
@media (hover: none) and (pointer: coarse)
|
||||
background-color: var(--bgColor-disabled)
|
||||
color: var(--fgColor-disabled)
|
||||
@media (hover: hover)
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--bgColor-disabled)
|
||||
color: var(--fgColor-disabled)
|
||||
|
||||
// Style clickable fields
|
||||
.project-custom-field-clickable
|
||||
@include hover-input-base
|
||||
cursor: pointer
|
||||
min-height: 1.2em
|
||||
-49
@@ -1,49 +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 Overviews
|
||||
module ProjectCustomFields
|
||||
class ShowDialogComponent < DialogComponent
|
||||
private
|
||||
|
||||
def body_component
|
||||
Overviews::ProjectCustomFields::ShowComponent.new(
|
||||
project_custom_field: @project_custom_field,
|
||||
project_custom_field_values: @project.custom_values_for_custom_field(@project_custom_field),
|
||||
project: @project
|
||||
)
|
||||
end
|
||||
|
||||
def close_button_title
|
||||
t("button_close")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,124 +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 Overviews::ProjectCustomFieldsController < ApplicationController
|
||||
include OpTurbo::ComponentStream
|
||||
|
||||
before_action :find_project_by_project_id
|
||||
before_action :find_project_custom_field
|
||||
before_action :authorize
|
||||
|
||||
def show
|
||||
respond_with_dialog(
|
||||
Overviews::ProjectCustomFields::ShowDialogComponent.new(
|
||||
project: @project,
|
||||
project_custom_field: @custom_field
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def edit
|
||||
respond_with_dialog(
|
||||
Overviews::ProjectCustomFields::EditDialogComponent.new(
|
||||
project: @project,
|
||||
project_custom_field: @custom_field
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def update
|
||||
# FIXME: submitted format of form parameters are not configurable for the tree view component. Hence, we
|
||||
# need to process it before giving them in standard format to the update service.
|
||||
if @custom_field.hierarchical_list?
|
||||
process_hierarchy_params
|
||||
end
|
||||
|
||||
service_call = ::Projects::UpdateService
|
||||
.new(
|
||||
user: current_user,
|
||||
model: @project,
|
||||
contract_options: { project_attributes_only: true }
|
||||
)
|
||||
.call(permitted_params.project)
|
||||
|
||||
if service_call.success?
|
||||
if field_shown_in_sidebar?(@custom_field)
|
||||
update_sidebar_component
|
||||
else
|
||||
update_widgets_component
|
||||
end
|
||||
else
|
||||
handle_errors(service_call.result, @custom_field)
|
||||
end
|
||||
|
||||
respond_to_with_turbo_streams(status: service_call.success? ? :ok : :unprocessable_entity)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_hierarchy_params
|
||||
values = params.dig(:project, :custom_field_values)
|
||||
|
||||
ids = Array(values).reject(&:empty?).map do |value|
|
||||
MultiJson.load(value, symbolize_keys: true)[:value]
|
||||
end
|
||||
|
||||
params[:project][:custom_field_values] = { @custom_field.id.to_s => ids.one? ? ids.first : ids }
|
||||
end
|
||||
|
||||
def find_project_custom_field
|
||||
@custom_field = @project.available_custom_fields.find(params[:id])
|
||||
end
|
||||
|
||||
def handle_errors(project_with_errors, custom_field)
|
||||
update_via_turbo_stream(
|
||||
component: Overviews::ProjectCustomFields::EditComponent.new(
|
||||
project: project_with_errors,
|
||||
project_custom_field: custom_field
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def update_sidebar_component
|
||||
update_via_turbo_stream(
|
||||
component: Overviews::ProjectCustomFields::SidePanelComponent.new(project: @project)
|
||||
)
|
||||
end
|
||||
|
||||
def update_widgets_component
|
||||
update_via_turbo_stream(
|
||||
component: Grids::ProjectAttributeWidgets.new(@project)
|
||||
)
|
||||
end
|
||||
|
||||
def field_shown_in_sidebar?(custom_field)
|
||||
CustomFieldSection.find(custom_field.custom_field_section_id).shown_in_overview_sidebar?
|
||||
end
|
||||
end
|
||||
@@ -12,8 +12,6 @@ Rails.application.routes.draw do
|
||||
get "project_custom_fields_sidebar" => :project_custom_fields_sidebar, as: :custom_fields_sidebar
|
||||
get "project_life_cycle_sidebar" => :project_life_cycle_sidebar, as: :life_cycle_sidebar
|
||||
end
|
||||
|
||||
resources :project_custom_fields, only: %i[show edit update], as: :custom_fields
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,117 +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 "rails_helper"
|
||||
|
||||
RSpec.describe Overviews::ProjectCustomFieldsController do
|
||||
describe "routing" do
|
||||
describe "#show" do
|
||||
it do
|
||||
expect(get("/projects/my-project/project_custom_fields/33"))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "show",
|
||||
project_id: "my-project",
|
||||
id: "33"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#edit" do
|
||||
it do
|
||||
expect(get("/projects/my-project/project_custom_fields/33/edit"))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "edit",
|
||||
project_id: "my-project",
|
||||
id: "33"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT/PATCH #update" do
|
||||
it do
|
||||
expect(put("/projects/my-project/project_custom_fields/44"))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "update",
|
||||
project_id: "my-project",
|
||||
id: "44"
|
||||
)
|
||||
end
|
||||
|
||||
it do
|
||||
expect(patch("/projects/my-project/project_custom_fields/44"))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "update",
|
||||
project_id: "my-project",
|
||||
id: "44"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "named routing" do
|
||||
describe "GET #edit" do
|
||||
it do
|
||||
expect(get(edit_project_custom_field_path("my-project", 33)))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "edit",
|
||||
project_id: "my-project",
|
||||
id: "33"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT/PATCH #update" do
|
||||
it do
|
||||
expect(put(project_custom_field_path("my-project", 44)))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "update",
|
||||
project_id: "my-project",
|
||||
id: "44"
|
||||
)
|
||||
end
|
||||
|
||||
it do
|
||||
expect(patch("/projects/my-project/project_custom_fields/44"))
|
||||
.to route_to(
|
||||
controller: "overviews/project_custom_fields",
|
||||
action: "update",
|
||||
project_id: "my-project",
|
||||
id: "44"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user