Skip to content
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

[#58865] add enterprise banner to new custom field form #17173

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 18 additions & 18 deletions app/helpers/custom_fields_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def custom_field_tag(name, custom_value) # rubocop:disable Metrics/AbcSize,Metri
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
field_id = "#{name}_custom_field_values_#{custom_field.id}"

field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format)
field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format)

tag = case field_format.try(:edit_as)
when "date"
Expand Down Expand Up @@ -146,7 +146,7 @@ def custom_field_tag_with_label(name, custom_value)
def custom_field_tag_for_bulk_edit(name, custom_field, project = nil) # rubocop:disable Metrics/AbcSize
field_name = "#{name}[custom_field_values][#{custom_field.id}]"
field_id = "#{name}_custom_field_values_#{custom_field.id}"
field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format)
field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format)

case field_format.try(:edit_as)
when "date"
Expand Down Expand Up @@ -186,10 +186,7 @@ def show_value(custom_value)

# Return a string used to display a custom value
def format_value(value, custom_field)
custom_value = CustomValue.new(custom_field:,
value:)

custom_value.formatted_value
CustomValue.new(custom_field:, value:).formatted_value
end

# Return an array of custom field formats which can be used in select_tag
Expand All @@ -198,21 +195,24 @@ def custom_field_formats_for_select(custom_field)
format.name == "hierarchy" && !OpenProject::FeatureDecisions.custom_field_of_type_hierarchy_active?
end

OpenProject::CustomFieldFormat
.all_for_field(custom_field)
.sort_by(&:order)
.reject { |format| format.label.nil? }
.reject(&hierarchy_if_deactivated)
.map do |custom_field_format|
[label_for_custom_field_format(custom_field_format.name), custom_field_format.name]
end
OpenProject::CustomFieldFormat.all_for_field(custom_field)
.sort_by(&:order)
.reject { |format| format.label.nil? }
.reject(&hierarchy_if_deactivated)
.map do |custom_field_format|
[label_for_custom_field_format(custom_field_format.name), custom_field_format.name]
end
end

def label_for_custom_field_format(format_string)
format = OpenProject::CustomFieldFormat.find_by_name(format_string)
format = OpenProject::CustomFieldFormat.find_by(name: format_string)
return "" if format.nil?

if format
format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label)
end
label = format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label)

show_enterprise_text = format_string == "hierarchy" && !EnterpriseToken.allows_to?(:custom_field_hierarchies)
suffix = show_enterprise_text ? " (#{I18n.t(:label_enterprise_addon)})" : ""

"#{label}#{suffix}"
end
end
2 changes: 1 addition & 1 deletion app/models/custom_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def value=(val)
def strategy
@strategy ||= begin
format = custom_field&.field_format || "empty"
OpenProject::CustomFieldFormat.find_by_name(format).formatter.new(self) # rubocop:disable Rails/DynamicFindBy
OpenProject::CustomFieldFormat.find_by(name: format).formatter.new(self)
end
end

Expand Down
1 change: 0 additions & 1 deletion app/models/permitted_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ def self.permitted_attributes
:searchable,
:admin_only,
:default_value,
:possible_values,
:multi_value,
:content_right_to_left,
:custom_field_section_id,
Expand Down
1 change: 1 addition & 0 deletions app/services/authorization/enterprise_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Authorization::EnterpriseService
board_view
conditional_highlighting
custom_actions
custom_field_hierarchies
date_alerts
define_custom_style
edit_attribute_groups
Expand Down
5 changes: 5 additions & 0 deletions app/views/admin/settings/project_custom_fields/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ See COPYRIGHT and LICENSE files for more details.

<%= error_messages_for 'custom_field' %>

<% content_controller "admin--custom-fields",
dynamic: true,
'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config
%>

