Profile Admin UI Setup Screen (v1) (#9610)

* Add ProfileField model

* Fix schema.rb

* Add service objects for base and link fields

* feat: show an index of profile fields and allow them to be edited

* Fix schema.rb

* Add service objects for base and link fields

* Add link fields to seeds

* Make placeholder a keyword argument

* Add work fields

* Add explanation column to profile fields

* Add coding fields

* Switch from inheritance to mixin

* Add email checkbox to base fields

* Add branding fields

* Add spec for ProfileFields::FieldDefinition

* chore: moved the migration file

* feat: add a create and destroy route

* feat: render a partial form

* fix: oops form instead of f

* Move migration back into correct location

* Rename column from explanation to description

* Rename attribute in mixin

* chore: update classed for buttons

* chore: rename from explanation to description

* chore: explanation to description

* chore: new profie field

* fix: only one submit button per form

* fix: update the form

* fix: remove files that got merged mistakenly

* chore: finally, some specs...

Co-authored-by: Michael Kohl <citizen428@dev.to>
This commit is contained in:
Ridhwana 2020-08-06 09:26:17 +02:00 committed by GitHub
parent b8ce85d58d
commit fc86c30790
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 173 additions and 2 deletions

View file

@ -22,6 +22,7 @@ module Internal
{ name: "pages", controller: "pages" },
{ name: "permissions", controller: "permissions" },
{ name: "podcasts", controller: "podcasts" },
{ name: "profile setup", controller: "profile_fields" },
{ name: "reports", controller: "reports" },
{ name: "response_templates", controller: "response_templates" },
{ name: "sponsorships", controller: "sponsorships" },

View file

@ -0,0 +1,33 @@
module Internal
class ProfileFieldsController < Internal::ApplicationController
layout "internal"
def index
@profile_fields = ProfileField.all
end
def update
@profile_fields = ProfileField.find(params[:id])
@profile_fields.update!(profile_field_params)
redirect_to internal_profile_fields_path
end
def create
@profile_field = ProfileField.create(profile_field_params)
redirect_to internal_profile_fields_path
end
def destroy
@profile_field = ProfileField.find(params[:id])
@profile_field.destroy
redirect_to internal_profile_fields_path
end
private
def profile_field_params
allowed_params = %i[input_type label active placeholder_text description]
params.require(:profile_field).permit(allowed_params)
end
end
end

View file

@ -1,11 +1,13 @@
class ProfileField < ApplicationRecord
# Key names follow the Rails form helpers
enum input_type: {
INPUT_TYPES = {
text_field: 0,
text_area: 1,
check_box: 2,
color_field: 3
}
}.freeze
enum input_type: INPUT_TYPES
validates :label, presence: true, uniqueness: { case_sensitive: false }
validates :active, inclusion: { in: [true, false] }

View file

@ -0,0 +1,20 @@
<div class="form-group">
<%= form.label :label %>
<%= form.text_field :label, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :description %>
<%= form.text_field :description, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :placeholder_text %>
<%= form.text_field :placeholder_text, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :input_type %>
<%= form.select :input_type, ProfileField::INPUT_TYPES.keys, class: "form-control" %>
</div>
<div class="form-group">
<%= form.label :active %>
<%= form.check_box :active %>
</div>

View file

@ -0,0 +1,18 @@
<div class="crayons-card grid p-6 mb-6 gap-1">
<%= form_for [:internal, ProfileField.new], html: { class: "inline-form" } do |form| %>
<div class="form-group">
<%= render "form", form: form %>
<%= form.submit class: "btn btn-primary" %>
</div>
<% end %>
</div>
<% @profile_fields.each do |field| %>
<div class="crayons-card grid p-6 mb-6 gap-1">
<%= form_for [:internal, field] do |form| %>
<%= render "form", form: form %>
<%= form.submit class: "btn btn-primary" %>
<% end %>
<%= button_to "Delete", internal_profile_field_path(field), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-secondary" %>
</div>
<% end %>

View file

@ -70,6 +70,7 @@ Rails.application.routes.draw do
delete :remove_admin
end
end
resources :profile_fields, only: %i[index update create destroy]
resources :reactions, only: [:update]
resources :response_templates, only: %i[index new edit create update destroy]
resources :chat_channels, only: %i[index create update] do

View file

@ -2,6 +2,7 @@ FactoryBot.define do
factory :profile_field do
sequence(:label) { |n| "Email #{n}" }
input_type { :text_field }
description { "some description" }
placeholder_text { "john.doe@example.com" }
active { true }
end

View file

@ -0,0 +1,95 @@
require "rails_helper"
RSpec.describe "/internal/profile_fields", type: :request do
include ActiveJob::TestHelper
let(:user) { create(:user) }
before do
user.add_role(:super_admin)
sign_in user
end
describe "GET /internal/profile_fields" do
let(:profile_field) { create(:profile_field) }
it "renders successfully" do
get internal_profile_fields_path
expect(response).to be_successful
end
it "lists the profile fields" do
profile_field
get internal_profile_fields_path
expect(response.body).to include(
profile_field.label,
profile_field.input_type,
profile_field.description,
profile_field.placeholder_text
)
end
end
describe "POST /internal/profile_fields" do
let(:new_profile_field) do
{
label: "Location",
input_type: "text_field",
description: "users' location",
placeholder_text: "new york",
active: false
}
end
it "redirects successfully" do
post internal_profile_fields_path, params: { profile_field: new_profile_field }
expect(response).to redirect_to internal_profile_fields_path
end
it "creates a profile_field" do
expect do
post internal_profile_fields_path, params: { profile_field: new_profile_field }
end.to change { ProfileField.all.count }.by(1)
last_profile_field_record = ProfileField.last
expect(last_profile_field_record.label).to eq(new_profile_field[:label])
expect(last_profile_field_record.input_type).to eq(new_profile_field[:input_type])
expect(last_profile_field_record.description).to eq(new_profile_field[:description])
expect(last_profile_field_record.placeholder_text).to eq(new_profile_field[:placeholder_text])
expect(last_profile_field_record.active).to eq(new_profile_field[:active])
end
end
describe "PUT /internal/profile_fields/:id" do
let(:profile_field) { create(:profile_field) }
it "redirects successfully" do
put "#{internal_profile_fields_path}/#{profile_field.id}",
params: { profile_field: { active: false }}
expect(response).to redirect_to internal_profile_fields_path
end
it "updates the profile field values" do
put "#{internal_profile_fields_path}/#{profile_field.id}",
params: { profile_field: { active: false }}
changed_profile_record = ProfileField.find(profile_field.id)
expect(changed_profile_record.active).to be(false)
end
end
describe "DELETE /internal/profile_fields/:id" do
let(:profile_field) { create(:profile_field) }
it "redirects successfully" do
delete "#{internal_profile_fields_path}/#{profile_field.id}"
expect(response).to redirect_to internal_profile_fields_path
end
it "removes a profile field" do
delete "#{internal_profile_fields_path}/#{profile_field.id}"
expect(ProfileField.count).to eq(0)
end
end
end