Skip to content
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
Original file line numberDiff line numberDiff line change
Expand Up@@ -30,8 +30,7 @@ def self.build_schema(collection, name)
slug = get_action_slug(name)

form_elements = extract_fields_and_layout(collection.get_form(nil, name))
if action.static_form? && form_elements[:layout].empty?
# if action.static_form?
if action.static_form?
fields = build_fields(collection, form_elements[:fields])
layout = form_elements[:layout]
else
Expand All@@ -58,12 +57,20 @@ def self.build_schema(collection, name)

return schema unless layout && !layout.empty?

schema[:layout] = build_layout(layout)
# schema[:layout] = build_layout(layout)

schema
end

def self.build_layout_schema(field)
if field.component == 'Row'
return {
**field.to_h,
component: field.component.camelize(:lower),
fields: field.fields.map { |f| build_layout_schema(f) }
}
end

{ **field.to_h, component: field.component.camelize(:lower) }
end

Expand DownExpand Up@@ -101,7 +108,7 @@ def self.build_fields(collection, fields)
if fields
return fields.map do |field|
new_field = build_field_schema(collection.datasource, field)
new_field[:default_value] = new_field[:value]
new_field[:defaultValue] = new_field[:value]
new_field.delete(:value)

new_field
Expand All@@ -112,7 +119,7 @@ def self.build_fields(collection, fields)
end

def self.build_layout(elements)
if elements
if elements.any? { |element| element.component != 'Input' }
return elements.map do |element|
build_layout_schema(element)
end
Expand All@@ -124,21 +131,25 @@ def self.build_layout(elements)
def self.extract_fields_and_layout(form)
fields = []
layout = []
has_real_layout = false

form&.each do |element|
if element.type == Actions::FieldType::LAYOUT
layout << element
has_real_layout = true
if element.component == 'Row'
extract = extract_fields_and_layout(element.fields)
element.fields = extract[:layout]
layout << element
fields.concat(extract[:fields])
else
layout << element
end

else
fields << element
# frontend rule
layout << Actions::ActionLayoutElement::InputElement.new(component: 'Input', field_id: element.label)
end
end

layout = [] unless has_real_layout

{ fields: fields, layout: layout }
end
end
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,7 @@ module Schema
httpMethod: 'POST',
redirect: nil,
download: false,
fields: [{ description: 'email', isRequired: true, isReadOnly: false, field: 'label', widgetEdit: nil, type: 'String', default_value: '' }],
fields: [{ description: 'email', isRequired: true, isReadOnly: false, field: 'label', widgetEdit: nil, type: 'String', defaultValue: '' }],
hooks: { load: false, change: ['changeHook'] }
}
)
Expand DownExpand Up@@ -234,31 +234,15 @@ module Schema
download: false,
fields: [
{
defaultValue: 'Form is loading',
description: '',
enums: nil,
field: 'Loading...',
hook: nil,
isReadOnly: true,
defaultValue: nil,
description: nil,
field: 'label',
isReadOnly: false,
isRequired: false,
reference: nil,
type: 'String',
value: nil,
widgetEdit: nil
}
],
# uncomment when back validations will be done ...
# fields: [
# {
# default_value: nil,
# description: nil,
# field: 'label',
# isReadOnly: false,
# isRequired: false,
# type: 'String',
# widgetEdit: nil
# }
# ],
# layout: [
# { component: 'input', fieldId: 'label', type: 'Layout' },
# { component: 'separator', type: 'Layout' }
Expand DownExpand Up@@ -301,31 +285,15 @@ module Schema
download: false,
fields: [
{
defaultValue: 'Form is loading',
description: '',
enums: nil,
field: 'Loading...',
hook: nil,
isReadOnly: true,
defaultValue: nil,
description: nil,
field: 'label',
isReadOnly: false,
isRequired: false,
reference: nil,
type: 'String',
value: nil,
widgetEdit: nil
}
],
# uncomment when back validations will be done ...
# fields: [
# {
# default_value: nil,
# description: nil,
# field: 'label',
# isReadOnly: false,
# isRequired: false,
# type: 'String',
# widgetEdit: nil
# }
# ],
# layout: [
# { component: 'input', fieldId: 'label', type: 'Layout' },
# { component: 'htmlBlock', type: 'Layout', content: '<p>foo</p>' }
Expand All@@ -336,6 +304,69 @@ module Schema
end
end

context 'with row element' do
before do
@collection = collection_build(
schema: {
actions: {
'Charge credit card' => BaseAction.new(
scope: Types::ActionScope::SINGLE
)
}
},
get_form: [
ActionLayoutElement::RowElement.new(
fields: [
ActionField.new(label: 'label', type: 'String'),
ActionField.new(label: 'amount', type: 'String')
]
)
]
)
end

it 'generate schema correctly' do
schema = described_class.build_schema(@collection, 'Charge credit card')

