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:
parent
b8ce85d58d
commit
fc86c30790
8 changed files with 173 additions and 2 deletions
|
|
@ -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" },
|
||||
|
|
|
|||
33
app/controllers/internal/profile_fields_controller.rb
Normal file
33
app/controllers/internal/profile_fields_controller.rb
Normal 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
|
||||
|
|
@ -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] }
|
||||
|
|
|
|||
20
app/views/internal/profile_fields/_form.html.erb
Normal file
20
app/views/internal/profile_fields/_form.html.erb
Normal 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>
|
||||
18
app/views/internal/profile_fields/index.html.erb
Normal file
18
app/views/internal/profile_fields/index.html.erb
Normal 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 %>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
95
spec/requests/internal/profile_fields_spec.rb
Normal file
95
spec/requests/internal/profile_fields_spec.rb
Normal 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
|
||||
Loading…
Add table
Reference in a new issue