210 lines
6.6 KiB
Ruby
210 lines
6.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Conditions::ConditionsComponent < ApplicationComponent
|
|
include Logic
|
|
|
|
private
|
|
|
|
def rows
|
|
condition_per_row.map { |c| Logic.split_condition(c) }
|
|
end
|
|
|
|
def condition_per_row
|
|
if [And, Or].include?(@condition.class)
|
|
@condition.operands
|
|
else
|
|
[@condition].compact
|
|
end
|
|
end
|
|
|
|
def far_left_tag(row_number)
|
|
if row_number == 0
|
|
t('.display_if')
|
|
elsif row_number == 1
|
|
select_tag(
|
|
"#{input_prefix}[top_operator_name]",
|
|
options_for_select(options_for_far_left_tag, @condition.class.name),
|
|
class: 'fr-select'
|
|
)
|
|
end
|
|
end
|
|
|
|
def options_for_far_left_tag
|
|
[And, Or]
|
|
.map(&:name)
|
|
.map { |name| [t(name, scope: 'logic.operators'), name] }
|
|
end
|
|
|
|
def left_operand_tag(targeted_champ, row_index)
|
|
# current_target can be invalid if
|
|
# - its type has changed : number -> carto
|
|
# - it has been removed
|
|
# - it has been put lower in the form
|
|
current_target_valid = targets_for_select.map(&:second).include?(targeted_champ.to_json)
|
|
|
|
selected_target = current_target_valid ? targeted_champ.to_json : empty.to_json
|
|
|
|
select_tag(
|
|
input_name_for('targeted_champ'),
|
|
options_for_select(targets_for_select, selected_target),
|
|
onchange: "this.form.action = this.form.action + '/change_targeted_champ?row_index=#{row_index}'",
|
|
id: input_id_for('targeted_champ', row_index),
|
|
class: { 'fr-select': true, alert: !current_target_valid }
|
|
)
|
|
end
|
|
|
|
def targets_for_select
|
|
empty_target_for_select + available_targets_for_select
|
|
end
|
|
|
|
def empty_target_for_select
|
|
[[t('.select'), empty.to_json]]
|
|
end
|
|
|
|
def available_targets_for_select
|
|
@source_tdcs
|
|
.filter(&:conditionable?)
|
|
.map { |tdc| [tdc.libelle, champ_value(tdc.stable_id).to_json] }
|
|
end
|
|
|
|
def operator_tag(operator_name, targeted_champ, row_index)
|
|
operators_for_select = compatibles_operators_for_select(targeted_champ)
|
|
|
|
current_operator_invalid = !operators_for_select.map(&:second).include?(operator_name)
|
|
|
|
if current_operator_invalid
|
|
operators_for_select = [[t('.select'), EmptyOperator.name]] + operators_for_select
|
|
end
|
|
|
|
select_tag(
|
|
input_name_for('operator_name'),
|
|
options_for_select(operators_for_select, selected: operator_name),
|
|
id: input_id_for('operator_name', row_index),
|
|
class: { 'fr-select': true, alert: current_operator_invalid }
|
|
)
|
|
end
|
|
|
|
def compatibles_operators_for_select(left)
|
|
case left.type(@source_tdcs)
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:boolean)
|
|
[
|
|
[t('is', scope: 'logic'), Eq.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:empty)
|
|
[
|
|
[t('is', scope: 'logic'), EmptyOperator.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:enum)
|
|
[
|
|
[t('is', scope: 'logic'), Eq.name],
|
|
[t('is_not', scope: 'logic'), NotEq.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:commune_enum), ChampValue::CHAMP_VALUE_TYPE.fetch(:epci_enum), ChampValue::CHAMP_VALUE_TYPE.fetch(:address)
|
|
[
|
|
[t(InDepartementOperator.name, scope: 'logic.operators'), InDepartementOperator.name],
|
|
[t(NotInDepartementOperator.name, scope: 'logic.operators'), NotInDepartementOperator.name],
|
|
[t(InRegionOperator.name, scope: 'logic.operators'), InRegionOperator.name],
|
|
[t(NotInRegionOperator.name, scope: 'logic.operators'), NotInRegionOperator.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:departement_enum)
|
|
[
|
|
[t('is', scope: 'logic'), Eq.name],
|
|
[t('is_not', scope: 'logic'), NotEq.name],
|
|
[t(InRegionOperator.name, scope: 'logic.operators'), InRegionOperator.name],
|
|
[t(NotInRegionOperator.name, scope: 'logic.operators'), NotInRegionOperator.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:enums)
|
|
[
|
|
[t(IncludeOperator.name, scope: 'logic.operators'), IncludeOperator.name],
|
|
[t(ExcludeOperator.name, scope: 'logic.operators'), ExcludeOperator.name]
|
|
]
|
|
when ChampValue::CHAMP_VALUE_TYPE.fetch(:number)
|
|
[Eq, LessThan, GreaterThan, LessThanEq, GreaterThanEq]
|
|
.map(&:name)
|
|
.map { |name| [t(name, scope: 'logic.operators'), name] }
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
|
|
def right_operand_tag(left, right, row_index, operator_name)
|
|
right_invalid = !current_right_valid?(left, right)
|
|
|
|
case left.type(@source_tdcs)
|
|
when :boolean
|
|
booleans_for_select = [[t('utils.yes'), constant(true).to_json], [t('utils.no'), constant(false).to_json]]
|
|
|
|
if right_invalid
|
|
booleans_for_select = empty_target_for_select + booleans_for_select
|
|
end
|
|
|
|
select_tag(
|
|
input_name_for('value'),
|
|
options_for_select(booleans_for_select, right.to_json),
|
|
id: input_id_for('value', row_index),
|
|
class: { 'fr-select': true, alert: right_invalid }
|
|
)
|
|
when :empty
|
|
select_tag(
|
|
input_name_for('value'),
|
|
options_for_select(empty_target_for_select),
|
|
id: input_id_for('value', row_index),
|
|
class: 'fr-select'
|
|
)
|
|
when :enum, :enums, :commune_enum, :epci_enum, :departement_enum, :address
|
|
enums_for_select = left.options(@source_tdcs, operator_name)
|
|
|
|
if right_invalid
|
|
enums_for_select = empty_target_for_select + enums_for_select
|
|
end
|
|
|
|
select_tag(
|
|
input_name_for('value'),
|
|
options_for_select(enums_for_select, right.value),
|
|
id: input_id_for('value', row_index),
|
|
class: { 'fr-select': true, alert: right_invalid }
|
|
)
|
|
when :number
|
|
text_field_tag(
|
|
input_name_for('value'),
|
|
right.value,
|
|
required: true,
|
|
id: input_id_for('value', row_index),
|
|
class: { 'fr-select': true, alert: right_invalid }
|
|
)
|
|
else
|
|
text_field_tag(input_name_for('value'), '', id: input_id_for('value', row_index), class: 'fr-input')
|
|
end
|
|
end
|
|
|
|
def current_right_valid?(left, right)
|
|
Logic.compatible_type?(left, right, @source_tdcs)
|
|
end
|
|
|
|
def add_condition_tag
|
|
tag.button(
|
|
t('.add_condition'),
|
|
formaction: add_condition_path,
|
|
formnovalidate: true,
|
|
class: 'fr-btn fr-btn--secondary fr-btn--sm fr-icon-add-circle-line fr-btn--icon-left'
|
|
)
|
|
end
|
|
|
|
def delete_condition_tag(row_index)
|
|
tag.button(
|
|
class: "fr-btn fr-btn--sm fr-btn--tertiary fr-icon-delete-line",
|
|
title: t('.remove_a_row'),
|
|
formaction: delete_condition_path(row_index),
|
|
formmethod: 'delete',
|
|
formnovalidate: true
|
|
)
|
|
end
|
|
|
|
def render?
|
|
@condition.present? || available_targets_for_select.any?
|
|
end
|
|
|
|
def input_name_for(name)
|
|
"#{input_prefix}[rows][][#{name}]"
|
|
end
|
|
end
|