Skip to content
Open
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 number Diff line number Diff line change
Expand Up @@ -45,24 +45,28 @@ def setup_routes

def handle_api_chart(args)
context = build(args)
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
{
content: Serializer::ForestChartSerializer.serialize(
context.collection.render_chart(
context.caller,
@chart_name,
Id.unpack_id(context.collection, args[:params]['record_id'])
Id.unpack_id(context.collection, args[:params]['record_id']),
parameters
)
)
}
end

def handle_smart_chart(args)
context = build(args)
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
{
content: context.collection.render_chart(
context.caller,
@chart_name,
Id.unpack_id(context.collection, args[:params]['record_id'])
Id.unpack_id(context.collection, args[:params]['record_id']),
parameters
)
}
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,30 @@ def setup_routes

def handle_api_chart(args = {})
caller = Utils::QueryStringParser.parse_caller(args)
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
datasource = ForestAdminAgent::Facades::Container.datasource

{
content: Serializer::ForestChartSerializer.serialize(
datasource.render_chart(
caller,
@chart_name
@chart_name,
parameters
)
)
}
end

def handle_smart_chart(args = {})
caller = Utils::QueryStringParser.parse_caller(args)
parameters = Utils::QueryStringParser.parse_chart_parameters(args)
datasource = ForestAdminAgent::Facades::Container.datasource

{
content: datasource.render_chart(
caller,
@chart_name
@chart_name,
parameters
)
}
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,17 @@ def self.parse_sort(collection, args)
sort
end

def self.parse_chart_parameters(args)
params = args[:params] || {}

params.each_with_object({}) do |(key, value), result|
key_s = key.to_s
next if value.nil? || value.is_a?(Hash) || value.is_a?(Array)

result[key_s] = value.to_s
end
end

