diff --git a/app/assets/stylesheets/admin/items.scss b/app/assets/stylesheets/admin/items.scss
index 2e04f087..206f7c55 100644
--- a/app/assets/stylesheets/admin/items.scss
+++ b/app/assets/stylesheets/admin/items.scss
@@ -1,13 +1,41 @@
-.item input, .item textarea {
- width: 50rem;
- display: block;
-}
+.item {
+ input, textarea {
+ width: 50rem;
+ display: block;
+ }
+
+ select {
+ width: 35rem;
+ margin-right: 2rem;
+ height: 1.9rem;
+ }
+
+ button.delete_value {
+ width: 13rem;
+ }
+
+ button.add_value {
+ display: block;
+ margin-top: 0.25rem;
+ }
-.item .required {
- font-style: italic;
+ .required {
+ font-style: italic;
+ }
+
+ label {
+ margin-bottom: 0.5rem;
+ }
}
-#choose_blueprint button {
- display: block;
- margin-bottom: 0.25rem;
+#choose_blueprint {
+ width: fit-content;
+
+ button {
+ display: block;
+ width: 100%;
+ margin-bottom: 0.25rem;
+ }
}
+
+
diff --git a/app/helpers/t3_form_builder.rb b/app/helpers/t3_form_builder.rb
index 8b5d6073..e9425ddb 100644
--- a/app/helpers/t3_form_builder.rb
+++ b/app/helpers/t3_form_builder.rb
@@ -1,7 +1,7 @@
# Custom form controls to support T3 field-specific data types
# e.g. #vacabulary provides a customized select populated with a defined vocabulary
class T3FormBuilder < ActionView::Helpers::FormBuilder
- def vocabulary(method, options = {})
+ def vocabulary_field(method, options = {})
multiple = options.delete(:multiple)
selected = options.delete(:value) || ''
select_options = options.except(:multiple)
@@ -9,7 +9,7 @@ def vocabulary(method, options = {})
{ name: @template.field_name(@object_name, method, multiple: multiple) }
)
.merge({ selected: selected })
- option_tags = @template.options_from_collection_for_select(Collection.order(:created_at), :id, :id, selected)
+ option_tags = @template.options_from_collection_for_select(Collection.order(:created_at), :label, :label, selected)
select(method, option_tags, { prompt: 'Select one', selected: '', disabled: true }, select_options)
end
end
diff --git a/app/models/field.rb b/app/models/field.rb
index 219017bd..9e92ca17 100644
--- a/app/models/field.rb
+++ b/app/models/field.rb
@@ -7,7 +7,8 @@ class Field < ApplicationRecord
integer: 3,
float: 4,
date: 5,
- boolean: 6
+ boolean: 6,
+ vocabulary: 7
}
TYPE_TO_SOLR = {
@@ -16,7 +17,8 @@ class Field < ApplicationRecord
'integer' => 'lt',
'float' => 'dbt',
'date' => 'dt',
- 'boolean' => 'b'
+ 'boolean' => 'b',
+ 'vocabulary' => 's'
}.freeze
TYPE_TO_HELPER = {
@@ -25,7 +27,8 @@ class Field < ApplicationRecord
'integer' => :number_field,
'float' => :number_field,
'date' => :date_field,
- 'boolean' => :check_box
+ 'boolean' => :check_box,
+ 'vocabulary' => :vocabulary_field
}.freeze
validates :name, presence: true
@@ -98,6 +101,10 @@ def move(position) # rubocop:disable Metrics/MethodLength
end
end
+ def form_helper
+ TYPE_TO_HELPER[data_type]
+ end
+
private
def clear_solr_field
diff --git a/app/models/item.rb b/app/models/item.rb
index df60a726..d8e77ce9 100644
--- a/app/models/item.rb
+++ b/app/models/item.rb
@@ -51,6 +51,10 @@ def prune_orphans(batch, previously_checked)
end
end
+ def label
+ metadata[label_field]
+ end
+
def to_partial_path
"admin/#{super}"
end
@@ -115,4 +119,8 @@ def required_fields_present
end
end
end
+
+ def label_field
+ @label_field ||= blueprint.fields.first.name
+ end
end
diff --git a/app/views/admin/items/_form.html.erb b/app/views/admin/items/_form.html.erb
index b7d6cc35..4f3806fe 100644
--- a/app/views/admin/items/_form.html.erb
+++ b/app/views/admin/items/_form.html.erb
@@ -1,4 +1,4 @@
-<%= form_with(model: item, scope: 'item', id: 'item_fields', class: 'item') do |form| %>
+<%= form_with(model: item, scope: 'item', id: 'item_fields', class: 'item', builder: T3FormBuilder) do |form| %>
<% if item.errors.any? %>
<%= pluralize(item.errors.count, "error") %> prohibited this item from being saved:
@@ -23,20 +23,21 @@
diff --git a/spec/helpers/t3_form_builder_spec.rb b/spec/helpers/t3_form_builder_spec.rb
index ac8d091c..6e0e619f 100644
--- a/spec/helpers/t3_form_builder_spec.rb
+++ b/spec/helpers/t3_form_builder_spec.rb
@@ -11,7 +11,7 @@
let(:tag_options) { {} }
describe '#vocabulary' do
- let(:vocabulary_helper) { Capybara.string(form_builder.vocabulary(:collection, tag_options)) }
+ let(:vocabulary_helper) { Capybara.string(form_builder.vocabulary_field(:collection, tag_options)) }
it 'renders a select with the expected id' do
expect(vocabulary_helper).to have_select('item[metadata][collection]')
@@ -33,7 +33,11 @@
let(:tag_options) { { value: 'Green' } }
before do
- collections = [OpenStruct.new({ id: 'Red' }), OpenStruct.new({ id: 'Green' }), OpenStruct.new({ id: 'Blue' })]
+ collections = [
+ instance_double(Collection, { label: 'Red', id: 5 }),
+ instance_double(Collection, { label: 'Green', id: 20 }),
+ instance_double(Collection, { label: 'Blue', id: 25 })
+ ]
allow(Collection).to receive(:order).and_return(collections)
end
diff --git a/spec/models/field_spec.rb b/spec/models/field_spec.rb
index 79591d88..a833c611 100644
--- a/spec/models/field_spec.rb
+++ b/spec/models/field_spec.rb
@@ -111,6 +111,15 @@
end
end
+ describe '#form_helper' do
+ it 'is defined for each data_type' do
+ described_class.data_types.each_key do |data_type|
+ field.data_type = data_type
+ expect(field.form_helper).to be_present, "Missing form_helper mapping for data_type: #{data_type}"
+ end
+ end
+ end
+
describe '#solr_suffix' do
it 'ends in "m" for multivalued fields' do
field.multiple = true
diff --git a/spec/models/item_spec.rb b/spec/models/item_spec.rb
index 32cf1db6..b1e9eca3 100644
--- a/spec/models/item_spec.rb
+++ b/spec/models/item_spec.rb
@@ -4,7 +4,7 @@
let(:new_item) { described_class.new(metadata: basic_description) }
let(:basic_description) do
{
- 'Title' => 'One Hundred Years of Solitute',
+ 'Title' => 'One Hundred Years of Solitude',
'Author' => ['Márquez, Gabriel García'],
'Date' => '1967'
}
@@ -12,7 +12,7 @@
let(:solr_doc) do
{
'blueprint_ssi' => 'Sample Blueprint',
- 'title_tesi' => 'One Hundred Years of Solitute',
+ 'title_tesi' => 'One Hundred Years of Solitude',
'author_tesim' => ['Márquez, Gabriel García'],
'date_ltsi' => '1967'
}
@@ -46,6 +46,18 @@
end
end
+ describe '#label' do
+ let(:blueprint) { FactoryBot.build(:blueprint, name: 'Sample Blueprint') }
+ let(:new_item) { described_class.new(blueprint: blueprint, metadata: basic_description.as_json) }
+
+ it 'returns the value of the bluprint title field' do
+ allow(blueprint).to receive(:fields).and_return(
+ [FactoryBot.build(:field, name: 'Title', data_type: 'text_en')]
+ )
+ expect(new_item.label).to eq 'One Hundred Years of Solitude'
+ end
+ end
+
describe '#to_solr' do
let(:blueprint) { FactoryBot.build(:blueprint, name: 'Sample Blueprint') }
let(:new_item) { described_class.new(blueprint: blueprint, metadata: basic_description.as_json) }
diff --git a/spec/views/admin/collections/edit.html.erb_spec.rb b/spec/views/admin/collections/edit.html.erb_spec.rb
index 1455e4d8..4dc9443f 100644
--- a/spec/views/admin/collections/edit.html.erb_spec.rb
+++ b/spec/views/admin/collections/edit.html.erb_spec.rb
@@ -168,4 +168,32 @@
expect(rendered).to have_button('refresh', value: 'delete keyword 2')
end
end
+
+ describe 'a vocabulary field' do
+ let(:vocabulary_field) do
+ FactoryBot.build(:field, name: 'collection', data_type: 'vocabulary', multiple: false, id: 1, sequence: 1)
+ end
+
+ before do
+ collections = [
+ instance_double(Collection, { id: 1, label: 'Cyan' }),
+ instance_double(Collection, { id: 2, label: 'Magenta' }),
+ instance_double(Collection, { id: 4, label: 'Yellow' })
+ ]
+ allow(Collection).to receive(:order).and_return(collections)
+ end
+
+ it 'renders a slection list' do
+ allow(blueprint).to receive(:fields).and_return([vocabulary_field])
+ render
+ expect(rendered).to have_select('item[metadata][collection]')
+ end
+
+ it 'lists available values' do
+ allow(blueprint).to receive(:fields).and_return([vocabulary_field])
+ render
+ select_options = Capybara.string(rendered).all('select option').map(&:text)
+ expect(select_options).to include('Cyan', 'Magenta', 'Yellow')
+ end
+ end
end