From 63510eaacc65be36c017360ea65cd8117e968e05 Mon Sep 17 00:00:00 2001 From: Han Date: Tue, 12 Nov 2024 10:43:03 +0000 Subject: [PATCH 1/5] add space between month and date --- app/models/regular_schedule.rb | 2 +- spec/models/regular_schedule_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/regular_schedule.rb b/app/models/regular_schedule.rb index 1e654c2d..835e73ef 100644 --- a/app/models/regular_schedule.rb +++ b/app/models/regular_schedule.rb @@ -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 diff --git a/spec/models/regular_schedule_spec.rb b/spec/models/regular_schedule_spec.rb index 828296ce..ba95d84a 100644 --- a/spec/models/regular_schedule_spec.rb +++ b/spec/models/regular_schedule_spec.rb @@ -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 From 8603281f8d6a1f8ac380ce10fdf544fae7123576 Mon Sep 17 00:00:00 2001 From: Han Date: Mon, 11 Nov 2024 15:25:12 +0000 Subject: [PATCH 2/5] TOP-251 add keys to custom fields and service meta --- .../admin/custom_field_sections_controller.rb | 1 + app/controllers/admin/services_controller.rb | 1 + .../api/v1/custom_fields_controller.rb | 39 +++++++++++++++++++ app/controllers/services_controller.rb | 1 + app/models/custom_field.rb | 13 ++++++- app/models/custom_field_section.rb | 2 + app/models/service_meta.rb | 4 +- app/serializers/service_meta_serializer.rb | 1 + .../custom_field_sections/_fields.html.erb | 2 +- .../_repeatable-fields.html.erb | 13 ++++++- .../services/editors/_custom-fields.html.erb | 7 ++-- config/routes.rb | 1 + .../20241111163850_add_custom_field_label.rb | 14 +++++++ .../20241111181710_add_service_meta_label.rb | 14 +++++++ db/schema.rb | 4 +- 15 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 app/controllers/api/v1/custom_fields_controller.rb create mode 100644 db/migrate/20241111163850_add_custom_field_label.rb create mode 100644 db/migrate/20241111181710_add_service_meta_label.rb diff --git a/app/controllers/admin/custom_field_sections_controller.rb b/app/controllers/admin/custom_field_sections_controller.rb index 3f1e577d..152440f5 100644 --- a/app/controllers/admin/custom_field_sections_controller.rb +++ b/app/controllers/admin/custom_field_sections_controller.rb @@ -51,6 +51,7 @@ def custom_field_section_params custom_fields_attributes: [ :id, :key, + :label, :field_type, :hint, :options, diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb index c220a16e..194089b6 100644 --- a/app/controllers/admin/services_controller.rb +++ b/app/controllers/admin/services_controller.rb @@ -192,6 +192,7 @@ def service_params ], meta_attributes: [ :id, + :label, :key, :value ] diff --git a/app/controllers/api/v1/custom_fields_controller.rb b/app/controllers/api/v1/custom_fields_controller.rb new file mode 100644 index 00000000..11c83a0f --- /dev/null +++ b/app/controllers/api/v1/custom_fields_controller.rb @@ -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 \ No newline at end of file diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index 74c4cfc4..bd71b817 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -158,6 +158,7 @@ def service_params meta_attributes: [ :id, :key, + :label, :value ] ) diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 6ada0bd0..9190cc05 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -1,5 +1,8 @@ class CustomField < ApplicationRecord - validates :key, presence: true, uniqueness: true + before_validation :slugify_key + + validates :key, uniqueness: true, format: { with: /\A[a-z0-9\-]+\z/, message: "must be lowercase, numbers, and dashes only" } + validates :label, presence: true, uniqueness: true validates_presence_of :field_type belongs_to :custom_field_section, counter_cache: :custom_fields_count @@ -12,4 +15,12 @@ def self.types "Date" ] end + + private + + def slugify_key + self.key = key.to_s.parameterize if key.present? + end + + end diff --git a/app/models/custom_field_section.rb b/app/models/custom_field_section.rb index 00b70f15..ec626193 100644 --- a/app/models/custom_field_section.rb +++ b/app/models/custom_field_section.rb @@ -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 diff --git a/app/models/service_meta.rb b/app/models/service_meta.rb index ec884597..96175f36 100644 --- a/app/models/service_meta.rb +++ b/app/models/service_meta.rb @@ -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 diff --git a/app/serializers/service_meta_serializer.rb b/app/serializers/service_meta_serializer.rb index c6f03512..b70b20a0 100644 --- a/app/serializers/service_meta_serializer.rb +++ b/app/serializers/service_meta_serializer.rb @@ -1,5 +1,6 @@ class ServiceMetaSerializer < ActiveModel::Serializer + attribute :label attribute :key attribute :value end \ No newline at end of file diff --git a/app/views/admin/custom_field_sections/_fields.html.erb b/app/views/admin/custom_field_sections/_fields.html.erb index 38f81cd2..701c2d57 100644 --- a/app/views/admin/custom_field_sections/_fields.html.erb +++ b/app/views/admin/custom_field_sections/_fields.html.erb @@ -39,7 +39,7 @@ diff --git a/app/views/admin/custom_field_sections/_repeatable-fields.html.erb b/app/views/admin/custom_field_sections/_repeatable-fields.html.erb index 0c413a81..efa2d02e 100644 --- a/app/views/admin/custom_field_sections/_repeatable-fields.html.erb +++ b/app/views/admin/custom_field_sections/_repeatable-fields.html.erb @@ -1,7 +1,7 @@
- <%= 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" %>
@@ -20,6 +20,15 @@ <%= c.text_area :hint, class: "field__input", rows: 1 %>
+<% if @section.api_public %> +
+ <%= c.label :key, "Key", class: "field__label" %> +

