feat(announce): super admin can create announce

This commit is contained in:
Colin Darie 2023-10-03 16:20:13 +02:00
parent 0d626f1811
commit ff8ed6016e
No known key found for this signature in database
GPG key ID: 8C76CADD40253590
12 changed files with 234 additions and 2 deletions

View file

@ -0,0 +1,52 @@
class SuperAdmins::ReleaseNotesController < ApplicationController
before_action :authenticate_super_admin!
before_action :set_note, only: [:edit, :update]
def index
@release_notes = ReleaseNote
.order(released_on: :desc, id: :asc)
.with_rich_text_body
end
def show
# allows refreshing a submitted page in error
redirect_to edit_super_admins_release_note_path(params[:id])
end
def new
@release_note = ReleaseNote.new(released_on: Date.current)
end
def create
@release_note = ReleaseNote.new(release_note_params)
if @release_note.save
redirect_to edit_super_admins_release_note_path(@release_note), notice: t('.success')
else
flash.now[:alert] = [t('.error'), @release_note.errors.full_messages].flatten
render :new
end
end
def edit
@release_note = ReleaseNote.find(params[:id])
end
def update
if @release_note.update(release_note_params)
redirect_to edit_super_admins_release_note_path(@release_note), notice: t('.success')
else
flash.now[:alert] = [t('.error'), @release_note.errors.full_messages].flatten
render :edit
end
end
private
def release_note_params
params.require(:release_note).permit(:released_on, :published, :body, categories: [])
end
def set_note
@release_note = ReleaseNote.find(params[:id])
end
end

View file

@ -1,2 +1,14 @@
class ReleaseNote < ApplicationRecord class ReleaseNote < ApplicationRecord
has_rich_text :body
CATEGORIES = [
'administrateur',
'instructeur',
'expert',
'usager',
'api'
]
validates :categories, presence: true, inclusion: { in: CATEGORIES }
validates :body, presence: true
end end

View file

@ -0,0 +1,30 @@
= form_for [:super_admins, release_note] do |f|
%fieldset#release_notes_fieldset.fr-fieldset{ 'data-controller': 'trix' }
.fr-fieldset__element
= render Dsfr::InputComponent.new(form: f, attribute: :released_on, input_type: :date_field)
.fr-fieldset__element
.fr-toggle
= f.check_box :published, class: "fr-toggle-input", id: dom_id(release_note, :published)
%label.fr-toggle__label{ for: dom_id(release_note, :published), data: { fr_checked_label: "Publié", fr_unchecked_label: "Brouillon" } }
Publier
.fr-fieldset__element
%fieldset.fr-fieldset{ "aria-labelledby": dom_id(release_note, :category_legend) }
%legend.fr-fieldset__legend.fr-fieldset__legend--regular{ id: dom_id(release_note, :category_legend) }
Catégories
- ReleaseNote::CATEGORIES.each do |category|
.fr-fieldset__element.fr-fieldset__element--inline
.fr-checkbox-group
= f.check_box :categories, { multiple: true, include_hidden: false, id: dom_id(release_note, "category_#{category}"), "aria-describedby" => "#{dom_id(release_note, "category_#{category}_messages")}" }, category, nil
%label.fr-label{ for: dom_id(release_note, "category_#{category}") }
= category.humanize
.fr-fieldset__element
.fr-input-group
= render Dsfr::InputComponent.new(form: f, attribute: :body, input_type: :rich_text_area)
.fr-fieldset__element
= f.submit "Valider", class: "fr-btn fr-btn--lg"

View file

@ -0,0 +1,6 @@
.fr-container.fr-my-5w
.fr-grid-row.fr-grid-row--center
.fr-col-lg-10
%h1.fr-h2 Annonce
= render partial: 'form', object: @release_note, as: :release_note

View file

@ -0,0 +1,24 @@
.fr-container.fr-my-5w
.fr-grid-row.fr-grid-row--center
.fr-col-lg-10
%h1.fr-h2 Liste des annonces
= link_to("Créer une annonce", new_super_admins_release_note_path, class: "fr-btn")
%table.fr-table
%thead
%th Annoncé le
%th Publié?
%th Actions
%tbody
- @release_notes.each do |note|
%tr
%td= l(note.released_on) if note.released_on
%td
- if note.published?
%span.fr-badge.fr-badge--success.fr-badge--no-icon Publié
- else
%span.fr-badge.fr-badge--warning.fr-badge--no-icon Brouillon
%td
= link_to 'Modifier', edit_super_admins_release_note_path(note), class: 'fr-btn fr-btn--secondary'

View file

@ -0,0 +1,5 @@
.fr-container.fr-my-5w
.fr-grid-row.fr-grid-row--center
.fr-col-lg-10
%h1.fr-h2 Nouvelle Annonce
= render ReleaseNote::FormComponent.new(release_note: @release_note)

View file

@ -0,0 +1,16 @@
---
en:
super_admins:
release_notes:
create: &save
success: Release note was successfully saved.
error: Release note was not saved.
update:
<<: *save
activerecord:
attributes:
release_note:
body: Announce
categories: Categories
released_on: Publication date

View file

@ -0,0 +1,16 @@
---
fr:
super_admins:
release_notes:
create: &save
success: Lannonce a été sauvegardée.
error: Lannonce na pas pu être sauvegardée.
update:
<<: *save
activerecord:
attributes:
release_note:
body: Annonce
categories: Catégories
released_on: Date de publication

View file

@ -125,6 +125,10 @@ Rails.application.routes.draw do
passwords: 'super_admins/passwords' passwords: 'super_admins/passwords'
} }
namespace :super_admins do
resources :release_notes, only: [:index, :new, :create, :edit, :update, :show]
end
get 'super_admins/edit_otp', to: 'super_admins#edit_otp', as: 'edit_super_admin_otp' get 'super_admins/edit_otp', to: 'super_admins#edit_otp', as: 'edit_super_admin_otp'
put 'super_admins/enable_otp', to: 'super_admins#enable_otp', as: 'enable_super_admin_otp' put 'super_admins/enable_otp', to: 'super_admins#enable_otp', as: 'enable_super_admin_otp'

