diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index e12d9258b..c4063d8a3 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -61,3 +61,35 @@ margin: 1em 0; text-align: end; } + +#profileFields { + .card-header { + display: flex; + align-items: center; + justify-content: space-between; + } + + .card-header__actions { + display: flex; + justify-content: space-between; + } + + .card-header__information { + display: flex; + align-items: center; + } + + .group__description { + color: $medium-gray; + width: 150px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-left: 16px; + } + + .card-header__actions > div { + margin: 0 16px; + cursor: pointer; + } +} diff --git a/app/controllers/admin/profile_field_groups_controller.rb b/app/controllers/admin/profile_field_groups_controller.rb new file mode 100644 index 000000000..b1cdf971a --- /dev/null +++ b/app/controllers/admin/profile_field_groups_controller.rb @@ -0,0 +1,47 @@ +module Admin + class ProfileFieldGroupsController < Admin::ApplicationController + ALLOWED_PARAMS = %i[ + name description + ].freeze + layout "admin" + + def update + profile_field_group = ProfileFieldGroup.find(params[:id]) + if profile_field_group.update(profile_field_group_params) + flash[:success] = "Group #{profile_field_group.name} updated" + else + flash[:error] = "Error: #{profile_field_group.errors_as_sentence}" + end + redirect_to admin_profile_fields_path + end + + def create + profile_field_group = ProfileFieldGroup.new(profile_field_group_params) + if profile_field_group.save + flash[:success] = "Successfully created group: #{profile_field_group.name}" + else + flash[:error] = "Error: #{profile_field_group.errors_as_sentence}" + end + redirect_to admin_profile_fields_path + end + + def destroy + profile_field_group = ProfileFieldGroup.find(params[:id]) + if profile_field_group.destroy + flash[:success] = "Group #{profile_field_group.name} deleted" + else + flash[:error] = "Error: #{profile_field_group.errors_as_sentence}" + end + redirect_to admin_profile_fields_path + end + + private + + private_constant :ALLOWED_PARAMS + + def profile_field_group_params + allowed_params = ALLOWED_PARAMS + params.require(:profile_field_group).permit(allowed_params) + end + end +end diff --git a/app/controllers/admin/profile_fields_controller.rb b/app/controllers/admin/profile_fields_controller.rb index fdeeb5722..b98d177f5 100644 --- a/app/controllers/admin/profile_fields_controller.rb +++ b/app/controllers/admin/profile_fields_controller.rb @@ -1,12 +1,13 @@ module Admin class ProfileFieldsController < Admin::ApplicationController ALLOWED_PARAMS = %i[ - input_type label active placeholder_text description group + input_type label active placeholder_text description profile_field_group_id ].freeze layout "admin" def index - @grouped_profile_fields = ProfileFieldGroup.all.includes(:profile_fields) + @grouped_profile_fields = ProfileFieldGroup.all.includes(:profile_fields).order(:name) + @ungrouped_profile_fields = ProfileField.where(profile_field_group_id: nil).order(:label) end def update diff --git a/app/views/admin/profile_fields/_add_group_modal.html.erb b/app/views/admin/profile_fields/_add_group_modal.html.erb new file mode 100644 index 000000000..cb64b42b2 --- /dev/null +++ b/app/views/admin/profile_fields/_add_group_modal.html.erb @@ -0,0 +1,50 @@ + + + + + diff --git a/app/views/admin/profile_fields/_add_profile_field_modal.html.erb b/app/views/admin/profile_fields/_add_profile_field_modal.html.erb new file mode 100644 index 000000000..54b488000 --- /dev/null +++ b/app/views/admin/profile_fields/_add_profile_field_modal.html.erb @@ -0,0 +1,43 @@ +
+ Add Field +
+ + + + diff --git a/app/views/admin/profile_fields/_edit_group_modal.html.erb b/app/views/admin/profile_fields/_edit_group_modal.html.erb new file mode 100644 index 000000000..45a12028c --- /dev/null +++ b/app/views/admin/profile_fields/_edit_group_modal.html.erb @@ -0,0 +1,50 @@ +
+ Edit group +
+ + + + diff --git a/app/views/admin/profile_fields/_group_form.erb b/app/views/admin/profile_fields/_group_form.erb deleted file mode 100644 index 11806375a..000000000 --- a/app/views/admin/profile_fields/_group_form.erb +++ /dev/null @@ -1,36 +0,0 @@ -
-
- <%= form.label :group %> - <%= select_tag "profile_field[group]", - select_option_tags, - select_options %> - <%= form.text_field :group, placeholder: "Add a new group", class: "form-control profile__group-text-input hidden", disabled: true %> -
-
- <%= toggle_text %> -
-
- - diff --git a/app/views/admin/profile_fields/_grouped_profile_fields.html.erb b/app/views/admin/profile_fields/_grouped_profile_fields.html.erb new file mode 100644 index 000000000..a23c29418 --- /dev/null +++ b/app/views/admin/profile_fields/_grouped_profile_fields.html.erb @@ -0,0 +1,52 @@ +<% @grouped_profile_fields.each do |group| %> + <% group_name = group.name.gsub(/\s+/, "_") %> +
+
+
+
+
<%= group_name %>
+
 (<%= group.profile_fields.length %>)
