Skip to content

Commit

Permalink
Add Note model and basic admin controller actions
Browse files Browse the repository at this point in the history
This is the start of #4478
  • Loading branch information
gbp committed Aug 11, 2022
1 parent c08a5cb commit a4fd508
Show file tree
Hide file tree
Showing 12 changed files with 432 additions and 0 deletions.
53 changes: 53 additions & 0 deletions app/controllers/admin/notes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class Admin::NotesController < AdminController
include Admin::TagHelper
include TranslatableParams

def new
@note = Note.new
@note.build_all_translations
end

def create
@note = Note.new(note_params)
if @note.save
notice = 'Note successfully created.'
redirect_to admin_note_parent_path(@note), notice: notice
else
@note.build_all_translations
render :new
end
end

def edit
@note = Note.find(params[:id])
@note.build_all_translations
end

def update
@note = Note.find(params[:id])
if @note.update(note_params)
notice = 'Note successfully updated.'
redirect_to admin_note_parent_path(@note), notice: notice
else
@note.build_all_translations
render :edit
end
end

def destroy
@note = Note.find(params[:id])
@note.destroy
notice = 'Note successfully destroyed.'
redirect_to admin_note_parent_path(@note), notice: notice
end

private

def note_params
translatable_params(
params.require(:note),
translated_keys: [:locale, :body],
general_keys: [:notable_id, :notable_type]
)
end
end
24 changes: 24 additions & 0 deletions app/models/note.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# == Schema Information
# Schema version: 20220720085105
#
# Table name: notes
#
# id :bigint not null, primary key
# notable_type :string
# notable_id :bigint
# notable_tag :string
# created_at :datetime not null
# updated_at :datetime not null
# body :text
#

class Note < ApplicationRecord
include AdminColumn

translates :body
include Translatable

belongs_to :notable, polymorphic: true

validates :body, presence: true
end
27 changes: 27 additions & 0 deletions app/views/admin/notes/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%= foi_error_messages_for :note %>

<div id="div-locales">
<ul class="locales nav nav-tabs">
<% @note.ordered_translations.each do |translation| %>
<li>
<a href="#div-locale-<%= translation.locale.to_s %>" data-toggle="tab" >
<%= locale_name(translation.locale.to_s) || translation.locale.to_s %>
</a>
</li>
<% end %>
</ul>

<div class="tab-content">
<% @note.ordered_translations.each do |translation| %>
<% if AlaveteliLocalization.default_locale?(translation.locale) %>
<%= fields_for('note', @note) do |t| %>
<%= render partial: 'locale_fields', locals: { t: t, locale: translation.locale } %>
<% end %>
<% else %>
<%= f.fields_for(:translations, translation, child_index: translation.locale) do |t| %>
<%= render partial: 'locale_fields', locals: { t: t, locale: translation.locale } %>
<% end %>
<% end %>
<% end %>
</div>
</div>
16 changes: 16 additions & 0 deletions app/views/admin/notes/_locale_fields.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="tab-pane" id="div-locale-<%= locale %>">
<div class="control-group">
<%= t.hidden_field :locale, :value => locale %>
<%= t.label :body, class: 'control-label' %>
<div class="controls">
<% if AlaveteliLocalization.default_locale?(locale) && t.object.errors[:body].any? %>
<span class="fieldWithErrors">
<% end %>
<%= t.text_area :body, class: 'span6', rows: 10 %>
<% if AlaveteliLocalization.default_locale?(locale) && t.object.errors[:body].any? %>
</span>
<%end %>
</div>
</div>
</div>
24 changes: 24 additions & 0 deletions app/views/admin/notes/_note.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="accordion-group">
<div class="accordion-heading accordion-toggle row">
<span class="item-title span6">
<%= link_to chevron_right, "##{dom_id(note)}", data: { toggle: 'collapse', parent: 'notes' } %>
<%= link_to(note.body, edit_admin_note_path(note), title: 'view full details') %>
</span>

<span class="item-metadata span6">
<%= render_tag note.notable_tag if note.notable_tag %>
</span>
</div>
<%= tag.div id: dom_id(note), class: 'item-detail accordion-body collapse row' do %>
<% note.for_admin_column do |name, value, type| %>
<div>
<span class="span6">
<b><%= name %></b>
</span>
<span class="span6">
<%= admin_value(value) %>
</span>
</div>
<% end %>
<% end %>
</div>
21 changes: 21 additions & 0 deletions app/views/admin/notes/edit.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="row">
<div class="span12">
<div class="page-header">
<h1><%= @title = 'Edit note' %></h1>
</div>
</div>
</div>