View file

@ -2,7 +2,6 @@ class CreateReleaseNotes < ActiveRecord::Migration[7.0]
def change def change
create_table :release_notes do |t| create_table :release_notes do |t|
t.date :released_on t.date :released_on
t.text :body, default: nil
t.boolean :published, default: false, null: false t.boolean :published, default: false, null: false
t.string :categories, array: true, default: [] t.string :categories, array: true, default: []

View file

@ -897,7 +897,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_26_161609) do
end end
create_table "release_notes", force: :cascade do |t| create_table "release_notes", force: :cascade do |t|
t.text "body"
t.string "categories", default: [], array: true t.string "categories", default: [], array: true
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.boolean "published", default: false, null: false t.boolean "published", default: false, null: false
@ -905,6 +904,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_26_161609) do
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["categories"], name: "index_release_notes_on_categories", using: :gin t.index ["categories"], name: "index_release_notes_on_categories", using: :gin
t.index ["published"], name: "index_release_notes_on_published" t.index ["published"], name: "index_release_notes_on_published"
t.index ["released_on"], name: "index_release_notes_on_released_on"
end end
create_table "safe_mailers", force: :cascade do |t| create_table "safe_mailers", force: :cascade do |t|

View file

@ -0,0 +1,68 @@
require 'rails_helper'
describe SuperAdmins::ReleaseNotesController, type: :controller do
let(:super_admin) { create(:super_admin) }
before do
sign_in super_admin if super_admin.present?
end
describe "acl" do
context 'when user is not signed as super admin' do
let(:super_admin) { nil }
let!(:release_note) { create(:release_note, published: false) }
it 'is not allowed to post' do
expect { post :create, params: { release_note: { released_on: Date.current, published: "0", body: "bam" } } }.not_to change(ReleaseNote, :count)
expect(response.status).to eq(302)
expect(flash[:alert]).to be_present
end
it 'is not allowed to put' do
expect {
put :update, params: {
id: release_note.id,
release_note: {
released_on: Date.current,
published: "1",
categories: release_note.categories,
body: "hacked body"
}
}
}.not_to change { release_note.reload.body }
expect(response.status).to eq(302)
expect(flash[:alert]).to be_present
end
it 'is not allowed to index' do
get :index
expect(response.status).to eq(302)
expect(flash[:alert]).to be_present
end
end
context 'when user is signed as super admin' do
it 'is allowed to post' do
expect { post :create, params: { release_note: { categories: ['api'], released_on: Date.current, published: "0", body: "bam" } } }.to change(ReleaseNote, :count).by(1)
expect(flash[:notice]).to be_present
end
it 'is allowed to put' do
release_note = create(:release_note, published: false)
put :update, params: {
id: release_note.id,
release_note: {
released_on: Date.current,
published: "1",
categories: release_note.categories,
body: "new body"
}
}
release_note.reload
expect(release_note.body.to_plain_text).to eq("new body")
expect(release_note.published).to be_truthy
end
end
end
end