Skip to content

Commit

Permalink
Merge pull request #378 from wearefuturegov/staging
Browse files Browse the repository at this point in the history
Production deployment
  • Loading branch information
apricot13 authored Nov 18, 2024
2 parents 97a1a55 + 874b00d commit c29951d
Show file tree
Hide file tree
Showing 24 changed files with 124 additions and 27 deletions.
1 change: 1 addition & 0 deletions app/controllers/admin/custom_field_sections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def custom_field_section_params
custom_fields_attributes: [
:id,
:key,
:label,
:field_type,
:hint,
:options,
Expand Down
1 change: 1 addition & 0 deletions app/controllers/admin/services_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ def service_params
],
meta_attributes: [
:id,
:label,
:key,
:value
]
Expand Down
39 changes: 39 additions & 0 deletions app/controllers/api/v1/custom_fields_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class API::V1::CustomFieldsController < ApplicationController
skip_before_action :authenticate_user!

def index
render json: json_tree(CustomFieldSection.api_public.includes(:custom_fields)).to_json
end

private

def json_tree(custom_field_sections)
custom_field_sections.map do |section|
{
id: section.id,
name: section.name,
hint: section.hint,
custom_fields: section.custom_fields.map do |field|
field_hash = {
id: field.id,
label: field.label,
key: field.key,
hint: field.hint,
field_type: field.field_type
}
field_hash[:options] = process_options(field.options) if field.field_type == 'select'
field_hash
end
}
end
end

def process_options(options_string)
options_string.split(',').map.with_index(1) do |option, index|
{
value: option.strip,
# key: option.strip.parameterize
}
end
end
end
1 change: 1 addition & 0 deletions app/controllers/services_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def service_params
meta_attributes: [
:id,
:key,
:label,
:value
]
)
Expand Down
13 changes: 12 additions & 1 deletion app/models/custom_field.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
class CustomField < ApplicationRecord
validates :key, presence: true, uniqueness: true
before_validation :slugify_key

validates :key, uniqueness: { allow_blank: true }, format: { with: /\A[a-z0-9\-]+\z/, message: "must be lowercase, numbers, and dashes only", allow_blank: true }
validates :label, presence: true, uniqueness: true
validates_presence_of :field_type
belongs_to :custom_field_section, counter_cache: :custom_fields_count

Expand All @@ -12,4 +15,12 @@ def self.types
"Date"
]
end

private

def slugify_key
self.key = key.to_s.parameterize if key.present?
end


end
2 changes: 2 additions & 0 deletions app/models/custom_field_section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ class CustomFieldSection < ApplicationRecord
default_scope { order(sort_order: :asc) }

scope :visible_to, -> (current_user){ current_user.admin ? all : where(public: true) }

scope :api_public, -> { where(api_public: true) }
end
2 changes: 1 addition & 1 deletion app/models/regular_schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def description
"Every #{month}#{day} from #{dtstart.strftime("%d/%m/%Y")} at #{opens_at.strftime("%I:%M%P")} to #{closes_at.strftime("%I:%M%P")}#{ends}"
end
else
"#{dtstart.strftime('%A%e %B %Y')} from #{opens_at.strftime("%I:%M%P")} to #{closes_at.strftime("%I:%M%P")}"
"#{dtstart.strftime('%A %e %B %Y')} from #{opens_at.strftime("%I:%M%P")} to #{closes_at.strftime("%I:%M%P")}"
end
else
# opening time
Expand Down
4 changes: 2 additions & 2 deletions app/models/service_meta.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class ServiceMeta < ApplicationRecord
belongs_to :service
validates :key, presence: true
validates_uniqueness_of :key, scope: :service_id
validates :label, presence: true
validates_uniqueness_of :label, scope: :service_id
end
1 change: 1 addition & 0 deletions app/serializers/service_meta_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

