From 5be83bd01e1ebe243ec6c15910876e5f7aa05ca5 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 21 Oct 2019 16:12:57 +0000 Subject: [PATCH] procedure: make the layout more similar to the mockup --- .../stylesheets/new_design/_constants.scss | 1 + app/assets/stylesheets/new_design/common.scss | 6 +- .../stylesheets/new_design/layouts.scss | 17 ++ .../new_design/procedure_form.scss | 79 +++++++ .../stylesheets/new_design/sub_header.scss | 2 +- .../{procedure-edit.js => procedure-form.js} | 7 +- app/javascript/packs/application.js | 2 +- .../procedures/_informations.html.haml | 215 +++++++++--------- .../procedures/edit.html.haml | 32 ++- .../procedures/new.html.haml | 28 ++- .../features/admin/procedure_creation_spec.rb | 6 +- spec/features/admin/procedure_update_spec.rb | 3 + 12 files changed, 263 insertions(+), 135 deletions(-) create mode 100644 app/assets/stylesheets/new_design/procedure_form.scss rename app/javascript/new_design/{procedure-edit.js => procedure-form.js} (69%) diff --git a/app/assets/stylesheets/new_design/_constants.scss b/app/assets/stylesheets/new_design/_constants.scss index 0b479f2de..dfc87c788 100644 --- a/app/assets/stylesheets/new_design/_constants.scss +++ b/app/assets/stylesheets/new_design/_constants.scss @@ -7,6 +7,7 @@ $default-padding: 2 * $default-spacer; // layouts $two-columns-padding: 60px; $two-columns-breakpoint: 980px; +$sub-header-bottom-margin: 3 * $default-spacer; // z-order $alert-z-index: 100; diff --git a/app/assets/stylesheets/new_design/common.scss b/app/assets/stylesheets/new_design/common.scss index 9e3d6a09f..171076082 100644 --- a/app/assets/stylesheets/new_design/common.scss +++ b/app/assets/stylesheets/new_design/common.scss @@ -61,11 +61,13 @@ sup { .container { @include horizontal-padding($default-padding); max-width: $page-width + 2 * $default-padding; - margin: 0 auto; + margin-left: auto; + margin-right: auto; } .small-container { @include horizontal-padding($default-padding); max-width: $small-page-width + 2 * $default-padding; - margin: 0 auto; + margin-left: auto; + margin-right: auto; } diff --git a/app/assets/stylesheets/new_design/layouts.scss b/app/assets/stylesheets/new_design/layouts.scss index a5eee6808..de4c71231 100644 --- a/app/assets/stylesheets/new_design/layouts.scss +++ b/app/assets/stylesheets/new_design/layouts.scss @@ -52,3 +52,20 @@ .blank-tab { text-align: center; } + +.sticky--top { + position: sticky; + // scss-lint:disable VendorPrefix + position: -webkit-sticky; // This is needed on Safari (tested on 12.1) + // scss-lint:enable VendorPrefix + top: 0; +} + +.sticky--bottom { + position: sticky; + // scss-lint:disable VendorPrefix + position: -webkit-sticky; // This is needed on Safari (tested on 12.1) + // scss-lint:enable VendorPrefix + bottom: 0; +} + diff --git a/app/assets/stylesheets/new_design/procedure_form.scss b/app/assets/stylesheets/new_design/procedure_form.scss new file mode 100644 index 000000000..4c920eb59 --- /dev/null +++ b/app/assets/stylesheets/new_design/procedure_form.scss @@ -0,0 +1,79 @@ +@import "colors"; +@import "constants"; + +// scss-lint:disable SelectorFormat + +.procedure-form .page-title { + text-align: left; +} + +.procedure-form__columns { + display: flex; + margin-top: -$sub-header-bottom-margin; +} + +// We want to make the form as large as possible, +// without shrinking the preview too much. +// +// A balanced compromised seems to make the form +// slighly larger than the preview (flex 10/9), and +// to reduce the margins on the preview as much as +// possible. +.procedure-form__column--form { + flex: 10; + padding: 0 $default-padding; + background-color: $light-grey; +} + +.procedure-form__column--preview { + flex: 9; + padding: 0 2 * $default-padding; + // Gain a little horizontal space by using the white + // space on the right as our margin. + padding-right: 0; +} + +// Hide the preview panel on smaller screens +@media screen and (max-width: 800px) { + .procedure-form__column--preview { + display: none; + } +} + +.procedure-form__preview .procedure-preview { + max-width: 450px; + margin: 0 auto; +} + +.procedure-form__preview-title { + font-size: 1.2rem; + font-weight: bold; + opacity: 0.5; + margin-top: $default-spacer * 4; + margin-bottom: $default-spacer * 8; +} + +.procedure-form__actions { + display: flex; + margin-left: -$default-padding; + margin-right: -$default-padding; + padding: $default-spacer $default-padding; + background: $light-grey; + border-top: 1px solid $border-grey; + + .button.send { + margin-left: auto; + } +} + +.procedure-form__options-details { + margin-bottom: $default-padding; +} + +.procedure-form__options-summary { + cursor: pointer; + + .header-section { + display: inline-block; + } +} diff --git a/app/assets/stylesheets/new_design/sub_header.scss b/app/assets/stylesheets/new_design/sub_header.scss index 84121b6dd..f3cc9eeb8 100644 --- a/app/assets/stylesheets/new_design/sub_header.scss +++ b/app/assets/stylesheets/new_design/sub_header.scss @@ -4,7 +4,7 @@ .sub-header { background-color: $light-grey; padding-top: $default-padding; - margin-bottom: 3 * $default-spacer; + margin-bottom: $sub-header-bottom-margin; border-bottom: 1px solid $border-grey; .container { diff --git a/app/javascript/new_design/procedure-edit.js b/app/javascript/new_design/procedure-form.js similarity index 69% rename from app/javascript/new_design/procedure-edit.js rename to app/javascript/new_design/procedure-form.js index be1bb3aa0..0c161bbb7 100644 --- a/app/javascript/new_design/procedure-edit.js +++ b/app/javascript/new_design/procedure-form.js @@ -9,10 +9,9 @@ function syncInputToElement(fromSelector, toSelector) { } function syncFormToPreview() { - syncInputToElement('#procedure_libelle', 'h2.procedure-title'); + syncInputToElement('#procedure_libelle', '.procedure-title'); syncInputToElement('#procedure_description', '.procedure-description-body'); } -delegate('input', '#procedure-edit #procedure_libelle', syncFormToPreview); -delegate('input', '#procedure-edit #procedure_description', syncFormToPreview); - +delegate('input', '.procedure-form #procedure_libelle', syncFormToPreview); +delegate('input', '.procedure-form #procedure_description', syncFormToPreview); diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index c72b799f9..9b956474a 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -22,7 +22,7 @@ import '../shared/toggle-target'; import '../new_design/dropdown'; import '../new_design/form-validation'; import '../new_design/procedure-context'; -import '../new_design/procedure-edit'; +import '../new_design/procedure-form'; import '../new_design/select2'; import '../new_design/spinner'; import '../new_design/support'; diff --git a/app/views/new_administrateur/procedures/_informations.html.haml b/app/views/new_administrateur/procedures/_informations.html.haml index 90165987a..780a3ef4a 100644 --- a/app/views/new_administrateur/procedures/_informations.html.haml +++ b/app/views/new_administrateur/procedures/_informations.html.haml @@ -1,125 +1,134 @@ -.container - - if @procedure.locked? - .alert.alert-info - Cette démarche est publiée, certains éléments de la description ne sont plus modifiables +- if @procedure.locked? + .card.warning + .card-title Cette démarche est publiée. + Certains éléments de la description ne sont plus modifiables. -.two-columns - .columns-container - .column - = f.label :libelle do - Titre de la démarche - %span.mandatory * - = f.text_field :libelle, class: 'form-control', placeholder: 'Titre' += f.label :libelle do + Titre de la démarche + %span.mandatory * += f.text_field :libelle, class: 'form-control', placeholder: 'Titre' - = f.label :description do - Description - %span.mandatory * - = f.text_area :description, rows: '6', placeholder: 'Description de la démarche, destinataires, etc. ', class: 'form-control' += f.label :description do + Description + %span.mandatory * += f.text_area :description, rows: '6', placeholder: 'Description de la démarche, destinataires, etc. ', class: 'form-control' - %h2.header-section Logo de la démarche - - if @procedure.persisted? - = link_to 'supprimer', delete_logo_admin_procedure_path(@procedure), method: :delete - .pj-input - = f.file_field :logo, - direct_upload: true, - accept: 'image/png, image/jpg, image/jpeg', - style: 'display: inline' +%h2.header-section Logo de la démarche +- if @procedure.persisted? + = link_to 'supprimer', delete_logo_admin_procedure_path(@procedure), method: :delete +.pj-input + = f.file_field :logo, + direct_upload: true, + accept: 'image/png, image/jpg, image/jpeg', + style: 'display: inline' - %div{ style: 'margin-top: 5px;' } - %i - Fichier accepté : JPG / JPEG / PNG +%div{ style: 'margin-top: 5px;' } + %i + Fichier accepté : JPG / JPEG / PNG - .column.procedure-preview - = render partial: 'layouts/commencer/procedure_description', locals: { procedure: @procedure } +- if !@procedure.locked? + %h2.header-section Conservation des données + = f.label :duree_conservation_dossiers_dans_ds do + Sur demarches-simplifiees.fr + %span.mandatory * + .notice (durée en mois après le début de l’instruction) + = f.number_field :duree_conservation_dossiers_dans_ds, class: 'form-control', placeholder: '6', required: true -.container - - if !@procedure.locked? - %h2.header-section Conservation des données - = f.label :duree_conservation_dossiers_dans_ds, "Sur demarches-simplifiees.fr* (durée en mois après le début de l’instruction)" - = f.number_field :duree_conservation_dossiers_dans_ds, class: 'form-control', placeholder: '6', required: true + = f.label :duree_conservation_dossiers_hors_ds do + Hors demarches-simplifiees.fr + %span.mandatory * + .notice (durée en mois après la fin de l'instruction) + = f.number_field :duree_conservation_dossiers_hors_ds, class: 'form-control', placeholder: '6', required: true - = f.label :duree_conservation_dossiers_hors_ds, "Hors demarches-simplifiees.fr* (durée en mois après la fin de l'instruction)" - = f.number_field :duree_conservation_dossiers_hors_ds, class: 'form-control', placeholder: '6', required: true +- if @procedure.created_at.present? + = f.label :lien_site_web do + Où les usagers trouveront-ils le lien vers la démarche ? + = f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://exemple.gouv.fr/ma_demarche' - - if @procedure.created_at.present? - = f.label :description do - Où les usagers trouveront-ils le lien vers la démarche ? - = f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://exemple.gouv.fr/ma_demarche' +%h2.header-section + Cadre juridique + %span.mandatory * - %h2.header-section Cadre juridique * - .explication - Texte qui justifie le droit de collecter les données demandées dans votre démarche auprès des usagers, par exemple : - %br - Texte de loi (loi, décret, circulaire, arrêté,…) - %br - Texte juridique (statuts, délibération, décision du conseil d'administration…) - %br += f.label :cadre_juridique do + .notice + %p + Le cadre juridique justifie le droit de collecter les données demandées dans votre démarche auprès des usagers. Par exemple : + %br + • Texte de loi (loi, décret, circulaire, arrêté…) + %br + • Texte juridique (statuts, délibération, décision du conseil d'administration…) + %br = link_to("En savoir plus avec cette vidéo de 5 minutes", CADRE_JURIDIQUE_URL, target: "_blank", rel: "noopener") + %p + Vous pouvez saisir un lien web vers ce texte, ou l’importer depuis un fichier. + Lien vers le texte += f.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/' - %p - Vous pouvez saisir un lien vers ce texte ou importer celui-ci directement. += f.label :deliberation, 'Importer le texte' +- deliberation = @procedure.deliberation +- if !deliberation.attached? + .pj-input + = f.file_field :deliberation, + direct_upload: true +- else + %a{ href: url_for(deliberation), target: '_blank', rel: 'noopener' } + = deliberation.filename.to_s + - if @procedure.persisted? + = link_to 'supprimer', delete_deliberation_admin_procedure_path(@procedure), method: :delete + %br + Modifier : + .pj-input + = f.file_field :deliberation, + direct_upload: true - = f.label :cadre_juridique, 'Lien vers le texte' - = f.text_field :cadre_juridique, class: 'form-control', placeholder: 'https://www.legifrance.gouv.fr/' +%h2.header-section + Notice explicative de la démarche - = f.label :deliberation, 'Importer le texte' - - deliberation = @procedure.deliberation - - if !deliberation.attached? - .pj-input - = f.file_field :deliberation, - direct_upload: true - - else - %a{ href: url_for(deliberation), target: '_blank', rel: 'noopener' } - = deliberation.filename.to_s - - if @procedure.persisted? - = link_to 'supprimer', delete_deliberation_admin_procedure_path(@procedure), method: :delete - %br - Modifier : - .pj-input - = f.file_field :deliberation, - direct_upload: true +- notice = @procedure.notice += f.label :notice do + .notice + %p + Une notice explicative est un document destiné à guider l’usager dans sa démarche. C’est un document que vous avez élaboré et qui peut prendre la forme d’un fichier doc, d’un pdf ou encore de diapositives. Le bouton pour télécharger cette notice apparaît en haut du formulaire pour l’usager. - - notice = @procedure.notice - %h2.header-section Notice explicative de la démarche - .explication - Une notice explicative est un document destiné à guider l’usager dans sa démarche. C’est un document que vous avez élaboré et qui peut prendre la forme d’un fichier doc, d’un pdf ou encore de diapositives. Le bouton pour télécharger cette notice apparaît en haut du formulaire pour l’usager. +- if !notice.attached? + .pj-input + = f.file_field :notice, + direct_upload: true +- else + %a{ href: url_for(notice), target: '_blank', rel: 'noopener' } + = notice.filename.to_s + - if @procedure.persisted? + \- + = link_to 'supprimer', delete_notice_admin_procedure_path(@procedure), method: :delete + %br + Modifier : + .pj-input + = f.file_field :notice, + direct_upload: true - - if !notice.attached? - .pj-input - = f.file_field :notice, - direct_upload: true - - else - %a{ href: url_for(notice), target: '_blank', rel: 'noopener' } - = notice.filename.to_s - - if @procedure.persisted? - \- - = link_to 'supprimer', delete_notice_admin_procedure_path(@procedure), method: :delete - %br - Modifier : - .pj-input - = f.file_field :notice, - direct_upload: true +- if !@procedure.locked? + %h2.header-section À qui s’adresse ma démarche ? + .editable-champ.editable-champ-radio.vertical + = f.label :for_individual, value: true do + Ma démarche s’adresse à un particulier + %span.notice + %p En choisissant cette option, l’usager devra renseigner son nom et prénom avant d’accéder au formulaire + = f.radio_button :for_individual, true - - if !@procedure.locked? - %h2.header-section À qui s’adresse ma démarche ? - .editable-champ.editable-champ-radio.vertical - = f.label :for_individual, value: true do - Ma démarche s’adresse à un particulier - %span.notice - %p En choisissant cette option, l’usager devra renseigner son nom et prénom avant d’accéder au formulaire - = f.radio_button :for_individual, true + .editable-champ.editable-champ-radio.vertical + = f.label :for_individual, value: false do + Ma démarche s’adresse à une personne morale + %span.notice + %p En choisissant cette option, l’usager devra renseigner son n° SIRET.
Grâce à l’API Entreprise, les informations sur la personne morale (raison sociale, adresse du siège, etc.) seront automatiquement renseignées. + = f.radio_button :for_individual, false - .editable-champ.editable-champ-radio.vertical - = f.label :for_individual, value: false do - Ma démarche s’adresse à une personne morale - %span.notice - %p En choisissant cette option, l’usager devra renseigner son n° SIRET.
Grâce à l’API Entreprise, les informations sur la personne morale (raison sociale, adresse du siège, etc.) seront automatiquement renseignées. - = f.radio_button :for_individual, false + %p.explication + Si votre démarche s’adresse indifféremment à une personne morale ou un particulier, choisissez l'option « Particuliers ». Vous pourrez ajouter un champ SIRET directement dans le formulaire. - %p.explication - Si votre démarche s’adresse indifféremment à une personne morale ou un particulier, choisissez l'option « Particuliers ». Vous pourrez utiliser le champ SIRET directement dans le formulaire. +%details.procedure-form__options-details + %summary.procedure-form__options-summary + %h2.header-section Options avancées - %h2.header-section Options avancées - if feature_enabled?(:administrateur_web_hook) = f.label :web_hook_url do Lien de rappel HTTP (webhook) diff --git a/app/views/new_administrateur/procedures/edit.html.haml b/app/views/new_administrateur/procedures/edit.html.haml index 038714a94..9ba8f8bdf 100644 --- a/app/views/new_administrateur/procedures/edit.html.haml +++ b/app/views/new_administrateur/procedures/edit.html.haml @@ -1,16 +1,24 @@ -#procedure-edit - = render partial: 'new_administrateur/breadcrumbs', - locals: { steps: [link_to('Démarches', admin_procedures_path), - link_to(@procedure.libelle, admin_procedure_path(@procedure)), - 'Description'] } += render partial: 'new_administrateur/breadcrumbs', + locals: { steps: [link_to('Démarches', admin_procedures_path), + link_to(@procedure.libelle, admin_procedure_path(@procedure)), + 'Description'] } +.procedure-form + .procedure-form__columns.container + = form_for @procedure, + url: url_for({ controller: 'new_administrateur/procedures', action: :update, id: @procedure.id }), + multipart: true, + html: { class: 'form procedure-form__column--form' } do |f| - .container - %h1.page-title Présentation + %h1.page-title Description - = form_for @procedure, url: url_for({ controller: 'new_administrateur/procedures', action: :update, id: @procedure.id }), multipart: true, html: { class: 'form' } do |f| + = render partial: 'new_administrateur/procedures/informations', locals: { f: f } - = render partial: 'informations', locals: { f: f } - - .container - .text-right + .procedure-form__actions.sticky--bottom + = link_to 'Annuler', admin_procedure_path(id: @procedure), class: 'button', data: { confirm: 'Êtes-vous sûr de vouloir annuler les modifications effectuées ?'} = f.button 'Enregistrer', class: 'button primary send' + + .procedure-form__column--preview + .procedure-form__preview.sticky--top + %h3.procedure-form__preview-title Aperçu + .procedure-preview + = render partial: 'layouts/commencer/procedure_description', locals: { procedure: @procedure } diff --git a/app/views/new_administrateur/procedures/new.html.haml b/app/views/new_administrateur/procedures/new.html.haml index 8bee8c4e1..42ee75fdb 100644 --- a/app/views/new_administrateur/procedures/new.html.haml +++ b/app/views/new_administrateur/procedures/new.html.haml @@ -2,13 +2,23 @@ locals: { steps: [link_to('Démarches', admin_procedures_path), 'Nouvelle'] } -.container - %h1.page-title - = t('dynamics.admin.dossiers.tableau_de_bord.nouvelle_procedure') +.procedure-form + .procedure-form__columns.container + = form_for @procedure, + url: url_for({ controller: 'new_administrateur/procedures', action: :create, id: @procedure.id }), + multipart: true, + html: { class: 'form procedure-form__column--form' } do |f| -.container - %h1 - = form_for @procedure, url: { controller: 'new_administrateur/procedures', action: :create }, multipart: true, html: { class: 'form' } do |f| - = render partial: 'informations', locals: { f: f } - .text-center - = f.button 'Valider', class: 'button primary send', id: 'save-procedure' + %h1.page-title Nouvelle démarche + + = render partial: 'new_administrateur/procedures/informations', locals: { f: f } + + .procedure-form__actions.sticky--bottom + = link_to 'Annuler', admin_procedures_path, class: 'button', data: { confirm: 'Êtes-vous sûr de vouloir annuler la création de cette démarche ?'} + = f.button 'Créer la démarche', class: 'button primary send' + + .procedure-form__column--preview + .procedure-form__preview.sticky--top + %h3.procedure-form__preview-title Aperçu + .procedure-preview + = render partial: 'layouts/commencer/procedure_description', locals: { procedure: @procedure } diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 5abfec21c..66292414c 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -40,11 +40,11 @@ feature 'As an administrateur I wanna create a new procedure', js: true do expect(find('#procedure_for_individual_false')).not_to be_checked fill_in 'procedure_duree_conservation_dossiers_dans_ds', with: '3' fill_in 'procedure_duree_conservation_dossiers_hors_ds', with: '6' - click_on 'save-procedure' + click_on 'Créer la démarche' expect(page).to have_text('Libelle doit être rempli') fill_in_dummy_procedure_details - click_on 'save-procedure' + click_on 'Créer la démarche' expect(page).to have_current_path(champs_procedure_path(Procedure.last)) end @@ -59,7 +59,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do expect(page).to have_current_path(new_admin_procedure_path) fill_in_dummy_procedure_details - click_on 'save-procedure' + click_on 'Créer la démarche' procedure = Procedure.last procedure.update(service: create(:service)) diff --git a/spec/features/admin/procedure_update_spec.rb b/spec/features/admin/procedure_update_spec.rb index 23101549b..f2d09565a 100644 --- a/spec/features/admin/procedure_update_spec.rb +++ b/spec/features/admin/procedure_update_spec.rb @@ -33,6 +33,9 @@ feature 'Administrateurs can edit procedures', js: true do expect(page).to have_field('procedure_libelle', with: procedure.libelle) fill_in('procedure_libelle', with: 'Ma petite démarche') + within('.procedure-form__preview') do + expect(page).to have_content('Ma petite démarche') + end click_on 'Enregistrer'