This is a unique field used to refer to this field in the API

+ <%= c.text_field :key, class: "field__input", data: { slugify: true } %> +
+<% end %> + + <%= c.hidden_field :_destroy, data: {destroy_field: true} %> \ No newline at end of file diff --git a/app/views/admin/services/editors/_custom-fields.html.erb b/app/views/admin/services/editors/_custom-fields.html.erb index e7a12746..d1367a83 100644 --- a/app/views/admin/services/editors/_custom-fields.html.erb +++ b/app/views/admin/services/editors/_custom-fields.html.erb @@ -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" %>
<%= 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" %>
<% else %>
- <%= c.label :value, field.key, class: "field__label" %> + <%= c.label :value, field.label, class: "field__label" %> <% if field.hint.present? %>

<%= field.hint %>

<% end %> diff --git a/config/routes.rb b/config/routes.rb index c8bbf451..c50a37ef 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/db/migrate/20241111163850_add_custom_field_label.rb b/db/migrate/20241111163850_add_custom_field_label.rb new file mode 100644 index 00000000..53b64363 --- /dev/null +++ b/db/migrate/20241111163850_add_custom_field_label.rb @@ -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 diff --git a/db/migrate/20241111181710_add_service_meta_label.rb b/db/migrate/20241111181710_add_service_meta_label.rb new file mode 100644 index 00000000..7eab7033 --- /dev/null +++ b/db/migrate/20241111181710_add_service_meta_label.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 32ba2452..49336f1a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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" @@ -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 @@ -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 From e0c5428d9739ad9860b6922989d3391c21ebc9b4 Mon Sep 17 00:00:00 2001 From: Han Date: Tue, 12 Nov 2024 18:21:35 +0000 Subject: [PATCH 3/5] key not required --- app/models/custom_field.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 9190cc05..21ce449b 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -1,7 +1,7 @@ class CustomField < ApplicationRecord before_validation :slugify_key - validates :key, uniqueness: true, format: { with: /\A[a-z0-9\-]+\z/, message: "must be lowercase, numbers, and dashes only" } + 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 From 253e326b8b815f6d6df7c276b4cb0c44a3dac2bd Mon Sep 17 00:00:00 2001 From: Han Date: Tue, 12 Nov 2024 18:34:22 +0000 Subject: [PATCH 4/5] fix tests --- lib/tasks/data_import/custom_fields/custom_fields.rake | 2 +- lib/tasks/data_import/services/import_services.rake | 2 +- spec/factories/custom_field.rb | 2 +- spec/tasks/data_import/services_spec.rb | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/tasks/data_import/custom_fields/custom_fields.rake b/lib/tasks/data_import/custom_fields/custom_fields.rake index f41a7eeb..124e01ff 100644 --- a/lib/tasks/data_import/custom_fields/custom_fields.rake +++ b/lib/tasks/data_import/custom_fields/custom_fields.rake @@ -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"], diff --git a/lib/tasks/data_import/services/import_services.rake b/lib/tasks/data_import/services/import_services.rake index 15a25068..650f2959 100644 --- a/lib/tasks/data_import/services/import_services.rake +++ b/lib/tasks/data_import/services/import_services.rake @@ -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 diff --git a/spec/factories/custom_field.rb b/spec/factories/custom_field.rb index 1ae24899..ac0393a2 100644 --- a/spec/factories/custom_field.rb +++ b/spec/factories/custom_field.rb @@ -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 diff --git a/spec/tasks/data_import/services_spec.rb b/spec/tasks/data_import/services_spec.rb index eb888116..08dc6111 100644 --- a/spec/tasks/data_import/services_spec.rb +++ b/spec/tasks/data_import/services_spec.rb @@ -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 From 5e690bad64b7b6515508bc052914a7ed128abf92 Mon Sep 17 00:00:00 2001 From: Han Date: Wed, 13 Nov 2024 09:36:43 +0000 Subject: [PATCH 5/5] fix tests --- lib/tasks/data_import/services/import_services.rake | 2 +- spec/factories/service_meta.rb | 2 +- spec/models/custom_field_spec.rb | 4 ++-- spec/models/service_meta_spec.rb | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/tasks/data_import/services/import_services.rake b/lib/tasks/data_import/services/import_services.rake index 650f2959..ca50bb1f 100644 --- a/lib/tasks/data_import/services/import_services.rake +++ b/lib/tasks/data_import/services/import_services.rake @@ -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?") diff --git a/spec/factories/service_meta.rb b/spec/factories/service_meta.rb index c5fe941f..2edf68c9 100644 --- a/spec/factories/service_meta.rb +++ b/spec/factories/service_meta.rb @@ -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 \ No newline at end of file diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb index 21d844fc..ca040e4f 100644 --- a/spec/models/custom_field_spec.rb +++ b/spec/models/custom_field_spec.rb @@ -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 diff --git a/spec/models/service_meta_spec.rb b/spec/models/service_meta_spec.rb index 7ecab145..04fed37a 100644 --- a/spec/models/service_meta_spec.rb +++ b/spec/models/service_meta_spec.rb @@ -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