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
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -183,6 +183,7 @@ Metrics/ParameterLists:
- 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/action/context/action_context.rb'
- 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/action/action_collection_decorator.rb'
- 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/action/dynamic_field.rb'
- 'packages/forest_admin_datasource_customizer/lib/forest_admin_datasource_customizer/decorators/hook/context/after/hook_after_aggregate_context.rb'
- 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/schema/relations/many_to_many_schema.rb'
- 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/schema/column_schema.rb'
- 'packages/forest_admin_datasource_toolkit/lib/forest_admin_datasource_toolkit/components/caller.rb'
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
module ForestAdminAgent
module Http
module Exceptions
class ValidationError < HttpException
attr_reader :name

def initialize(message, name = 'ValidationError')
super(400, message, name)
end
end
end
end
end
1 change: 1 addition & 0 deletions packages/forest_admin_datasource_customizer/Gemfile
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,6 +3,7 @@ source "https://rubygems.org"
# Specify your gem's dependencies in forest_admin_datasource_toolkit.gemspec
gemspec

gem 'forest_admin_agent', path: '../forest_admin_agent'
gem 'forest_admin_datasource_toolkit', path: '../forest_admin_datasource_toolkit'

gem 'rake', '~> 13.0'
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -215,18 +215,29 @@ def replace_field_writing(name, &definition)
# @param name name of the chart
# @param definition definition of the chart
# @example
# .addChart('num_customers') do |context, result_builder|
# .add_chart('num_customers') do |context, result_builder|
# return result_builder.distribution({
# tomatoes: 10,
# potatoes: 20,
# carrots: 30,
# });
# end
# )
# end
def add_chart(name, &definition)
push_customization { @stack.chart.get_collection(@name).add_chart(name, &definition) }
end

# Add a new hook handler to an action
# @param position Either if the hook is executed before or after the action
# @param type Type of action which should be hooked
# @param handler Callback that should be executed when the hook is triggered
# @example
# .add_hook('before', 'list') do |context|
# # Do something before the list action
# end
def add_hook(position, type, &handler)
push_customization { @stack.hook.get_collection(@name).add_hook(position, type, handler) }
end

private

def push_customization(&customization)
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ class DecoratorsStack
include ForestAdminDatasourceToolkit::Decorators

attr_reader :datasource, :schema, :search, :early_computed, :late_computed, :action, :relation, :late_op_emulate,
:early_op_emulate, :validation, :sort, :rename_field, :publication, :write, :chart
:early_op_emulate, :validation, :sort, :rename_field, :publication, :write, :chart, :hook

def initialize(datasource)
@customizations = []
Expand All@@ -28,6 +28,7 @@ def initialize(datasource)
last = @action = DatasourceDecorator.new(last, Action::ActionCollectionDecorator)
last = @schema = DatasourceDecorator.new(last, Schema::SchemaCollectionDecorator)
last = @write = Write::WriteDatasourceDecorator.new(last)
last = @hook = DatasourceDecorator.new(last, Hook::HookCollectionDecorator)
last = @validation = DatasourceDecorator.new(last, Validation::ValidationCollectionDecorator)

last = @publication = Publication::PublicationDatasourceDecorator.new(last)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module After
class HookAfterAggregateContext < Hook::Context::Before::HookBeforeAggregateContext
attr_reader :aggregate_result

def initialize(collection, caller, filter, aggregation, aggregate_result, limit = nil)
super(collection, caller, filter, aggregation, limit)
@aggregate_result = aggregate_result
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module After
class HookAfterCreateContext < Hook::Context::Before::HookBeforeCreateContext
attr_reader :record

def initialize(collection, caller, data, record)
super(collection, caller, data)
@record = record
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module After
class HookAfterDeleteContext < Hook::Context::Before::HookBeforeDeleteContext
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module After
class HookAfterListContext < Hook::Context::Before::HookBeforeListContext
attr_reader :records