+ <% if group.description %> +
<%= group.description %>
+ <% end %> +
+ +
+ <%= render partial: "add_profile_field_modal", locals: { group: group, group_name: group_name } %> + <%= render partial: "edit_group_modal", locals: { group: group, group_name: group_name } %> +
<%= link_to "Delete Group", admin_profile_field_group_path(group), data: { confirm: "Are you sure?" }, method: :delete, class: "color-accent-danger" %>
+ +
+
+ +
+ + <% if group.profile_fields.empty? %> +
There are no profile fields configured for this group.
+ <% else %> + <% group.profile_fields.each do |field| %> +
+ <%= render partial: "admin/configs/card_header", + locals: { + header: field.label, + state: "collapse", + target: "#{field.attribute_name}_container", + expanded: "false" + } %> +
+
+ <%= form_for [:admin, field] do |form| %> + <%= render "profile_field_form", form: form, group: group %> + <%= form.submit class: "btn btn-primary" %> + <% end %> + <%= button_to "Delete Profile Field", admin_profile_field_path(field), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-secondary" %> +
+
+
+ <% end %> + <% end %> +
+
+
+<% end %> diff --git a/app/views/admin/profile_fields/_form.html.erb b/app/views/admin/profile_fields/_profile_field_form.html.erb similarity index 55% rename from app/views/admin/profile_fields/_form.html.erb rename to app/views/admin/profile_fields/_profile_field_form.html.erb index 14d64e70f..c175c2a17 100644 --- a/app/views/admin/profile_fields/_form.html.erb +++ b/app/views/admin/profile_fields/_profile_field_form.html.erb @@ -1,3 +1,14 @@ +
+ <%= form.label :group %> + <%= select_tag "profile_field[profile_field_group_id]", + options_from_collection_for_select( + ProfileFieldGroup.all, + :id, :name, + selected: group&.id + ), + { class: "form-control selectpicker profile__group-dropdown", + include_blank: "" } %> +
<%= form.label :label %> <%= form.text_field :label, class: "form-control" %> diff --git a/app/views/admin/profile_fields/_ungrouped_profile_fields.html.erb b/app/views/admin/profile_fields/_ungrouped_profile_fields.html.erb new file mode 100644 index 000000000..811a5631e --- /dev/null +++ b/app/views/admin/profile_fields/_ungrouped_profile_fields.html.erb @@ -0,0 +1,22 @@ +<% @ungrouped_profile_fields.each do |field| %> +
+
+ <%= render partial: "admin/configs/card_header", + locals: { + header: field.label, + state: "collapse", + target: "#{field.attribute_name}_container", + expanded: "false" + } %> +
+
+ <%= form_for [:admin, field] do |form| %> + <%= render "profile_field_form", form: form, group: nil %> + <%= form.submit class: "btn btn-primary" %> + <% end %> + <%= button_to "Delete Profile Field", admin_profile_field_path(field), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-secondary" %> +
+
+
+
+<% end %> diff --git a/app/views/admin/profile_fields/index.html.erb b/app/views/admin/profile_fields/index.html.erb index e0359d5f8..bd193562b 100644 --- a/app/views/admin/profile_fields/index.html.erb +++ b/app/views/admin/profile_fields/index.html.erb @@ -1,41 +1,6 @@ -
-