class ServiceMetaSerializer < ActiveModel::Serializer
attribute :label
attribute :key
attribute :value
end
2 changes: 1 addition & 1 deletion app/views/admin/custom_field_sections/_fields.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<ul class="repeater__panels" aria-live="polite">
<%= f.fields_for :custom_fields do |c| %>
<li class="repeater__panel" data-custom-fields>
<%= render "admin/custom_field_sections/repeatable-fields", c: c %>
<%= render "admin/custom_field_sections/repeatable-fields", c: c, section: f.object %>
</li>
<% end %>
</ul>
Expand Down
13 changes: 11 additions & 2 deletions app/views/admin/custom_field_sections/_repeatable-fields.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="field-group field-group--two-cols">
<div class="field field--required">
<%= c.label :key, "Label", class: "field__label" %>
<%= c.text_field :key, class: "field__input" %>
<%= c.label :label, "Label", class: "field__label" %>
<%= c.text_field :label, class: "field__input" %>
</div>

<div class="field field--required">
Expand All @@ -20,6 +20,15 @@
<%= c.text_area :hint, class: "field__input", rows: 1 %>
</div>

<% if @section.api_public %>
<div class="field">
<%= c.label :key, "Key", class: "field__label" %>
<p class="field__hint">This is a unique field used to refer to this field in the API</p>
<%= c.text_field :key, class: "field__input", data: { slugify: true } %>
</div>
<% end %>


<%= c.hidden_field :_destroy, data: {destroy_field: true} %>

<button type="button" class="repeater__closer" data-close="true" title="Remove this field">Remove this field</button>
7 changes: 4 additions & 3 deletions app/views/admin/services/editors/_custom-fields.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@
<% end %>

<% section.custom_fields.each do |field| %>
<% meta = s.object.meta.find_or_initialize_by(key: field.key) %>
<% meta = s.object.meta.find_or_initialize_by(label: field.label, key: field.key) %>
<%= s.fields_for :meta, meta do |c| %>
<%= c.hidden_field :label %>
<%= c.hidden_field :key %>

<% if field.field_type === "checkbox" %>
<div class="field">
<div class="checkbox">
<%= c.check_box :value, {class: "checkbox__input"}, "Yes", "No" %>
<%= c.label :value, field.key, class: "checkbox__label" %>
<%= c.label :value, field.label, class: "checkbox__label" %>
</div>
</div>
<% else %>
<div class="field">
<%= c.label :value, field.key, class: "field__label" %>
<%= c.label :value, field.label, class: "field__label" %>
<% if field.hint.present? %>
<p class="field__hint"><%= field.hint %></p>
<% end %>
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
resources :accessibilities, only: [:index]
get "me", to: "me#show"
resources :services, only: [:index, :show]
resources :custom_fields, only: [:index]
end
end

Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20241111163850_add_custom_field_label.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AddCustomFieldLabel < ActiveRecord::Migration[6.0]
def change
# Add new label column
add_column :custom_fields, :label, :string

# Copy data from key to label (only on up migration)
reversible do |dir|
dir.up do
CustomField.reset_column_information
CustomField.update_all('label = key')
end
end
end
end
14 changes: 14 additions & 0 deletions db/migrate/20241111181710_add_service_meta_label.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AddServiceMetaLabel < ActiveRecord::Migration[6.0]
def change
# Add new label column
add_column :service_meta, :label, :string

# Copy data from key to label (only on up migration)
reversible do |dir|
dir.up do
ServiceMeta.reset_column_information
ServiceMeta.update_all('label = key')
end
end
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_09_18_091413) do
ActiveRecord::Schema.define(version: 2024_11_11_181710) do

# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
Expand Down Expand Up @@ -87,6 +87,7 @@
t.string "hint"
t.bigint "custom_field_section_id", null: false
t.string "options"
t.string "label"
t.index ["custom_field_section_id"], name: "index_custom_fields_on_custom_field_section_id"
end

Expand Down Expand Up @@ -318,6 +319,7 @@
t.string "value"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "label"
t.index ["service_id"], name: "index_service_meta_on_service_id"
end