def self.parse_segment(collection, args)
segment = args.dig(:params, :data, :attributes, :all_records_subset_query,
:segment) || args.dig(:params, :segment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,52 @@ module Utils
expect(page.limit).to be_nil
end
end

describe 'parse_chart_parameters' do
it 'returns all scalar parameters as strings' do
args = {
params: {
'timezone' => 'Europe/Paris',
'record_id' => '123',
'startDate' => '2024-01-01',
'endDate' => '2024-12-31'
}
}

result = described_class.parse_chart_parameters(args)

expect(result).to eq(
{
'timezone' => 'Europe/Paris',
'record_id' => '123',
'startDate' => '2024-01-01',
'endDate' => '2024-12-31'
}
)
end

it 'converts non-string primitives to strings' do
args = { params: { 'count' => 42, 'active' => true } }

result = described_class.parse_chart_parameters(args)

expect(result).to eq({ 'count' => '42', 'active' => 'true' })
end

it 'ignores nil, hash and array values' do
args = { params: { 'valid' => 'yes', 'nested' => { a: 1 }, 'list' => [1, 2], 'empty' => nil } }

result = described_class.parse_chart_parameters(args)

expect(result).to eq({ 'valid' => 'yes' })
end

it 'returns empty hash when no params' do
args = { params: {} }

expect(described_class.parse_chart_parameters(args)).to eq({})
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ def get_collection(name)
"Collection '#{name}' not found. List of available collections: #{collections.keys.sort.join(", ")}"
end

def render_chart(caller_obj, name)
def render_chart(caller_obj, name, parameters = {})
@datasources.each do |ds|
return ds.render_chart(caller_obj, name) if ds.schema[:charts].include?(name)
return ds.render_chart(caller_obj, name, parameters) if ds.schema[:charts].include?(name)
end

raise ForestAdminDatasourceToolkit::Exceptions::ForestException,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ def add_chart(name, &definition)
mark_schema_as_dirty
end

def render_chart(caller, name, record_id)
def render_chart(caller, name, record_id, parameters = {})
Copy link

Choose a reason for hiding this comment

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

Function with many parameters (count = 4): render_chart [qlty:function-parameters]

if @charts.key?(name)
context = ChartContext.new(self, caller, record_id)
context = ChartContext.new(self, caller, record_id, parameters)
result_builder = ResultBuilder.new

return @charts[name].call(context, result_builder)
end

@child_collection.render_chart(caller, name, record_id)
@child_collection.render_chart(caller, name, record_id, parameters)
end

def refine_schema(sub_schema)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ class ChartContext < ForestAdminDatasourceCustomizer::Context::CollectionCustomi
include ForestAdminDatasourceToolkit::Components::Query
include ForestAdminDatasourceToolkit::Components::Query::ConditionTree

attr_reader :composite_record_id
attr_reader :composite_record_id, :parameters

def initialize(collection, caller, record_id)
def initialize(collection, caller, record_id, parameters = {})
Copy link

Choose a reason for hiding this comment

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

Function with many parameters (count = 4): initialize [qlty:function-parameters]

super(collection, caller)
@composite_record_id = record_id
@parameters = (parameters || {}).freeze
end

def _composite_record_id=(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ def add_chart(name, &definition)
@charts[name] = definition
end

def render_chart(caller, name)
def render_chart(caller, name, parameters = {})
chart_definition = @charts[name]

if chart_definition
return chart_definition.call(
Context::AgentCustomizationContext.new(self, caller),
DatasourceChartContext.new(self, caller, parameters),
ResultBuilder.new
)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module ForestAdminDatasourceCustomizer
module Decorators
module Chart
class DatasourceChartContext < ForestAdminDatasourceCustomizer::Context::AgentCustomizationContext
attr_reader :parameters

def initialize(datasource, caller, parameters = {})
super(datasource, caller)
@parameters = (parameters || {}).freeze
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ module Chart
end
end

describe 'parameters' do
it 'returns empty hash when no parameters provided' do
expect(@context.parameters).to eq({})
end

it 'returns the parameters when provided' do
collection = build_collection(
name: 'my_collection',
schema: {
fields: { 'id1' => build_numeric_primary_key, 'id2' => build_numeric_primary_key }
},
list: [{ id1: 1, id2: 2 }]
)
ctx = described_class.new(collection, caller, [1, 2], { 'startDate' => '2024-01-01', 'endDate' => '2024-12-31' })

expect(ctx.parameters).to eq({ 'startDate' => '2024-01-01', 'endDate' => '2024-12-31' })
end

it 'returns a frozen hash' do
expect(@context.parameters).to be_frozen
end
end

describe 'attribute access pattern' do
describe '#composite_record_id=' do
it 'does not exist (raises NoMethodError)' do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ module Chart
expect(result).to eq({ countCurrent: 34, countPrevious: 45 })
expect(datasource).not_to have_received(:render_chart)
end

it 'passes parameters to the handler context' do
received_ctx = nil
decorator.add_chart('chart_with_params') do |ctx, result_builder|
received_ctx = ctx
result_builder.value(10)
end

decorator.render_chart(caller, 'chart_with_params', { 'startDate' => '2024-01-01' })

expect(received_ctx.parameters).to eq({ 'startDate' => '2024-01-01' })
end
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ def get_form(caller, name, data = nil, filter = nil, metas = nil)
end
end

def render_chart(caller, name, record_id)
params = build_params(chart: name, record_id: record_id)
def render_chart(caller, name, record_id, parameters = {})
Copy link

Choose a reason for hiding this comment

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

Function with many parameters (count = 4): render_chart [qlty:function-parameters]

params = build_params(chart: name, record_id: record_id, parameters: parameters)
url = "#{@rpc_collection_uri}/chart"

ForestAdminAgent::Facades::Container.logger.log(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ def initialize(options, introspection, schema_polling_client = nil)
register_shutdown_hook if @schema_polling_client
end

def render_chart(caller, name)
def render_chart(caller, name, parameters = {})
url = 'forest/rpc-datasource-chart'

ForestAdminAgent::Facades::Container.logger.log(
'Debug',
"Forwarding datasource chart '#{name}' call to the Rpc agent on #{url}."
)

@shared_rpc_client.call_rpc(url, caller: caller, method: :post, payload: { chart: name })
@shared_rpc_client.call_rpc(url, caller: caller, method: :post, payload: { chart: name, parameters: parameters })
end

def execute_native_query(connection_name, query, binds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,26 @@ module ForestAdminDatasourceRpc
{
collection_name: 'Product',
chart: 'my_chart',
record_id: 1
record_id: 1,
parameters: {}
}
)
end
end

it 'forward the call with parameters' do
collection.render_chart(caller, 'my_chart', 1, { 'startDate' => '2024-01-01' })

expect(rpc_client).to have_received(:call_rpc) do |url, options|
expect(url).to eq('/forest/rpc/Product/chart')
expect(options[:caller]).to eq(caller)
expect(options[:method]).to eq(:post)
expect(options[:payload]).to eq(
{
collection_name: 'Product',
chart: 'my_chart',
record_id: 1,
parameters: { 'startDate' => '2024-01-01' }
}
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,18 @@ module ForestAdminDatasourceRpc
expect(url).to eq('forest/rpc-datasource-chart')
expect(options[:caller]).to eq(caller)
expect(options[:method]).to eq(:post)
expect(options[:payload]).to eq({ chart: 'my_chart' })
expect(options[:payload]).to eq({ chart: 'my_chart', parameters: {} })
end
end

it 'forward the call with parameters' do
datasource.render_chart(caller, 'my_chart', { 'startDate' => '2024-01-01' })

expect(rpc_client).to have_received(:call_rpc) do |url, options|
expect(url).to eq('forest/rpc-datasource-chart')
expect(options[:caller]).to eq(caller)
expect(options[:method]).to eq(:post)
expect(options[:payload]).to eq({ chart: 'my_chart', parameters: { 'startDate' => '2024-01-01' } })
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def add_chart(name)
schema[:charts] << name
end

def render_chart(_caller, name, _record_id)
def render_chart(_caller, name, _record_id, _parameters = {})
Copy link

Choose a reason for hiding this comment

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

Function with many parameters (count = 4): render_chart [qlty:function-parameters]

raise Exceptions::ForestException, "Chart #{name} is not implemented."
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def add_collection(collection)
@collections[collection.name] = collection
end

def render_chart(_caller, name)
def render_chart(_caller, name, _parameters = {})
raise Exceptions::ForestException, "No chart named #{name} exists on this datasource."
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ def aggregate(caller, filter, aggregation, limit = nil)
@child_collection.aggregate(caller, refined_filter, aggregation, limit)
end

def render_chart(caller, name, record_id)
@child_collection.render_chart(caller, name, record_id)
def render_chart(caller, name, record_id, parameters = {})
Copy link

Choose a reason for hiding this comment

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

Function with many parameters (count = 4): render_chart [qlty:function-parameters]

@child_collection.render_chart(caller, name, record_id, parameters)
end

protected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def get_collection(name)
@decorators[collection.name]
end

def render_chart(caller, name)
@child_datasource.render_chart(caller, name)
def render_chart(caller, name, parameters = {})
@child_datasource.render_chart(caller, name, parameters)
end

def execute_native_query(connection_name, query, binds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ def handle_request(args)
return {} unless args[:params]['collection_name']

chart_name = args[:params]['chart']
parameters = args[:params]['parameters']
datasource = ForestAdminRpcAgent::Facades::Container.datasource
collection = get_collection_safe(datasource, args[:params]['collection_name'])

collection.render_chart(caller, chart_name, args[:params]['record_id'])
collection.render_chart(caller, chart_name, args[:params]['record_id'], parameters)
end
end
end
Expand Down
Loading
Loading