expect(schema).to eq(
{
id: 'collection-0-charge-credit-card',
name: 'Charge credit card',
type: 'single',
baseUrl: nil,
endpoint: '/forest/_actions/collection/0/charge-credit-card',
httpMethod: 'POST',
redirect: nil,
download: false,
fields: [
{
field: 'label',
type: 'String',
description: nil,
isRequired: false,
isReadOnly: false,
widgetEdit: nil,
defaultValue: nil
},
{
field: 'amount',
type: 'String',
description: nil,
isRequired: false,
isReadOnly: false,
widgetEdit: nil,
defaultValue: nil
}
],
# layout: [
# { component: 'row', type: 'Layout', fields: ['label'] }
# ],
hooks: { load: false, change: ['changeHook'] }
}
)
end
end

describe 'extract_fields_and_layout' do
before do
@collection = collection_build(
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,7 @@ def get_form(caller, name, data = nil, filter = nil, metas = {})
dynamic_fields = drop_defaults(context, dynamic_fields, form_values)
dynamic_fields = drop_ifs(context, dynamic_fields) unless metas[:include_hidden_fields]

fields = drop_deferred(context, metas[:search_values], dynamic_fields)
fields = drop_deferred(context, metas[:search_values], dynamic_fields).compact

fields.each do |field|
next if field.type == 'Layout'
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -72,14 +72,16 @@ def build_layout_element(field)
FormLayoutElement::SeparatorElement.new(**field)
when 'HtmlBlock'
FormLayoutElement::HtmlBlockElement.new(**field)
when 'Row'
FormLayoutElement::RowElement.new(**field)
else
raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
"Unknow component type: #{field[:component]}"
end
end

def static_form?
return form&.all?(&:static?) if form
return form&.all?(&:static?) && form&.none? { |field| field.type == 'Layout' } if form

true
end
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,13 +3,13 @@ module Decorators
module Action
module FormLayoutElement
include Types
include ForestAdminDatasourceToolkit::Exceptions

class LayoutElement < BaseFormElement
attr_accessor :if_condition, :component

def initialize(component:, if_condition: nil, **kwargs)
super(type: 'Layout', **kwargs)

@component = component
@if_condition = if_condition
end
Expand All@@ -29,6 +29,39 @@ def initialize(content:, **options)
@content = content
end
end

class RowElement < LayoutElement
include ForestAdminDatasourceToolkit::Exceptions
attr_accessor :fields

def initialize(options)
super(component: 'Row', **options)
validate_fields_presence!(options)
validate_no_layout_subfields!(options[:fields])
@fields = instantiate_subfields(options[:fields] || [])
end

private

def validate_fields_presence!(options)
raise ForestException, "Using 'fields' in a 'Row' configuration is mandatory" unless options.key?(:fields)
end

def validate_no_layout_subfields!(fields)
fields.each do |field|
if (field.is_a?(DynamicField) && field.type == 'Layout') ||
(field.is_a?(Hash) && field[:type] == 'Layout')
raise ForestException, "A 'Row' form element doesn't allow layout elements as subfields"
end
end
end

def instantiate_subfields(fields)
fields.map do |field|
ForestAdminDatasourceToolkit::Components::Actions::ActionFieldFactory.build(field.to_h)
end
end
end
end
end
end
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -225,6 +225,27 @@ module Action
expect(result.content).to eq('<p>foo</p>')
end
end

context 'when element is a Row' do
let(:element) { { type: 'Layout', component: 'Row', fields: [field_send_notification, field_message] } }

it 'returns a row element' do
result = action.build_layout_element(element)
expect(result).to be_a(ForestAdminDatasourceCustomizer::Decorators::Action::FormLayoutElement::RowElement)
expect(result.fields[0].label).to eq('Send a notification')
expect(result.fields[1].label).to eq('Notification message')
end

it 'raises an exception when fields are missing' do
element.delete(:fields)
expect { action.build_layout_element(element) }.to raise_error(ForestAdminDatasourceToolkit::Exceptions::ForestException)
end

it 'raises an exception when fields contain a layout element' do
element[:fields] << { type: 'Layout' }
expect { action.build_layout_element(element) }.to raise_error(ForestAdminDatasourceToolkit::Exceptions::ForestException)
end
end
end

describe 'when check form is static' do
Expand All@@ -237,7 +258,7 @@ module Action
end

context 'when all fields are static' do
let(:form) { [instance_double(DynamicField, static?: true), instance_double(DynamicField, static?: true)] }
let(:form) { [instance_double(DynamicField, static?: true, type: 'String'), instance_double(DynamicField, static?: true, type: 'String')] }
let(:action) { described_class.new(scope: :single, form: form) }

it 'returns true' do
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,10 @@ def self.build_layout_element(field)
ActionLayoutElement::SeparatorElement.new(**field)
when 'HtmlBlock'
ActionLayoutElement::HtmlBlockElement.new(**field)
when 'Row'
return ActionLayoutElement::RowElement.new(**field) unless field[:fields].empty?

nil
end
end

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,15 @@ def initialize(**options)
super(component: 'Separator', **options)
end
end

class RowElement < BaseLayoutElement
attr_accessor :fields

def initialize(fields:, **options)
super(component: 'Row', **options)
@fields = fields
end
end
end
end
end
Expand Down