From 217793c5c89aef90699f6fad8faa68c4d2ad02b7 Mon Sep 17 00:00:00 2001 From: Kara Diaby Date: Tue, 22 Mar 2022 15:00:17 +0100 Subject: [PATCH 1/6] modify model --- app/models/dossier.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 095b47c07..2602fee6d 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -504,7 +504,7 @@ class Dossier < ApplicationRecord end def read_only? - en_instruction? || accepte? || refuse? || sans_suite? + en_instruction? || accepte? || refuse? || sans_suite? || procedure.discarded? || procedure.close? && brouillon? end def can_transition_to_en_construction? From b08011cff70cf785878960a310b0b1aa36658218 Mon Sep 17 00:00:00 2001 From: Kara Diaby Date: Tue, 22 Mar 2022 15:00:26 +0100 Subject: [PATCH 2/6] layout --- app/assets/stylesheets/card.scss | 6 +++++ app/views/shared/dossiers/_header.html.haml | 7 +++--- .../_procedure_removed_banner.html.haml | 22 +++++++++++++++++++ .../users/dossiers/show/_header.html.haml | 12 ++++------ .../dossiers/show/_print_dossier.html.haml | 6 +++++ 5 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 app/views/users/dossiers/_procedure_removed_banner.html.haml create mode 100644 app/views/users/dossiers/show/_print_dossier.html.haml diff --git a/app/assets/stylesheets/card.scss b/app/assets/stylesheets/card.scss index ff90ff483..0a772dc09 100644 --- a/app/assets/stylesheets/card.scss +++ b/app/assets/stylesheets/card.scss @@ -53,6 +53,12 @@ } } + &.no-list { + ul { + list-style: none !important; + } + } + ul { list-style-type: disc; list-style-position: inside; diff --git a/app/views/shared/dossiers/_header.html.haml b/app/views/shared/dossiers/_header.html.haml index dbffd3434..ce1a700dc 100644 --- a/app/views/shared/dossiers/_header.html.haml +++ b/app/views/shared/dossiers/_header.html.haml @@ -8,7 +8,8 @@ = render(partial: 'users/dossiers/expiration_banner', locals: {dossier: dossier}) - .header-actions - - if current_user.owns?(dossier) + - if current_user.owns?(dossier) && !dossier.procedure.discarded? && !dossier.procedure.close? + .header-actions = render partial: 'invites/dropdown', locals: { dossier: dossier } - + - else + = render(partial: 'users/dossiers/procedure_removed_banner', locals: { dossier: dossier }) diff --git a/app/views/users/dossiers/_procedure_removed_banner.html.haml b/app/views/users/dossiers/_procedure_removed_banner.html.haml new file mode 100644 index 000000000..db410b2b7 --- /dev/null +++ b/app/views/users/dossiers/_procedure_removed_banner.html.haml @@ -0,0 +1,22 @@ +.card.warning.mb-3.no-list + - if dossier.procedure.discarded? + .flex.justify-between + .card-title= t('users.dossiers.header.banner.procedure_deleted_title') + = render(partial: 'users/dossiers/show/print_dossier', locals: { dossier: dossier}) if !dossier.brouillon? + - if dossier.termine? + %p + = t('users.dossiers.header.banner.procedure_deleted_dossier_termine_content') + - elsif dossier.brouillon? + %p + = t('users.dossiers.header.banner.procedure_close_content') + - else + %p + = t('users.dossiers.header.banner.procedure_deleted_dossier_en_cours_content') + + - else + .flex.justify-between + .card-title= t('users.dossiers.header.banner.procedure_close_title') + = render(partial: 'users/dossiers/show/print_dossier', locals: { dossier: dossier }) if !dossier.brouillon? + %p + = t('users.dossiers.header.banner.procedure_close_content') + diff --git a/app/views/users/dossiers/show/_header.html.haml b/app/views/users/dossiers/show/_header.html.haml index 4670a9811..19b2b0e39 100644 --- a/app/views/users/dossiers/show/_header.html.haml +++ b/app/views/users/dossiers/show/_header.html.haml @@ -12,19 +12,15 @@ = render(partial: 'users/dossiers/expiration_banner', locals: {dossier: dossier}) - - - if current_user.owns?(dossier) + - if (current_user.owns?(dossier) && !dossier.procedure.discarded?) || (!dossier.procedure.discarded? && !dossier.procedure.close? && !dossier.en_construction?) .header-actions = render partial: 'invites/dropdown', locals: { dossier: dossier } - if dossier.can_be_updated_by_user? && !current_page?(modifier_dossier_path(dossier)) = link_to t('views.users.dossiers.show.header.edit_dossier'), modifier_dossier_path(dossier), class: 'button accepted edit-form', 'title'=> "Vous pouvez modifier votre dossier tant qu'il n'est passé en instruction" - %span.dropdown.print-menu-opener - %button.button.dropdown-button.icon-only{ title: t('views.users.dossiers.show.header.print'), 'aria-label': 'imprimer', 'aria-expanded' => 'false', 'aria-controls' => 'print-menu' } - %span.icon.printer - %ul#print-menu.print-menu.dropdown-content - %li - = link_to t('views.users.dossiers.show.header.print_dossier'), dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link" + = render(partial: 'users/dossiers/show/print_dossier', locals: { dossier: dossier }) + - else + = render(partial: 'users/dossiers/procedure_removed_banner', locals: { dossier: dossier }) %nav.tabs %ul diff --git a/app/views/users/dossiers/show/_print_dossier.html.haml b/app/views/users/dossiers/show/_print_dossier.html.haml new file mode 100644 index 000000000..8f1aa0904 --- /dev/null +++ b/app/views/users/dossiers/show/_print_dossier.html.haml @@ -0,0 +1,6 @@ +%span.dropdown.print-menu-opener + %button.button.dropdown-button.icon-only{ title: t('views.users.dossiers.show.header.print'), 'aria-label': 'imprimer', 'aria-expanded' => 'false', 'aria-controls' => 'print-menu' } + %span.icon.printer + %ul#print-menu.print-menu.dropdown-content + %li + = link_to t('views.users.dossiers.show.header.print_dossier'), dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link" From 516bfa86cf2d41dbf5af82ddca1625e2bc30a355 Mon Sep 17 00:00:00 2001 From: Kara Diaby Date: Tue, 22 Mar 2022 15:00:33 +0100 Subject: [PATCH 3/6] locale --- config/locales/views/users/header/fr.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/locales/views/users/header/fr.yml b/config/locales/views/users/header/fr.yml index 5d2af1fad..1ebab82d7 100644 --- a/config/locales/views/users/header/fr.yml +++ b/config/locales/views/users/header/fr.yml @@ -3,6 +3,11 @@ fr: dossiers: header: banner: + procedure_deleted_title: "La démarche liée à votre dossier est supprimée" + procedure_close_title: "La démarche liée à votre dossier est close" + procedure_deleted_dossier_en_cours_content: "Vous pouvez toujours consulter votre dossier, mais il n’est plus possible de le modifier." + procedure_deleted_dossier_termine_content: "Votre dossier a été traité par l'administration, aucune action n'est possible" + procedure_close_content: "Vous pouvez toujours consulter votre dossier, mais il ne sera pas traité par l'administration" title: Votre dossier va expirer states: brouillon: Votre dossier est en brouillon, mais va bientôt expirer. Cela signifie qu’il va bientôt être supprimé sans avoir été déposé. Si vous souhaitez le conserver afin de poursuivre la démarche, vous pouvez le conserver un mois de plus en cliquant sur le bouton ci-dessous. From 71614d4ba370d1467f50c39371ae2dc0109c4856 Mon Sep 17 00:00:00 2001 From: Kara Diaby Date: Wed, 23 Mar 2022 08:03:08 +0100 Subject: [PATCH 4/6] tests --- .../shared/dossiers/_header.html.haml.spec.rb | 34 +++++++++++++++ .../dossiers/show/_header.html.haml_spec.rb | 41 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 spec/views/shared/dossiers/_header.html.haml.spec.rb diff --git a/spec/views/shared/dossiers/_header.html.haml.spec.rb b/spec/views/shared/dossiers/_header.html.haml.spec.rb new file mode 100644 index 000000000..648fdb365 --- /dev/null +++ b/spec/views/shared/dossiers/_header.html.haml.spec.rb @@ -0,0 +1,34 @@ +describe 'dossiers/show/header.html.haml', type: :view do + let(:procedure) { create(:procedure, :discarded) } + let(:dossier) { create(:dossier, state: "brouillon", procedure: procedure) } + + before do + sign_in dossier.user + end + + subject! { render 'shared/dossiers/header.html.haml', dossier: dossier } + + context "when the procedure is discarded with a dossier en brouillon" do + it 'affiche que la démarche est supprimée' do + expect(rendered).to have_text("La démarche liée à votre dossier est supprimée") + expect(rendered).to have_text("Vous pouvez toujours consulter votre dossier, mais il ne sera pas traité par l'administration") + end + + it 'cannot download the dossier' do + expect(rendered).not_to have_text("Tout le dossier") + end + end + + context "when the procedure is closed with a dossier en brouillon" do + let(:procedure) { create(:procedure, :closed) } + + it 'affiche que la démarche est close' do + expect(rendered).to have_text("La démarche liée à votre dossier est close") + expect(rendered).to have_text("Vous pouvez toujours consulter votre dossier, mais il ne sera pas traité par l'administration") + end + + it 'cannot download the dossier' do + expect(rendered).not_to have_text("Tout le dossier") + end + end +end diff --git a/spec/views/users/dossiers/show/_header.html.haml_spec.rb b/spec/views/users/dossiers/show/_header.html.haml_spec.rb index 69cc5b371..660a09a3c 100644 --- a/spec/views/users/dossiers/show/_header.html.haml_spec.rb +++ b/spec/views/users/dossiers/show/_header.html.haml_spec.rb @@ -16,4 +16,45 @@ describe 'users/dossiers/show/header.html.haml', type: :view do expect(rendered).to have_link("Résumé", href: dossier_path(dossier)) expect(rendered).to have_link("Demande", href: demande_dossier_path(dossier)) end + + context "when the procedure is closed with a dossier en construction" do + let(:procedure) { create(:procedure, :closed) } + let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + + it "n'affiche pas de banner" do + expect(rendered).not_to have_text("La démarche liée à votre dossier est close") + end + + it 'can download the dossier' do + expect(rendered).to have_text("Tout le dossier") + end + end + + context "when the procedure is discarded with a dossier en construction" do + let(:procedure) { create(:procedure, :discarded) } + let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + + it 'affiche que la démarche est supprimée' do + expect(rendered).to have_text("La démarche liée à votre dossier est supprimée") + expect(rendered).to have_text("Vous pouvez toujours consulter votre dossier, mais il n’est plus possible de le modifier") + end + + it 'can download the dossier' do + expect(rendered).to have_text("Tout le dossier") + end + end + + context "when the procedure is discarded with a dossier terminé" do + let(:procedure) { create(:procedure, :discarded) } + let(:dossier) { create(:dossier, state: "accepte", procedure: procedure) } + + it 'affiche que la démarche est supprimée' do + expect(rendered).to have_text("La démarche liée à votre dossier est supprimée") + expect(rendered).to have_text("Votre dossier a été traité par l'administration, aucune action n'est possible") + end + + it 'can download the dossier' do + expect(rendered).to have_text("Tout le dossier") + end + end end From 017625207e05fdc04fd39ff4f652abcc7854c25a Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 22 Mar 2022 15:53:38 +0000 Subject: [PATCH 5/6] db: add constraints to role tables --- app/models/administrateur.rb | 2 +- app/models/expert.rb | 2 +- app/models/instructeur.rb | 2 +- ..._add_not_null_constraints_to_role_tables.rb | 18 ++++++++++++++++++ ...23113048_add_foreign_keys_to_role_tables.rb | 10 ++++++++++ ...152_validate_foreign_keys_to_role_tables.rb | 10 ++++++++++ .../20220323113327_add_index_to_role_tables.rb | 9 +++++++++ db/schema.rb | 14 ++++++++++---- 8 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20220323064705_add_not_null_constraints_to_role_tables.rb create mode 100644 db/migrate/20220323113048_add_foreign_keys_to_role_tables.rb create mode 100644 db/migrate/20220323113152_validate_foreign_keys_to_role_tables.rb create mode 100644 db/migrate/20220323113327_add_index_to_role_tables.rb diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index f5eb26d4a..a35e77098 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -7,7 +7,7 @@ # encrypted_token :string # created_at :datetime # updated_at :datetime -# user_id :bigint +# user_id :bigint not null # class Administrateur < ApplicationRecord include ActiveRecord::SecureToken diff --git a/app/models/expert.rb b/app/models/expert.rb index 07cc31940..284fe1555 100644 --- a/app/models/expert.rb +++ b/app/models/expert.rb @@ -5,7 +5,7 @@ # id :bigint not null, primary key # created_at :datetime not null # updated_at :datetime not null -# user_id :bigint +# user_id :bigint not null # class Expert < ApplicationRecord belongs_to :user diff --git a/app/models/instructeur.rb b/app/models/instructeur.rb index 8fb79ddc1..570f5c220 100644 --- a/app/models/instructeur.rb +++ b/app/models/instructeur.rb @@ -9,7 +9,7 @@ # created_at :datetime # updated_at :datetime # agent_connect_id :string -# user_id :bigint +# user_id :bigint not null # class Instructeur < ApplicationRecord has_and_belongs_to_many :administrateurs diff --git a/db/migrate/20220323064705_add_not_null_constraints_to_role_tables.rb b/db/migrate/20220323064705_add_not_null_constraints_to_role_tables.rb new file mode 100644 index 000000000..3d29bf143 --- /dev/null +++ b/db/migrate/20220323064705_add_not_null_constraints_to_role_tables.rb @@ -0,0 +1,18 @@ +class AddNotNullConstraintsToRoleTables < ActiveRecord::Migration[6.1] + include Database::MigrationHelpers + + def change + # If this migration fails, that means you need to run the matching data migration task first. + # Please run: + # bin/rake after_party:copy_user_association_to_user_related_models + # bin/rake after_party:delete_roles_without_users + # + # (We ignore strong_migrations safety warnings, because those tables are relatively small, and the null check + # will be very fast.) + safety_assured do + change_column_null :administrateurs, :user_id, false + change_column_null :instructeurs, :user_id, false + change_column_null :experts, :user_id, false + end + end +end diff --git a/db/migrate/20220323113048_add_foreign_keys_to_role_tables.rb b/db/migrate/20220323113048_add_foreign_keys_to_role_tables.rb new file mode 100644 index 000000000..ffbf3696a --- /dev/null +++ b/db/migrate/20220323113048_add_foreign_keys_to_role_tables.rb @@ -0,0 +1,10 @@ +class AddForeignKeysToRoleTables < ActiveRecord::Migration[6.1] + def change + # Add foreign keys constraints to role tables. + # + # (We don't validate foreign keys right now, to avoid blocking writes to these tables for too long.) + add_foreign_key :administrateurs, :users, validate: false + add_foreign_key :instructeurs, :users, validate: false + add_foreign_key :experts, :users, validate: false + end +end diff --git a/db/migrate/20220323113152_validate_foreign_keys_to_role_tables.rb b/db/migrate/20220323113152_validate_foreign_keys_to_role_tables.rb new file mode 100644 index 000000000..3e83674d8 --- /dev/null +++ b/db/migrate/20220323113152_validate_foreign_keys_to_role_tables.rb @@ -0,0 +1,10 @@ +class ValidateForeignKeysToRoleTables < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + # Now that the foreign keys are added, we can validate them safely without blocking writes. + validate_foreign_key :administrateurs, :users + validate_foreign_key :instructeurs, :users + validate_foreign_key :experts, :users + end +end diff --git a/db/migrate/20220323113327_add_index_to_role_tables.rb b/db/migrate/20220323113327_add_index_to_role_tables.rb new file mode 100644 index 000000000..c5c9fd7b8 --- /dev/null +++ b/db/migrate/20220323113327_add_index_to_role_tables.rb @@ -0,0 +1,9 @@ +class AddIndexToRoleTables < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :administrateurs, :user_id, algorithm: :concurrently + add_index :instructeurs, :user_id, algorithm: :concurrently + add_index :experts, :user_id, algorithm: :concurrently + end +end diff --git a/db/schema.rb b/db/schema.rb index 23114c7c9..473cb35aa 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: 2022_03_22_110900) do +ActiveRecord::Schema.define(version: 2022_03_23_113327) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -60,7 +60,8 @@ ActiveRecord::Schema.define(version: 2022_03_22_110900) do t.datetime "created_at" t.string "encrypted_token" t.datetime "updated_at" - t.bigint "user_id" + t.bigint "user_id", null: false + t.index ["user_id"], name: "index_administrateurs_on_user_id" end create_table "administrateurs_instructeurs", id: false, force: :cascade do |t| @@ -410,7 +411,8 @@ ActiveRecord::Schema.define(version: 2022_03_22_110900) do create_table "experts", force: :cascade do |t| t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false - t.bigint "user_id" + t.bigint "user_id", null: false + t.index ["user_id"], name: "index_experts_on_user_id" end create_table "experts_procedures", force: :cascade do |t| @@ -539,8 +541,9 @@ ActiveRecord::Schema.define(version: 2022_03_22_110900) do t.text "encrypted_login_token" t.datetime "login_token_created_at" t.datetime "updated_at" - t.bigint "user_id" + t.bigint "user_id", null: false t.index ["agent_connect_id"], name: "index_instructeurs_on_agent_connect_id", unique: true + t.index ["user_id"], name: "index_instructeurs_on_user_id" end create_table "invites", id: :serial, force: :cascade do |t| @@ -852,6 +855,7 @@ ActiveRecord::Schema.define(version: 2022_03_22_110900) do end add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "administrateurs", "users" add_foreign_key "administrateurs_instructeurs", "administrateurs" add_foreign_key "administrateurs_instructeurs", "instructeurs" add_foreign_key "administrateurs_procedures", "administrateurs" @@ -876,12 +880,14 @@ ActiveRecord::Schema.define(version: 2022_03_22_110900) do add_foreign_key "dossiers", "groupe_instructeurs" add_foreign_key "dossiers", "procedure_revisions", column: "revision_id" add_foreign_key "dossiers", "users" + add_foreign_key "experts", "users" add_foreign_key "experts_procedures", "experts" add_foreign_key "experts_procedures", "procedures" add_foreign_key "france_connect_informations", "users" add_foreign_key "geo_areas", "champs" add_foreign_key "groupe_instructeurs", "procedures" add_foreign_key "initiated_mails", "procedures" + add_foreign_key "instructeurs", "users" add_foreign_key "merge_logs", "users" add_foreign_key "procedure_presentations", "assign_tos" add_foreign_key "procedure_revision_types_de_champ", "procedure_revision_types_de_champ", column: "parent_id" From 79ea80c1998fcd2705ae8f80e7468f8f90e6b1bb Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 29 Mar 2022 07:04:26 +0000 Subject: [PATCH 6/6] db: remove deprecated role columns on user --- .../20220323120846_remove_role_columns_on_user.rb | 10 ++++++++++ db/schema.rb | 11 +---------- 2 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20220323120846_remove_role_columns_on_user.rb diff --git a/db/migrate/20220323120846_remove_role_columns_on_user.rb b/db/migrate/20220323120846_remove_role_columns_on_user.rb new file mode 100644 index 000000000..1ba0e89ce --- /dev/null +++ b/db/migrate/20220323120846_remove_role_columns_on_user.rb @@ -0,0 +1,10 @@ +class RemoveRoleColumnsOnUser < ActiveRecord::Migration[6.1] + def change + # (The safety_assured block validates that the columns to remove are ignored in the model, which is the case.) + safety_assured do + remove_column :users, :administrateur_id + remove_column :users, :instructeur_id + remove_column :users, :expert_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 473cb35aa..40d9f2ece 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: 2022_03_23_113327) do +ActiveRecord::Schema.define(version: 2022_03_23_120846) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -791,7 +791,6 @@ ActiveRecord::Schema.define(version: 2022_03_23_113327) do end create_table "users", id: :serial, force: :cascade do |t| - t.bigint "administrateur_id" t.datetime "confirmation_sent_at" t.string "confirmation_token" t.datetime "confirmed_at" @@ -800,9 +799,7 @@ ActiveRecord::Schema.define(version: 2022_03_23_113327) do t.string "current_sign_in_ip" t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false - t.bigint "expert_id" t.integer "failed_attempts", default: 0, null: false - t.bigint "instructeur_id" t.datetime "last_sign_in_at" t.string "last_sign_in_ip" t.string "locale" @@ -817,11 +814,8 @@ ActiveRecord::Schema.define(version: 2022_03_23_113327) do t.text "unconfirmed_email" t.string "unlock_token" t.datetime "updated_at" - t.index ["administrateur_id"], name: "index_users_on_administrateur_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true - t.index ["expert_id"], name: "index_users_on_expert_id" - t.index ["instructeur_id"], name: "index_users_on_instructeur_id" t.index ["requested_merge_into_id"], name: "index_users_on_requested_merge_into_id" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true @@ -907,9 +901,6 @@ ActiveRecord::Schema.define(version: 2022_03_23_113327) do add_foreign_key "trusted_device_tokens", "instructeurs" add_foreign_key "types_de_champ", "procedure_revisions", column: "revision_id" add_foreign_key "types_de_champ", "types_de_champ", column: "parent_id" - add_foreign_key "users", "administrateurs" - add_foreign_key "users", "experts" - add_foreign_key "users", "instructeurs" add_foreign_key "users", "users", column: "requested_merge_into_id" add_foreign_key "without_continuation_mails", "procedures" end