def initialize(collection, caller, filter, projection, records)
super(collection, caller, filter, projection)
@records = records
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module After
class HookAfterUpdateContext < Hook::Context::Before::HookBeforeUpdateContext
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module Before
class HookBeforeAggregateContext < Hook::Context::HookContext
attr_reader :filter, :aggregation, :limit

def initialize(collection, caller, filter, aggregation, limit = nil)
super(collection, caller)
@filter = filter
@aggregation = aggregation
@limit = limit
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module Before
class HookBeforeCreateContext < Hook::Context::HookContext
attr_reader :data

def initialize(collection, caller, data)
super(collection, caller)
@data = data
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module Before
class HookBeforeDeleteContext < Hook::Context::HookContext
attr_reader :filter

def initialize(collection, caller, filter)
super(collection, caller)
@filter = filter
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module Before
class HookBeforeListContext < Hook::Context::HookContext
attr_reader :filter, :projection

def initialize(collection, caller, filter, projection)
super(collection, caller)
@filter = filter
@projection = projection
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
module Before
class HookBeforeUpdateContext < Hook::Context::HookContext
attr_reader :filter, :patch

def initialize(collection, caller, filter, patch)
super(collection, caller)
@filter = filter
@patch = patch
end
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
module Context
class HookContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomizationContext
include ForestAdminAgent::Http::Exceptions
def raise_validation_error(message)
raise ValidationError, message
end

def raise_forbidden_error(message)
raise ForbiddenError, message
end

def raise_error(message)
raise UnprocessableError, message
end
end
end
end
end
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Hook
class HookCollectionDecorator < ForestAdminDatasourceToolkit::Decorators::CollectionDecorator
include ForestAdminDatasourceToolkit::Components
include Context

attr_reader :hooks

def initialize(child_collection, datasource)
super
@hooks = {
'list' => Hooks.new,
'create' => Hooks.new,
'update' => Hooks.new,
'delete' => Hooks.new,
'aggregate' => Hooks.new
}
end

def add_hook(position, type, hook)
@hooks[type].add_handler(position, hook)
end

def create(caller, data)
before_context = Before::HookBeforeCreateContext.new(@child_collection, caller, data)
@hooks['create'].execute_before(before_context)

record = @child_collection.create(caller, before_context.data)

after_context = After::HookAfterCreateContext.new(@child_collection, caller, data, record)
@hooks['create'].execute_after(after_context)

record
end

def list(caller, filter, projection)
before_context = Before::HookBeforeListContext.new(@child_collection, caller, filter, projection)
@hooks['list'].execute_before(before_context)

records = @child_collection.list(caller, before_context.filter, before_context.projection)

after_context = After::HookAfterListContext.new(@child_collection, caller, filter, projection, records)
@hooks['list'].execute_after(after_context)

records
end

def update(caller, filter, patch)
before_context = Before::HookBeforeUpdateContext.new(@child_collection, caller, filter, patch)
@hooks['update'].execute_before(before_context)

@child_collection.update(caller, before_context.filter, before_context.patch)

after_context = After::HookAfterUpdateContext.new(@child_collection, caller, filter, patch)
@hooks['update'].execute_after(after_context)
end

def delete(caller, filter)
before_context = Before::HookBeforeDeleteContext.new(@child_collection, caller, filter)
@hooks['delete'].execute_before(before_context)

@child_collection.delete(caller, before_context.filter)

after_context = After::HookAfterDeleteContext.new(@child_collection, caller, filter)
@hooks['delete'].execute_after(after_context)
end

def aggregate(caller, filter, aggregation, limit = nil)
before_context = Before::HookBeforeAggregateContext.new(@child_collection, caller, filter, aggregation, limit)
@hooks['aggregate'].execute_before(before_context)

results = @child_collection.aggregate(
caller,
before_context.filter,
before_context.aggregation,
before_context.limit
)

after_context = After::HookAfterAggregateContext.new(
@child_collection,
caller,
filter,
aggregation,
results,
limit
)
@hooks['aggregate'].execute_after(after_context)

results
end
end
end
end
end
Loading