Profile fields

-
+
+ <%= render "add_group_modal" %> -<% @grouped_profile_fields.each do |group| %> - <% group_name = group.name.gsub(/\s+/, "_") %> -
- -
- <% group.profile_fields.each do |field| %> -
- <%= render partial: "admin/configs/card_header", - locals: { - header: field.label, - state: "collapse", - target: "#{field.attribute_name}_container", - expanded: "false" - } %> -
-
- <%= form_for [:admin, field] do |form| %> - <%= render "form", form: form %> - <%= form.submit class: "btn btn-primary" %> - <% end %> - <%= button_to "Delete Profile Field", admin_profile_field_path(field), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-secondary" %> -
-
-
- <% end %> -
-
-<% end %> + <%= render "grouped_profile_fields" %> + <%= render "ungrouped_profile_fields" %> +
diff --git a/config/routes.rb b/config/routes.rb index 7fef6b05a..fa7cfd65b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -73,6 +73,8 @@ Rails.application.routes.draw do delete :remove_admin end end + + resources :profile_field_groups, only: %i[update create destroy] resources :profile_fields, only: %i[index update create destroy] resources :reactions, only: [:update] resources :response_templates, only: %i[index new edit create update destroy] diff --git a/spec/requests/admin/profile_field_groups_spec.rb b/spec/requests/admin/profile_field_groups_spec.rb new file mode 100644 index 000000000..1c58d479d --- /dev/null +++ b/spec/requests/admin/profile_field_groups_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" + +RSpec.describe "/admin/profile_field_groups", type: :request do + let(:admin) { create(:user, :super_admin) } + + before do + sign_in admin + end + + describe "POST /admin/profile_field_groups" do + let(:new_profile_field_group) do + { + name: "Group 1", + description: "Description" + } + end + + it "redirects successfully" do + post admin_profile_field_groups_path, params: { profile_field_group: new_profile_field_group } + expect(response).to redirect_to admin_profile_fields_path + end + + it "creates a profile_field_group" do + expect do + post admin_profile_field_groups_path, params: { profile_field_group: new_profile_field_group } + end.to change { ProfileFieldGroup.all.count }.by(1) + + last_profile_field_record = ProfileFieldGroup.last + expect(last_profile_field_record.name).to eq(new_profile_field_group[:name]) + expect(last_profile_field_record.description).to eq(new_profile_field_group[:description]) + end + end + + describe "PUT /admin/profile_field_groups/:id" do + let(:profile_field_group) { create(:profile_field_group) } + + it "redirects successfully" do + put "#{admin_profile_field_groups_path}/#{profile_field_group.id}", + params: { profile_field_group: { name: "Group 2" } } + expect(response).to redirect_to admin_profile_fields_path + end + + it "updates the profile field values" do + put "#{admin_profile_field_groups_path}/#{profile_field_group.id}", + params: { profile_field_group: { name: "Group 2" } } + + changed_profile_group_record = ProfileFieldGroup.find(profile_field_group.id) + expect(changed_profile_group_record.name).to eq("Group 2") + end + end + + describe "DELETE /admin/profile_fields/:id" do + let(:profile_field_group) { create(:profile_field_group) } + + it "redirects successfully" do + delete "#{admin_profile_field_groups_path}/#{profile_field_group.id}" + expect(response).to redirect_to admin_profile_fields_path + end + + it "removes a profile_field_group" do + delete "#{admin_profile_field_groups_path}/#{profile_field_group.id}" + expect(ProfileFieldGroup.count).to eq(0) + end + end +end