diff --git a/app/assets/stylesheets/new_design/card.scss b/app/assets/stylesheets/new_design/card.scss index 5506635af..c73875b2e 100644 --- a/app/assets/stylesheets/new_design/card.scss +++ b/app/assets/stylesheets/new_design/card.scss @@ -7,6 +7,13 @@ margin-bottom: $default-spacer * 2; background: #FFFFFF; + .notice { + font-size: 16px; + color: #666666; + margin-top: -8px; + margin-bottom: 16px; + } + .card-title { font-weight: bold; font-size: 20px; diff --git a/app/assets/stylesheets/new_design/helpers.scss b/app/assets/stylesheets/new_design/helpers.scss index f8f0f71bf..e82b9d548 100644 --- a/app/assets/stylesheets/new_design/helpers.scss +++ b/app/assets/stylesheets/new_design/helpers.scss @@ -12,6 +12,14 @@ margin-bottom: 4 * $default-spacer; } +.ml-1 { + margin-left: $default-spacer; +} + +.pl-0 { + padding-left: 0px !important; +} + .numbers-delimiter { display: inline-block; width: 5px; diff --git a/app/assets/stylesheets/new_design/procedure_admin.scss b/app/assets/stylesheets/new_design/procedure_admin.scss index 28a3764cb..0227b3772 100644 --- a/app/assets/stylesheets/new_design/procedure_admin.scss +++ b/app/assets/stylesheets/new_design/procedure_admin.scss @@ -14,6 +14,23 @@ } } +.procedure-admin-listing-container { + display: flex; + justify-content: flex-end; + padding-left: 16px; + padding-right: 16px; + max-width: 1072px; + margin-left: auto; + margin-right: auto; + margin-top: 10px; +} + +.container { + a { + cursor: pointer; + } +} + .procedure-admin-explanation { font-weight: bold; font-size: 20px; diff --git a/app/controllers/new_administrateur/procedures_controller.rb b/app/controllers/new_administrateur/procedures_controller.rb index d8f5fbbc5..70e0bbf9f 100644 --- a/app/controllers/new_administrateur/procedures_controller.rb +++ b/app/controllers/new_administrateur/procedures_controller.rb @@ -3,6 +3,46 @@ module NewAdministrateur before_action :retrieve_procedure, only: [:champs, :annotations, :edit, :monavis, :update_monavis, :jeton, :update_jeton] before_action :procedure_locked?, only: [:champs, :annotations] + ITEMS_PER_PAGE = 25 + + def index + @procedures_publiees = paginated_published_procedures + @procedures_draft = paginated_draft_procedures + @procedures_closed = paginated_closed_procedures + @procedures_publiees_count = current_administrateur.procedures.publiees.count + @procedures_draft_count = current_administrateur.procedures.brouillons.count + @procedures_closed_count = current_administrateur.procedures.closes.count + @statut = params[:statut] + @statut.blank? ? @statut = 'publiees' : @statut = params[:statut] + end + + def paginated_published_procedures + current_administrateur + .procedures + .publiees + .page(params[:page]) + .per(ITEMS_PER_PAGE) + .order(published_at: :desc) + end + + def paginated_draft_procedures + current_administrateur + .procedures + .brouillons + .page(params[:page]) + .per(ITEMS_PER_PAGE) + .order(created_at: :desc) + end + + def paginated_closed_procedures + current_administrateur + .procedures + .closes + .page(params[:page]) + .per(ITEMS_PER_PAGE) + .order(created_at: :desc) + end + def apercu @dossier = procedure_without_control.new_dossier @tab = apercu_tab @@ -56,6 +96,19 @@ module NewAdministrateur end end + def destroy + procedure = current_administrateur.procedures.find(params[:id]) + + if procedure.can_be_deleted_by_administrateur? + procedure.discard_and_keep_track!(current_administrateur) + + flash.notice = 'Démarche supprimée' + redirect_to admin_procedures_draft_path + else + render json: {}, status: 403 + end + end + def monavis end diff --git a/app/views/new_administrateur/procedures/_procedures_list.html.haml b/app/views/new_administrateur/procedures/_procedures_list.html.haml new file mode 100644 index 000000000..cfbfaad03 --- /dev/null +++ b/app/views/new_administrateur/procedures/_procedures_list.html.haml @@ -0,0 +1,73 @@ +- procedures.each do |procedure| + .card + .flex.justify-between + .flex + - if procedure.logo.present? + = image_tag procedure.logo, alt: procedure.libelle, width: '100' + .flex.column.ml-1 + .card-title + = link_to procedure.libelle, admin_procedure_path(procedure), style: 'color: black;' + = link_to(procedure_lien(procedure), procedure_lien(procedure), class: 'procedure-lien mb-1') + + %div + %p.notice N° #{procedure.id} + %p.notice créée le #{procedure.created_at.strftime('%d/%m/%Y')} + - if procedure.published_at.present? + %p.notice publiée le #{procedure.published_at.strftime('%d/%m/%Y')} + - if procedure.closed_at.present? + %p.notice archivée le #{procedure.closed_at.strftime('%d/%m/%Y')} + + .flex.justify-between + %div + - if feature_enabled?(:administrateur_routage) + %span.icon.person + %span.badge.baseline= procedure.groupe_instructeurs.count + - else + %span.icon.person + %span.badge.baseline= procedure.instructeurs.count + + %span.icon.folder + %span.badge.baseline= procedure.dossiers.count + + %div + = link_to admin_procedure_path(procedure), class: 'button mr-1 edit-procedure' do + %span.icon.edit + Modifier + .dropdown + .button.dropdown-button.procedures-actions-btn + Actions + .dropdown-content.fade-in-down + %ul.dropdown-items.pl-0 + - if !procedure.close? + %li + = link_to sanitize_url(procedure.brouillon? ? commencer_test_url(path: procedure.path) : commencer_url(path: procedure.path)), target: :blank, rel: :noopener do + %span.icon.in-progress + .dropdown-description + %h4 Tester + %li + = link_to admin_procedure_clone_path(procedure.id), class: 'clone-btn', data: { method: :put } do + %span.icon.new-folder + .dropdown-description + %h4 Cloner + + - if procedure.publiee? + %li + = link_to admin_procedure_archive_path(procedure_id: procedure.id), method: :put, data: { confirm: "Voulez-vous vraiment clore la démarche ? \nLes dossiers en cours pourront être instruits, mais aucun nouveau dossier ne pourra plus être déposé.", disable_with: "Archivage..."} do + %span.icon.archive + .dropdown-description + %h4 Clore + + - if procedure.brouillon? + %li + = link_to admin_procedure_path(procedure), method: :delete, data: { confirm: "Voulez-vous vraiment supprimer la démarche ? \nToute suppression est définitive et s'appliquera aux éventuels autres administrateurs de cette démarche !" } do + %span.icon.refuse + .dropdown-description + %h4 Supprimer + + - else + %li + = link_to admin_procedure_publication_path(procedure) do + %span.icon.unarchive + .dropdown-description + %h4 Réactiver + diff --git a/app/views/new_administrateur/procedures/index.html.haml b/app/views/new_administrateur/procedures/index.html.haml new file mode 100644 index 000000000..0f68be127 --- /dev/null +++ b/app/views/new_administrateur/procedures/index.html.haml @@ -0,0 +1,22 @@ +.sub-header + .procedure-admin-listing-container + = link_to "Nouvelle Démarche", new_admin_procedure_path, id: 'new-procedure', class: 'button primary' + .container + + %ul.tabs + = tab_item(t('pluralize.published', count: @procedures_publiees.count), admin_procedures_path(statut: 'publiees'), active: @statut == 'publiees', badge: number_with_html_delimiter(@procedures_publiees_count)) + = tab_item('En test', admin_procedures_path(statut: 'brouillons'), active: @statut == 'brouillons', badge: number_with_html_delimiter(@procedures_draft_count)) + = tab_item(t('pluralize.closed', count: @procedures_closed.count), admin_procedures_path(statut: 'archivees'), active: @statut == 'archivees', badge: number_with_html_delimiter(@procedures_closed_count)) + +.container#procedures{ data: { item_count: @statut === "publiees" ? @procedures_publiees_count : @statut === "brouillons" ? @procedures_draft_count : @procedures_closed_count } } + - if @statut === "publiees" + = render partial: "procedures_list", locals: { procedures: @procedures_publiees } + = paginate @procedures_publiees + + - if @statut === "brouillons" + = render partial: "procedures_list", locals: { procedures: @procedures_draft } + = paginate @procedures_draft + + - if @statut === "archivees" + = render partial: "procedures_list", locals: { procedures: @procedures_closed } + = paginate @procedures_closed diff --git a/app/views/new_administrateur/procedures/show.html.haml b/app/views/new_administrateur/procedures/show.html.haml index 7cb5e38b2..68320f480 100644 --- a/app/views/new_administrateur/procedures/show.html.haml +++ b/app/views/new_administrateur/procedures/show.html.haml @@ -20,10 +20,10 @@ - if !@procedure.publiee? = link_to 'Publier', admin_procedure_publication_path(@procedure), class: 'button primary', id: 'publish-procedure-link', data: { disable_with: "Publication..." } - - if @procedure.locked? - = link_to admin_procedure_archive_path(procedure_id: @procedure.id), method: :put, class: 'button', data: { confirm: "Voulez-vous vraiment archiver la démarche ? \nLes dossiers en cours pourront être instruits, mais aucun nouveau dossier ne pourra plus être déposé.", disable_with: "Archivage..."} do + - if @procedure.locked? && !@procedure.close? + = link_to admin_procedure_archive_path(procedure_id: @procedure.id), method: :put, class: 'button', data: { confirm: "Voulez-vous vraiment clore la démarche ? \nLes dossiers en cours pourront être instruits, mais aucun nouveau dossier ne pourra plus être déposé.", disable_with: "Archivage..."} do %span.icon.archive - Archiver + Clore .container %h2.procedure-admin-explanation Indispensable avant publication diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 41bea6663..925f958fd 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -317,3 +317,15 @@ fr: zero: 0 dossier trouvé one: 1 dossier trouvé other: "%{count} dossiers trouvés" + published: + zero: Publiée + one: Publiée + other: Publiées + closed: + zero: Close + one: Close + other: Closes + draft: + zero: Brouillon + one: Brouillon + other: Brouillons diff --git a/config/routes.rb b/config/routes.rb index 7bfbea98d..05f860b51 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -178,7 +178,7 @@ Rails.application.routes.draw do get 'procedures/draft' => 'procedures#draft' get 'procedures/:id/publication' => 'procedures#show', as: :procedure_publication - resources :procedures, only: [:index, :destroy] do + resources :procedures, only: [:destroy] do collection do get 'new_from_existing' => 'procedures#new_from_existing', as: :new_from_existing end @@ -373,7 +373,7 @@ Rails.application.routes.draw do # namespace :admin, module: 'new_administrateur' do - resources :procedures, except: [:index, :destroy] do + resources :procedures, except: [:destroy] do member do get 'apercu' get 'champs' diff --git a/db/schema.rb b/db/schema.rb index 3c242925f..040346832 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_07_16_143010) do +ActiveRecord::Schema.define(version: 2020_07_15_143010) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -257,9 +257,9 @@ ActiveRecord::Schema.define(version: 2020_07_16_143010) do t.datetime "en_construction_close_to_expiration_notice_sent_at" t.interval "en_construction_conservation_extension", default: "PT0S" t.datetime "termine_close_to_expiration_notice_sent_at" + t.bigint "revision_id" t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin - t.bigint "revision_id" t.index ["archived"], name: "index_dossiers_on_archived" t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id" t.index ["hidden_at"], name: "index_dossiers_on_hidden_at" diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index c8cf264e8..2390b965e 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -41,23 +41,6 @@ describe Admin::ProceduresController, type: :controller do it { expect(response.status).to eq(200) } end - describe 'GET #index with sorting and pagination' do - before do - create(:procedure, administrateur: admin) - admin.reload - end - - subject { - get :index, params: { - 'procedures_smart_listing[page]': 1, - 'procedures_smart_listing[per_page]': 10, - 'procedures_smart_listing[sort][id]': 'asc' - } - } - - it { expect(subject.status).to eq(200) } - end - describe 'GET #archived' do subject { get :archived } diff --git a/spec/controllers/new_administrateur/procedures_controller_spec.rb b/spec/controllers/new_administrateur/procedures_controller_spec.rb index dd79cd59b..36cc682c4 100644 --- a/spec/controllers/new_administrateur/procedures_controller_spec.rb +++ b/spec/controllers/new_administrateur/procedures_controller_spec.rb @@ -43,6 +43,27 @@ describe NewAdministrateur::ProceduresController, type: :controller do sign_in(admin.user) end + describe 'GET #index' do + subject { get :index } + + it { expect(response.status).to eq(200) } + end + + describe 'GET #index with sorting and pagination' do + before do + create(:procedure, administrateur: admin) + admin.reload + end + + subject { + get :index, params: { + 'statut': 'publiees' + } + } + + it { expect(subject.status).to eq(200) } + end + describe 'GET #edit' do let(:published_at) { nil } let(:procedure) { create(:procedure, administrateur: admin, published_at: published_at) } diff --git a/spec/features/admin/procedure_cloning_spec.rb b/spec/features/admin/procedure_cloning_spec.rb index 8264321a9..8f67aea46 100644 --- a/spec/features/admin/procedure_cloning_spec.rb +++ b/spec/features/admin/procedure_cloning_spec.rb @@ -18,6 +18,7 @@ feature 'As an administrateur I wanna clone a procedure', js: true do scenario do visit admin_procedures_path expect(page.find_by_id('procedures')['data-item-count']).to eq('1') + page.all('.procedures-actions-btn').first.click page.all('.clone-btn').first.click visit admin_procedures_draft_path expect(page.find_by_id('procedures')['data-item-count']).to eq('1') diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 815e89a1c..a2b2f0faa 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -12,18 +12,18 @@ feature 'As an administrateur I wanna create a new procedure', js: true do context 'Right after sign_in I shall see all procedure states links' do scenario 'Finding draft procedures' do - click_on 'draft-procedures' - expect(page).to have_current_path(admin_procedures_draft_path) + page.all('.tabs li a')[1].click + expect(page).to have_current_path(admin_procedures_path(statut: 'brouillons')) end scenario 'Finding active procedures' do - click_on 'active-procedures' - expect(page).to have_current_path(admin_procedures_path) + page.all('.tabs li a').first.click + expect(page).to have_current_path(admin_procedures_path(statut: 'publiees')) end scenario 'Finding archived procedures' do - click_on 'archived-procedures' - expect(page).to have_current_path(admin_procedures_archived_path) + page.all('.tabs li a').last.click + expect(page).to have_current_path(admin_procedures_path(statut: 'archivees')) end end @@ -32,7 +32,6 @@ feature 'As an administrateur I wanna create a new procedure', js: true do scenario 'Finding save button for new procedure, libelle, description and cadre_juridique required' do expect(page).to have_selector('#new-procedure') find('#new-procedure').click - click_on 'from-scratch' expect(page).to have_current_path(new_admin_procedure_path) expect(find('#procedure_for_individual_true')).to be_checked @@ -54,7 +53,6 @@ feature 'As an administrateur I wanna create a new procedure', js: true do before 'Create procedure' do expect(page).to have_selector('#new-procedure') find('#new-procedure').click - click_on 'from-scratch' expect(page).to have_current_path(new_admin_procedure_path) fill_in_dummy_procedure_details diff --git a/spec/features/routing/full_scenario_spec.rb b/spec/features/routing/full_scenario_spec.rb index fb0bbcc9d..b23f74762 100644 --- a/spec/features/routing/full_scenario_spec.rb +++ b/spec/features/routing/full_scenario_spec.rb @@ -229,6 +229,7 @@ feature 'The routing', js: true do def log_out(old_layout: false) if old_layout + page.all('.dropdown-button').first.click click_on 'Se déconnecter' else click_button(title: 'Mon compte')