<%= labelled_tabular_form_for @custom_field, as: :custom_field,
url: admin_settings_project_custom_fields_path,
html: { id: 'custom_field_form' } do |f| %>
Expand Down
6 changes: 5 additions & 1 deletion app/views/custom_fields/_custom_options.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,17 @@ See COPYRIGHT and LICENSE files for more details.
>
<td>
<span class="dragula-handle icon icon-table icon-drag-handle"></span>
<%= co_f.hidden_field :id, class: 'custom-option-id' %>
<%= co_f.hidden_field :id,
disabled:true,
class: 'custom-option-id' %>
<%= co_f.text_field :value,
disabled: true,
container_class: 'custom-option-value',
no_label: true %>
</td>
<td>
<%= co_f.check_box :default_value,
disabled: true,
container_class: 'custom-option-default-value',
data: {
'admin--custom-fields-target': 'customOptionDefaults',
Expand Down
14 changes: 11 additions & 3 deletions app/views/custom_fields/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ See COPYRIGHT and LICENSE files for more details.
<section
class="form--section"
id="custom_field_form"
data-controller="admin--custom-fields"
data-application-target="dynamic"
data-admin--custom-fields-format-config-value="<%= OpenProject::CustomFieldFormatDependent.stimulus_config %>"
>
<div class="form--field -required" id="custom_field_name_attributes">
<%= f.text_field :name,
Expand Down Expand Up @@ -62,6 +59,17 @@ See COPYRIGHT and LICENSE files for more details.
}
%>
</div>
<div class="form--field-extra-actions" <%= format_dependent.attributes(:enterpriseBanner) %>>
<%= angular_component_tag "opce-enterprise-banner",
inputs: {
collapsible: true,
opReferrer: "custom-field-hierarchy",
textMessage: "PLACEHOLDER - upgrade to Starkiller Base",
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @Kharonus, here is still a placeholder UI copy in the PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, there is a TASK for Maya, to provide the correct text.

My take was, as this is behind a feature flag, we can merge it even with the placeholder. But before removing the flag, we need to replace it.

moreInfoLink: OpenProject::Static::Links.links[:enterprise_docs][:boards][:href]
}
%>
</div>

<div class="form--grouping" id="custom_field_length" <%= format_dependent.attributes(:length) %>>
<div class="form--grouping-label">
<%= t(:label_min_max_length) %> <br>
Expand Down
5 changes: 5 additions & 0 deletions app/views/custom_fields/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ See COPYRIGHT and LICENSE files for more details.

<%= error_messages_for 'custom_field' %>

<% content_controller "admin--custom-fields",
dynamic: true,
'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config
%>

<% if @custom_field.field_format_hierarchy? %>
<%= render CustomFields::DetailsComponent.new(@custom_field) %>
<% else %>
Expand Down
12 changes: 11 additions & 1 deletion app/views/custom_fields/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,20 @@ See COPYRIGHT and LICENSE files for more details.

<%= error_messages_for 'custom_field' %>

<% content_controller "admin--custom-fields",
dynamic: true,
'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config,
'admin--custom-fields-enterprise-edition-value': EnterpriseToken.allows_to?(:custom_field_hierarchies)
%>

<%= labelled_tabular_form_for @custom_field, as: :custom_field,
url: custom_fields_path,
html: {id: 'custom_field_form', class: "-wide-labels"} do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<%= hidden_field_tag 'type', @custom_field.type %>
<%= styled_button_tag t(:button_save), class: '-primary -with-icon icon-checkmark' %>
<%= styled_button_tag t(:button_save),
class: '-primary -with-icon icon-checkmark',
data: {
'admin--custom-fields-target': 'submitButton'
} %>
<% end %>
1 change: 1 addition & 0 deletions config/initializers/custom_field_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@