<%= form_for [:admin, @note], class: 'form form-horizontal' do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<div class="form-actions">
<%= submit_tag 'Save', class: 'btn btn-success' %>
</div>
<% end %>
<%= form_tag [:admin, @note], class: 'form form-inline', method: 'delete' do %>
<%= submit_tag 'Destroy note',
class: 'btn btn-danger',
data: { confirm: 'Are you sure? This is irreversible.' } %>
(this is permanent!)
<% end %>
14 changes: 14 additions & 0 deletions app/views/admin/notes/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div class="row">
<div class="span12">
<div class="page-header">
<h1><%= @title = 'New note' %></h1>
</div>
</div>
</div>

<%= form_for [:admin, @note], class: 'form form-horizontal' do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<div class="form-actions">
<%= submit_tag 'Create', class: 'btn btn-success' %>
</div>
<% end %>
10 changes: 10 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,16 @@
end
####

#### AdminNote controller
namespace :admin do
resources :notes, except: [:index, :show]
end

direct :admin_note_parent do |note|
admin_general_index_path
end
####

#### AdminPublicBody controller
scope '/admin', :as => 'admin' do
resources :bodies,
Expand Down
19 changes: 19 additions & 0 deletions db/migrate/20220720085105_create_notes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class CreateNotes < ActiveRecord::Migration[6.1]
def change
create_table :notes do |t|
t.references :notable, polymorphic: true
t.string :notable_tag
t.timestamps
end

reversible do |dir|
dir.up do
Note.create_translation_table!(body: :text)
end

dir.down do
Note.drop_translation_table!
end
end
end
end
153 changes: 153 additions & 0 deletions spec/controllers/admin/notes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
require 'spec_helper'

RSpec.describe Admin::NotesController do
before(:each) { basic_auth_login(@request) }

describe 'GET new' do
before { get :new }

it 'returns a successful response' do
expect(response).to be_successful
end

it 'assigns the note' do
expect(assigns[:note]).to be_a(Note)
end

it 'renders the correct template' do
expect(response).to render_template(:new)
end
end

describe 'POST #create' do
before do
post :create, params: params
end

context 'on a successful create' do
let(:params) do
{ note: { body: 'New body' } }
end

it 'assigns the note' do
expect(assigns[:note]).to be_a(Note)
end

it 'creates the note' do
expect(assigns[:note].body).to eq('New body')
end

it 'sets a notice' do
expect(flash[:notice]).to eq('Note successfully created.')
end

it 'redirects to the general index' do
expect(response).to redirect_to(admin_general_index_path)
end
end

context 'on an unsuccessful create' do
let(:params) do
{ note: { body: '' } }
end

it 'assigns the note' do
expect(assigns[:note]).to be_a(Note)
end

it 'does not create the note' do
expect(assigns[:note]).to be_new_record
end

it 'renders the form again' do
expect(response).to render_template(:new)
end
end
end

describe 'GET edit' do
let!(:note) { FactoryBot.create(:note) }

before { get :edit, params: { id: note.id } }

it 'returns a successful response' do
expect(response).to be_successful
end

it 'assigns the note' do
expect(assigns[:note]).to eq(note)
end

it 'renders the correct template' do
expect(response).to render_template(:edit)
end
end

describe 'PATCH #update' do
let!(:note) { FactoryBot.create(:note) }

before do
patch :update, params: params
end

context 'on a successful update' do
let(:params) do
{ id: note.id, note: { body: 'New body' } }
end

it 'assigns the note' do
expect(assigns[:note]).to eq(note)
end

it 'updates the note' do
expect(note.reload.body).to eq('New body')
end

it 'sets a notice' do
expect(flash[:notice]).to eq('Note successfully updated.')
end

it 'redirects to the general index' do
expect(response).to redirect_to(admin_general_index_path)
end
end

context 'on an unsuccessful update' do
let(:params) do
{ id: note.id, note: { body: '' } }
end

it 'assigns the note' do
expect(assigns[:note]).to eq(note)
end

it 'does not update the note' do
expect(note.reload.body).not_to be_blank
end

it 'renders the form again' do
expect(response).to render_template(:edit)
end
end
end

describe 'DELETE #destroy' do
let!(:note) { FactoryBot.create(:note) }

it 'destroys the note' do
allow(Note).to receive(:find).and_return(note)
expect(note).to receive(:destroy)
delete :destroy, params: { id: note.id }
end

it 'sets a notice' do
delete :destroy, params: { id: note.id }
expect(flash[:notice]).to eq('Note successfully destroyed.')
end

it 'redirects to the general index' do
delete :destroy, params: { id: note.id }
expect(response).to redirect_to(admin_general_index_path)
end
end
end
Loading

0 comments on commit a4fd508

Please sign in to comment.