Expand Down
2 changes: 1 addition & 1 deletion lib/tasks/data_import/custom_fields/custom_fields.rake
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace :import do
Rails.logger.info("🟠 Field: \"#{row["name"]}\" already exists, skipping.")
else
custom_field = CustomField.new(
key: row["name"]&.strip,
label: row["name"]&.strip,
field_type: row["field_type"].downcase,
options: row["field_options"],
hint: row["hint"],
Expand Down
4 changes: 2 additions & 2 deletions lib/tasks/data_import/services/import_services.rake
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ namespace :import do
def import_service_meta(type, service_id, fields_for_import, row)
fields_for_import.map do |t|
# Find the existing custom field to add this service meta to
custom_field = CustomField.where(field_type: type).find{|cf| cf.key.downcase.delete("^a-zA-Z0-9 ").gsub(' ', '_') === t}
custom_field = CustomField.where(field_type: type).find{|cf| cf.label.downcase.delete("^a-zA-Z0-9 ").gsub(' ', '_') === t}

unless custom_field.present?
Rails.logger.info("🟠 Custom field \"#{t}\" of type #{type} does not exist. Please check the field name or create the custom field in order to add this service data. Perhaps you have forgotten to run the custom field import?")
Expand All @@ -91,7 +91,7 @@ namespace :import do
end

if value.present?
new_service_meta = ServiceMeta.find_or_initialize_by(service_id: service_id, key: custom_field.key) do |new_sm|
new_service_meta = ServiceMeta.find_or_initialize_by(service_id: service_id, label: custom_field.label) do |new_sm|
new_sm.value = value
end

Expand Down
2 changes: 1 addition & 1 deletion spec/factories/custom_field.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FactoryBot.define do
factory :custom_field do
key { Faker::Lorem.sentence }
label { Faker::Lorem.sentence }
field_type { 'text' }
custom_field_section

Expand Down
2 changes: 1 addition & 1 deletion spec/factories/service_meta.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FactoryBot.define do
factory :service_meta do
key { Faker::Lorem.sentence }
label { Faker::Lorem.sentence }
value { Faker::Number.number }
end
end
4 changes: 2 additions & 2 deletions spec/models/custom_field_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
RSpec.describe CustomField, type: :model do
subject { FactoryBot.build :custom_field }

it { should validate_presence_of :key }
it { should validate_uniqueness_of :key }
it { should validate_presence_of :label }
it { should validate_uniqueness_of :label }
it { should validate_presence_of :field_type }
end
4 changes: 2 additions & 2 deletions spec/models/regular_schedule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,10 @@


context 'event times' do
let(:dtstart) { DateTime.new(2023, 10, 4) } # Wednesday
let(:dtstart) { Date.new(2023, 10, 4) } # Wednesday
context 'single event time' do
it 'should return description of the single event time' do
expect(regular_schedule.description).to eq("#{dtstart.strftime('%A%e %B %Y')} from #{opens_at.strftime("%I:%M%P")} to #{closes_at.strftime("%I:%M%P")}")
expect(regular_schedule.description).to eq("#{dtstart.strftime('%A %e %B %Y')} from #{opens_at.strftime("%I:%M%P")} to #{closes_at.strftime("%I:%M%P")}")
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/models/service_meta_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
RSpec.describe ServiceMeta, type: :model do
subject { FactoryBot.create :service_meta, service: FactoryBot.create(:service) }

it { should validate_presence_of(:key) }
it { should validate_uniqueness_of(:key).scoped_to(:service_id) }
it { should validate_presence_of(:label) }
it { should validate_uniqueness_of(:label).scoped_to(:service_id) }
end
10 changes: 5 additions & 5 deletions spec/tasks/data_import/services_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@

context 'with custom fields in the DB' do
before do
FactoryBot.create :custom_field, key: 'text field'
FactoryBot.create :custom_field, :number, key: 'number field'
FactoryBot.create :custom_field, :checkbox, key: 'checkbox field'
FactoryBot.create :custom_field, :date, key: 'date field'
FactoryBot.create :custom_field, :select, key: 'select field'
FactoryBot.create :custom_field, label: 'text field'
FactoryBot.create :custom_field, :number, label: 'number field'
FactoryBot.create :custom_field, :checkbox, label: 'checkbox field'
FactoryBot.create :custom_field, :date, label: 'date field'
FactoryBot.create :custom_field, :select, label: 'select field'
end

it 'creates the service meta' do
Expand Down

0 comments on commit c29951d

Please sign in to comment.