fields.register OpenProject::CustomFieldFormat.new("hierarchy",
label: :label_hierarchy,
only: %w(WorkPackage),
order: 12,
formatter: "CustomValue::HierarchyStrategy")
end
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default class CustomFieldsController extends Controller {
static targets = [
'format',
'dragContainer',
'submitButton',

'customOptionDefaults',
'customOptionRow',
Expand All @@ -48,17 +49,23 @@ export default class CustomFieldsController extends Controller {
'regexp',
'searchable',
'textOrientation',

'enterpriseBanner',
];

static values = {
formatConfig: Array,
enterpriseEdition: Boolean,
};

declare readonly formatConfigValue:[string, string, string[]][];
declare readonly enterpriseEditionValue:boolean;

declare readonly formatTarget:HTMLInputElement;
declare readonly dragContainerTarget:HTMLElement;
declare readonly hasDragContainerTarget:boolean;
declare readonly submitButtonTarget:HTMLButtonElement;
declare readonly hasSubmitButtonTarget:boolean;

declare readonly customOptionDefaultsTargets:HTMLInputElement[];
declare readonly customOptionRowTargets:HTMLTableRowElement[];
Expand All @@ -74,6 +81,8 @@ export default class CustomFieldsController extends Controller {
declare readonly searchableTargets:HTMLInputElement[];
declare readonly textOrientationTargets:HTMLElement[];

declare readonly enterpriseBannerTarget:HTMLElement;

connect() {
if (this.hasDragContainerTarget) {
this.setupDragAndDrop();
Expand Down Expand Up @@ -242,8 +251,16 @@ export default class CustomFieldsController extends Controller {
}

private toggleFormat(format:string) {
if (this.hasSubmitButtonTarget) {
this.submitButtonTarget.disabled = format === 'hierarchy' && !this.enterpriseEditionValue;
}

this.formatConfigValue.forEach(([targetsName, operator, formats]) => {
const active = operator === 'only' ? formats.includes(format) : !formats.includes(format);
let active = operator === 'only' ? formats.includes(format) : !formats.includes(format);
if (targetsName === 'enterpriseBanner' && this.enterpriseEditionValue) {
active = false;
}

const targets = this[`${targetsName}Targets` as keyof typeof this] as HTMLElement[];
if (targets) {
this.setActive(targets, active);
Expand Down
5 changes: 4 additions & 1 deletion lib/custom_field_form_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ def cf_form_field(options = {})

private

# rubocop:disable Metrics/AbcSize
def custom_field_input(options = {})
field = custom_field.attribute_name

input_options = options.merge(no_label: true,
name: custom_field_field_name,
id: custom_field_field_id)

field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format)
field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format)

case field_format.try(:edit_as)
when "date"
Expand All @@ -80,6 +81,8 @@ def custom_field_input(options = {})
end
end

# rubocop:enable Metrics/AbcSize

def custom_field_input_list(field, input_options)
customized = Array(custom_value).first&.customized
possible_options = custom_field.possible_values_options(customized)
Expand Down
2 changes: 1 addition & 1 deletion lib/open_project/custom_field_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def available_formats
@@available.keys
end

def find_by_name(name)
def find_by(name:)
@@available[name.to_s]
end

Expand Down
3 changes: 2 additions & 1 deletion lib/open_project/custom_field_format_dependent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class CustomFieldFormatDependent
possibleValues: [:only, %w[list]],
regexp: [:except, %w[list bool date user version hierarchy]],
searchable: [:except, %w[bool date float int user version]],
textOrientation: [:only, %w[text]]
textOrientation: [:only, %w[text]],
enterpriseBanner: [:only, %w[hierarchy]]
}.freeze

def self.stimulus_config
Expand Down
19 changes: 10 additions & 9 deletions spec/features/admin/custom_fields/user_custom_field_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
RSpec.describe "User custom fields edit", :js, :with_cuprite do
shared_let(:admin) { create(:admin) }
let(:cf_page) { Pages::CustomFields::IndexPage.new }
let(:new_cf_page) { Pages::CustomFields::NewPage.new }

before do
login_as(admin)
Expand All @@ -39,30 +40,30 @@

it "can create and edit user custom fields (#48725)" do
# Create CF
click_link "Create a new custom field"
click_on "New custom field"
new_cf_page.expect_current_path

wait_for_reload

fill_in "custom_field_name", with: "My User CF"
select "User", from: "custom_field_field_format"
fill_in "Name", with: "My User CF"
select "User", from: "Format"

expect(page).to have_no_field("custom_field_custom_options_attributes_0_value")

click_on "Save"

# Expect field to be created
cf = CustomField.last
expect(cf.name).to eq("My User CF")
cf_page.expect_current_path("tab=WorkPackageCustomField")
expect(page).to have_list_item("My User CF")

# Edit again
find("a", text: "My User CF").click
click_on "My User CF"

expect(page).to have_no_field("custom_field_custom_options_attributes_0_value")
fill_in "custom_field_name", with: "My User CF (edited)"
fill_in "Name", with: "My User CF (edited)"

click_on "Save"

# Expect field to be saved
expect(page).to have_css(".PageHeader-title", text: "My User CF (edited)")
cf = CustomField.last
expect(cf.name).to eq("My User CF (edited)")
end
Expand Down
8 changes: 6 additions & 2 deletions spec/features/custom_fields/hierarchy_custom_field_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,18 @@
require "spec_helper"

RSpec.describe "custom fields of type hierarchy", :js, :with_cuprite do
let(:user) { create(:admin) }
let(:admin) { create(:admin) }
let(:custom_field_index_page) { Pages::CustomFields::IndexPage.new }
let(:new_custom_field_page) { Pages::CustomFields::NewPage.new }
let(:hierarchy_page) { Pages::CustomFields::HierarchyPage.new }

before do
allow(EnterpriseToken).to receive(:allows_to?).and_return(true)
end

it "lets you create, update and delete a custom field of type hierarchy",
with_flag: { custom_field_of_type_hierarchy: true } do
login_as user
login_as admin

# region CustomField creation

Expand Down
Loading