diff --git a/lib/spectrum/config.rb b/lib/spectrum/config.rb index ed48ab0..2002bfa 100644 --- a/lib/spectrum/config.rb +++ b/lib/spectrum/config.rb @@ -53,6 +53,10 @@ require 'spectrum/config/quoted_search1_metadata_component' require 'spectrum/config/quoted_search2_metadata_component' +require 'spectrum/config/header_region' +require 'spectrum/config/header_component' +require 'spectrum/config/plain_header_component' + require 'spectrum/config/highly_recommended' require 'spectrum/config/sort' require 'spectrum/config/sort_list' diff --git a/lib/spectrum/config/field.rb b/lib/spectrum/config/field.rb index 70ebfdb..516f991 100644 --- a/lib/spectrum/config/field.rb +++ b/lib/spectrum/config/field.rb @@ -57,7 +57,7 @@ def index attr_reader :list, :full, :viewable, :searchable, :uid, :field, :sorts, :fields, :query_params, :values, - :query_field, :facet_field, :metadata_component + :query_field, :facet_field, :metadata_component, :header_region type 'default' @@ -87,6 +87,7 @@ def initialize_from_instance(i) @csl = i.csl @z3988 = i.z3988 @metadata_component = i.metadata_component + @header_region = i.header_region end def initialize_from_hash(args, config) @@ -126,6 +127,13 @@ def initialize_from_hash(args, config) medium: MetadataComponent.new(name, mc['medium']), full: MetadataComponent.new(name, mc['full']), } + + hr = args['header_region'] || {} + @header_region = { + preview: HeaderRegion.new(hr['preview']), + medium: HeaderRegion.new(hr['medium']), + full: HeaderRegion.new(hr['full']), + } end def type @@ -175,6 +183,12 @@ def display(mode, data, request) mc.resolve(filter(data, request)) end + def header_region_display(mode, data, request) + hr = header_region[mode] + return nil unless hr + hr.resolve(filter(data, request)) + end + def icons(data, request) mc = metadata_component[:preview] return nil unless mc.respond_to?(:icons) diff --git a/lib/spectrum/config/focus.rb b/lib/spectrum/config/focus.rb index 7c29b70..5db52b0 100644 --- a/lib/spectrum/config/focus.rb +++ b/lib/spectrum/config/focus.rb @@ -195,6 +195,29 @@ def metadata_component(data, _ = nil, request = nil) ret end + def header_component(data, _ = nil, request = nil) + return data.map {|item| header_component(item, nil, request)}.compact if data === Array + ret = {} + [:preview, :medium, :full].each do |display_type| + ret[display_type] = Hash.new + @fields.each_value do |field| + if field.respond_to?(:header_region_display) + rendered_display = field.header_region_display(display_type, data, request) + unless rendered_display.nil? + region = rendered_display[:region] + description = rendered_display[:description] + unless description.nil? + ret[display_type][region] ||= [] + ret[display_type][region] << description + end + end + end + end + end + ret + end + + def apply_fields(data, _ = nil, request = nil) if data === Array data.map { |item| apply_fields(item, nil, request) }.compact diff --git a/lib/spectrum/config/header_component.rb b/lib/spectrum/config/header_component.rb new file mode 100644 index 0000000..f2d89ea --- /dev/null +++ b/lib/spectrum/config/header_component.rb @@ -0,0 +1,53 @@ +module Spectrum + module Config + class HeaderComponent + class << self + def new(region, config) + klass = get_type(config) + return klass.new(region, config) if klass + obj = allocate + obj.send(:initialize, region, config) + obj + end + + def inherited(base) + registry << base + end + + def type(t = nil) + @type = t if t + @type + end + + def get_type(config) + return nil unless config&.respond_to?(:[]) + return nil unless config['type'] + registry.find {|item| item.type == config['type'] } + end + + def registry + @registry ||= [] + end + end + + attr_accessor :region, :config + + def initialize(_, _) + end + + def resolve(_) + nil + end + + def get_description(_) + nil + end + + def icons(_) + nil + end + + end + end +end + diff --git a/lib/spectrum/config/header_region.rb b/lib/spectrum/config/header_region.rb new file mode 100644 index 0000000..3fd184c --- /dev/null +++ b/lib/spectrum/config/header_region.rb @@ -0,0 +1,20 @@ +module Spectrum + module Config + class HeaderRegion + + def initialize(config) + if config.is_a?(Hash) + @region, component_config = config.first + end + + @header_component = HeaderComponent.new(@region, component_config) + end + + def resolve(data) + return nil if @header_component.nil? + @header_component.resolve(data) + end + + end + end +end diff --git a/lib/spectrum/config/plain_header_component.rb b/lib/spectrum/config/plain_header_component.rb new file mode 100644 index 0000000..0a27032 --- /dev/null +++ b/lib/spectrum/config/plain_header_component.rb @@ -0,0 +1,33 @@ +module Spectrum + module Config + class PlainHeaderComponent < HeaderComponent + type 'plain' + + def initialize(region, config) + self.region = region + end + + def get_description(data) + [data].flatten(1).map do |item| + item = item.to_s + if item.empty? + nil + else + {text: item} + end + end.compact + end + + def resolve(data) + return data if Hash === data && data[:region] && data[:description] + description = get_description(data) + return nil if description.empty? + + { + region: region, + description: description, + } + end + end + end +end diff --git a/spec/spectrum/config/header_region_spec.rb b/spec/spectrum/config/header_region_spec.rb new file mode 100644 index 0000000..5ee09ce --- /dev/null +++ b/spec/spectrum/config/header_region_spec.rb @@ -0,0 +1,54 @@ +require_relative '../../spec_helper' +require 'spectrum/config/header_region' +require 'spectrum/config/header_component' +require 'spectrum/config/plain_header_component' + + +describe Spectrum::Config::HeaderRegion do + subject { described_class.new(region_config) } + + let(:region_config) {{ 'region_descriptor'=>{ 'type' => 'plain' } }} + + let(:string_data) { "STRING" } + let(:array_data) { ["STRING1", "STRING2"] } + + let(:string_data_result) { + { + description: [{text: "STRING"}], + region: 'region_descriptor', + } + } + + let(:array_data_result) { + { + description: [{text: "STRING1"}, {text: "STRING2"}], + region: 'region_descriptor', + } + } + + context "#resolve" do + it "returns nil when given nil" do + expect(subject.resolve(nil)).to be(nil) + end + + it "returns nil when given []" do + expect(subject.resolve([])).to be(nil) + end + + it "returns nil when given [nil]" do + expect(subject.resolve([nil])).to be(nil) + end + + it "returns nil when given ['']" do + expect(subject.resolve([''])).to be(nil) + end + + it "returns string_data_result when given string_data" do + expect(subject.resolve(string_data)).to eq(string_data_result) + end + + it "returns string_data_result when given string_data" do + expect(subject.resolve(array_data)).to eq(array_data_result) + end + end +end diff --git a/spec/spectrum/config/plain_header_component_spec.rb b/spec/spectrum/config/plain_header_component_spec.rb new file mode 100644 index 0000000..71280cb --- /dev/null +++ b/spec/spectrum/config/plain_header_component_spec.rb @@ -0,0 +1,64 @@ +require_relative '../../spec_helper' +require 'spectrum/config/header_component' +require 'spectrum/config/plain_header_component' + +describe Spectrum::Config::PlainHeaderComponent do + subject { described_class.new('REGION', {'type' => 'plain'}) } + + let(:string_data) { "STRING" } + + let(:data) {{ + region: 'REGION', + description: 'DESCRIPTION', + }} + + let(:data_result) {{ + region: 'REGION', + description: 'DESCRIPTION', + }} + + let(:string_data_result) {{ + region: 'REGION', + description: [{text: "STRING"}], + }} + + let(:data_full) {{ + region: 'REGION', + description: [{text: 'DESCRIPTION'}] + }} + + let(:data_full_result) {{ + region: 'REGION', + description: [{text: 'DESCRIPTION'}] + }} + + context "#resolve" do + it "returns nil when given nil" do + expect(subject.resolve(nil)).to be(nil) + end + + it "returns nil when given []" do + expect(subject.resolve([])).to be(nil) + end + + it "returns nil when given [nil]" do + expect(subject.resolve([''])).to be(nil) + end + + it "returns nil when given ['']" do + expect(subject.resolve([''])).to be(nil) + end + + it "returns data when given a header component hash" do + expect(subject.resolve(data)).to eq(data_result) + end + + it "returns data when given a header component hash" do + expect(subject.resolve(string_data)).to eq(string_data_result) + end + + it "returns data when given full header component data" do + expect(subject.resolve(data_full)).to eq(data_full_result) + end + end +end