diff --git a/Gemfile b/Gemfile index c0c5e4e46..c954f3e37 100644 --- a/Gemfile +++ b/Gemfile @@ -60,7 +60,7 @@ gem 'puma' # Use Puma as the app server gem 'pundit' gem 'rack-attack' gem 'rack-mini-profiler' -gem 'rails', '6.0.3.2' +gem 'rails' gem 'rails-i18n' # Locales par défaut gem 'rake-progressbar', require: false gem 'react-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 44573761e..fea174196 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,38 +11,38 @@ GEM specs: aasm (5.0.8) concurrent-ruby (~> 1.0) - actioncable (6.0.3.2) - actionpack (= 6.0.3.2) + actioncable (6.0.3.3) + actionpack (= 6.0.3.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3.2) - actionpack (= 6.0.3.2) - activejob (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + actionmailbox (6.0.3.3) + actionpack (= 6.0.3.3) + activejob (= 6.0.3.3) + activerecord (= 6.0.3.3) + activestorage (= 6.0.3.3) + activesupport (= 6.0.3.3) mail (>= 2.7.1) - actionmailer (6.0.3.2) - actionpack (= 6.0.3.2) - actionview (= 6.0.3.2) - activejob (= 6.0.3.2) + actionmailer (6.0.3.3) + actionpack (= 6.0.3.3) + actionview (= 6.0.3.3) + activejob (= 6.0.3.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.3.2) - actionview (= 6.0.3.2) - activesupport (= 6.0.3.2) + actionpack (6.0.3.3) + actionview (= 6.0.3.3) + activesupport (= 6.0.3.3) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.3.2) - actionpack (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + actiontext (6.0.3.3) + actionpack (= 6.0.3.3) + activerecord (= 6.0.3.3) + activestorage (= 6.0.3.3) + activesupport (= 6.0.3.3) nokogiri (>= 1.8.5) - actionview (6.0.3.2) - activesupport (= 6.0.3.2) + actionview (6.0.3.3) + activesupport (= 6.0.3.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -57,25 +57,25 @@ GEM jsonapi-renderer (>= 0.1.1.beta1, < 0.3) active_storage_validations (0.8.8) rails (>= 5.2.0) - activejob (6.0.3.2) - activesupport (= 6.0.3.2) + activejob (6.0.3.3) + activesupport (= 6.0.3.3) globalid (>= 0.3.6) - activemodel (6.0.3.2) - activesupport (= 6.0.3.2) - activerecord (6.0.3.2) - activemodel (= 6.0.3.2) - activesupport (= 6.0.3.2) - activestorage (6.0.3.2) - actionpack (= 6.0.3.2) - activejob (= 6.0.3.2) - activerecord (= 6.0.3.2) + activemodel (6.0.3.3) + activesupport (= 6.0.3.3) + activerecord (6.0.3.3) + activemodel (= 6.0.3.3) + activesupport (= 6.0.3.3) + activestorage (6.0.3.3) + actionpack (= 6.0.3.3) + activejob (= 6.0.3.3) + activerecord (= 6.0.3.3) marcel (~> 0.3.1) activestorage-openstack (1.4.1) fog-openstack (~> 1.0) marcel mime-types rails (>= 5.2.2) - activesupport (6.0.3.2) + activesupport (6.0.3.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -169,7 +169,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.6) + concurrent-ruby (1.1.7) connection_pool (2.2.2) crack (0.4.3) safe_yaml (~> 1.0.0) @@ -340,7 +340,7 @@ GEM http_accept_language (2.1.1) http_parser.rb (0.6.0) httpclient (2.8.3) - i18n (1.8.3) + i18n (1.8.5) concurrent-ruby (~> 1.0) ice_nine (0.11.2) ipaddress (0.8.3) @@ -384,7 +384,7 @@ GEM railties (>= 4) request_store (~> 1.0) logstash-event (1.2.02) - loofah (2.6.0) + loofah (2.7.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.2.4) @@ -403,7 +403,7 @@ GEM mimemagic (0.3.5) mini_mime (1.0.2) mini_portile2 (2.4.0) - minitest (5.14.1) + minitest (5.14.2) momentjs-rails (2.20.1) railties (>= 3.1) multi_json (1.15.0) @@ -413,7 +413,7 @@ GEM ruby2_keywords (~> 0.0.1) nenv (0.3.0) netrc (0.11.0) - nio4r (2.5.2) + nio4r (2.5.3) nokogiri (1.10.10) mini_portile2 (~> 2.4.0) notiffany (0.1.3) @@ -504,20 +504,20 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.0.3.2) - actioncable (= 6.0.3.2) - actionmailbox (= 6.0.3.2) - actionmailer (= 6.0.3.2) - actionpack (= 6.0.3.2) - actiontext (= 6.0.3.2) - actionview (= 6.0.3.2) - activejob (= 6.0.3.2) - activemodel (= 6.0.3.2) - activerecord (= 6.0.3.2) - activestorage (= 6.0.3.2) - activesupport (= 6.0.3.2) + rails (6.0.3.3) + actioncable (= 6.0.3.3) + actionmailbox (= 6.0.3.3) + actionmailer (= 6.0.3.3) + actionpack (= 6.0.3.3) + actiontext (= 6.0.3.3) + actionview (= 6.0.3.3) + activejob (= 6.0.3.3) + activemodel (= 6.0.3.3) + activerecord (= 6.0.3.3) + activestorage (= 6.0.3.3) + activesupport (= 6.0.3.3) bundler (>= 1.3.0) - railties (= 6.0.3.2) + railties (= 6.0.3.3) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) @@ -536,9 +536,9 @@ GEM rails-i18n (6.0.0) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 7) - railties (6.0.3.2) - actionpack (= 6.0.3.2) - activesupport (= 6.0.3.2) + railties (6.0.3.3) + actionpack (= 6.0.3.3) + activesupport (= 6.0.3.3) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) @@ -682,7 +682,7 @@ GEM sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) @@ -740,7 +740,7 @@ GEM rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - websocket-driver (0.7.2) + websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) @@ -837,7 +837,7 @@ DEPENDENCIES pundit rack-attack rack-mini-profiler - rails (= 6.0.3.2) + rails rails-controller-testing rails-erd rails-i18n diff --git a/app/assets/stylesheets/new_design/flex.scss b/app/assets/stylesheets/new_design/flex.scss index b16b0e243..1a04cdda3 100644 --- a/app/assets/stylesheets/new_design/flex.scss +++ b/app/assets/stylesheets/new_design/flex.scss @@ -25,6 +25,10 @@ justify-content: flex-start; } + &.justify-end { + justify-content: flex-end; + } + &.wrap { flex-wrap: wrap; } diff --git a/app/assets/stylesheets/new_design/helpers.scss b/app/assets/stylesheets/new_design/helpers.scss index e82b9d548..de1fff1ed 100644 --- a/app/assets/stylesheets/new_design/helpers.scss +++ b/app/assets/stylesheets/new_design/helpers.scss @@ -9,7 +9,7 @@ } .mb-4 { - margin-bottom: 4 * $default-spacer; + margin-bottom: 4 * $default-spacer !important; } .ml-1 { @@ -20,6 +20,10 @@ padding-left: 0px !important; } +.bold { + font-weight: bold; +} + .numbers-delimiter { display: inline-block; width: 5px; diff --git a/app/assets/stylesheets/new_design/new_header.scss b/app/assets/stylesheets/new_design/new_header.scss index 597bfd52e..f3613af3f 100644 --- a/app/assets/stylesheets/new_design/new_header.scss +++ b/app/assets/stylesheets/new_design/new_header.scss @@ -192,9 +192,6 @@ $header-mobile-breakpoint: 550px; background: none; } - &::after { - display: none; - } } .header-menu { diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index 3b2401e36..69addf3d6 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -62,40 +62,6 @@ class Admin::ProceduresController < AdminController end end - def publish_validate - @procedure.assign_attributes(publish_params) - end - - def publish - @procedure.assign_attributes(publish_params) - - @procedure.publish_or_reopen!(current_administrateur) - - flash.notice = "Démarche publiée" - render js: "window.location='#{admin_procedures_path}'" - rescue ActiveRecord::RecordInvalid - respond_to do |format| - format.js { render :publish_validate } - end - end - - def transfer - admin = Administrateur.by_email(params[:email_admin].downcase) - - if admin.nil? - respond_to do |format| - format.js { render :transfer, status: :not_found } - end - else - procedure = current_administrateur.procedures.find(params[:procedure_id]) - procedure.clone(admin, false) - - flash.now.notice = "La démarche a correctement été clonée vers le nouvel administrateur." - - respond_to(&:js) - end - end - def archive procedure = current_administrateur.procedures.find(params[:procedure_id]) procedure.close! diff --git a/app/controllers/new_administrateur/procedures_controller.rb b/app/controllers/new_administrateur/procedures_controller.rb index 61a031c20..9715e8832 100644 --- a/app/controllers/new_administrateur/procedures_controller.rb +++ b/app/controllers/new_administrateur/procedures_controller.rb @@ -1,6 +1,6 @@ module NewAdministrateur class ProceduresController < AdministrateurController - before_action :retrieve_procedure, only: [:champs, :annotations, :edit, :monavis, :update_monavis, :jeton, :update_jeton] + before_action :retrieve_procedure, only: [:champs, :annotations, :edit, :monavis, :update_monavis, :jeton, :update_jeton, :publication, :publish] before_action :procedure_locked?, only: [:champs, :annotations] ITEMS_PER_PAGE = 25 @@ -132,6 +132,41 @@ module NewAdministrateur render 'jeton' end + def publication + if @procedure.brouillon? + @procedure_lien = commencer_test_url(path: @procedure.path) + else + @procedure_lien = commencer_url(path: @procedure.path) + end + @procedure.path = @procedure.suggested_path(current_administrateur) + @current_administrateur = current_administrateur + end + + def publish + @procedure.assign_attributes(publish_params) + + if @procedure.publish_or_reopen!(current_administrateur) + redirect_to admin_procedure_path(@procedure) + flash.notice = "Démarche publiée" + else + redirect_to admin_procedure_path(@procedure) + flash.alert = @procedure.errors.full_messages + end + end + + def transfer + admin = Administrateur.by_email(params[:email_admin].downcase) + if admin.nil? + redirect_to admin_procedure_publication_path(params[:procedure_id]) + flash.alert = "Envoi vers #{params[:email_admin]} impossible : cet administrateur n'existe pas" + else + procedure = current_administrateur.procedures.find(params[:procedure_id]) + procedure.clone(admin, false) + redirect_to admin_procedure_path(params[:procedure_id]) + flash.notice = "La démarche a correctement été clonée vers le nouvel administrateur." + end + end + private def apercu_tab @@ -154,5 +189,9 @@ module NewAdministrateur end permited_params end + + def publish_params + params.permit(:path, :lien_site_web) + end end end diff --git a/app/controllers/new_administrateur/types_de_champ_controller.rb b/app/controllers/new_administrateur/types_de_champ_controller.rb index ea7023757..655950b0a 100644 --- a/app/controllers/new_administrateur/types_de_champ_controller.rb +++ b/app/controllers/new_administrateur/types_de_champ_controller.rb @@ -56,30 +56,27 @@ module NewAdministrateur :updated_at ], methods: [ - :cadastres, :drop_down_list_value, - :parcelles_agricoles, :piece_justificative_template_filename, :piece_justificative_template_url, - :quartiers_prioritaires + :cadastres, + :mnhn ] ) } end def type_de_champ_create_params - type_de_champ_params = params.required(:type_de_champ).permit(:cadastres, - :description, - :drop_down_list_value, + type_de_champ_params = params.required(:type_de_champ).permit(:type_champ, :libelle, + :description, :mandatory, - :order_place, - :parcelles_agricoles, :parent_id, - :piece_justificative_template, :private, - :quartiers_prioritaires, - :type_champ) + :drop_down_list_value, + :piece_justificative_template, + :cadastres, + :mnhn) if type_de_champ_params[:parent_id].present? type_de_champ_params[:parent_id] = TypeDeChamp.to_stable_id(type_de_champ_params[:parent_id]) @@ -89,15 +86,14 @@ module NewAdministrateur end def type_de_champ_update_params - params.required(:type_de_champ).permit(:cadastres, - :description, - :drop_down_list_value, + params.required(:type_de_champ).permit(:type_champ, :libelle, + :description, :mandatory, - :parcelles_agricoles, + :drop_down_list_value, :piece_justificative_template, - :quartiers_prioritaires, - :type_champ) + :cadastres, + :mnhn) end end end diff --git a/app/helpers/procedure_helper.rb b/app/helpers/procedure_helper.rb index 93ac0dc0f..4124d3c1d 100644 --- a/app/helpers/procedure_helper.rb +++ b/app/helpers/procedure_helper.rb @@ -13,7 +13,7 @@ module ProcedureHelper safe_join(parts, ' ') end - def procedure_modal_text(procedure, key) + def procedure_publish_text(procedure, key) action = procedure.close? ? :reopen : :publish t(action, scope: [:modal, :publish, key]) end diff --git a/app/javascript/components/MapEditor/index.js b/app/javascript/components/MapEditor/index.js index c8bb44555..c025f5fb3 100644 --- a/app/javascript/components/MapEditor/index.js +++ b/app/javascript/components/MapEditor/index.js @@ -23,7 +23,7 @@ import { const Map = ReactMapboxGl({}); -function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) { +function MapEditor({ featureCollection, url, preview, options }) { const drawControl = useRef(null); const [currentMap, setCurrentMap] = useState(null); @@ -35,10 +35,10 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) { const [cadastresFeatureCollection, setCadastresFeatureCollection] = useState( filterFeatureCollection(featureCollection, 'cadastre') ); - const mapStyle = useMemo(() => getMapStyle(style, hasCadastres), [ - style, - hasCadastres - ]); + const mapStyle = useMemo( + () => getMapStyle(style, options.cadastres, options.mnhn), + [style, options] + ); const translations = [ ['.mapbox-gl-draw_line', 'Tracer une ligne'], @@ -306,7 +306,7 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) { height: '500px' }} > - {hasCadastres ? ( + {options.cadastres ? ( <GeoJSONLayer data={cadastresFeatureCollection} fillPaint={polygonCadastresFill} @@ -326,7 +326,7 @@ function MapEditor({ featureCollection, url, preview, hasCadastres, ign }) { trash: true }} /> - <SwitchMapStyle style={style} setStyle={setStyle} ign={ign} /> + <SwitchMapStyle style={style} setStyle={setStyle} ign={options.ign} /> <ZoomControl /> </Map> </> @@ -341,8 +341,11 @@ MapEditor.propTypes = { }), url: PropTypes.string, preview: PropTypes.bool, - hasCadastres: PropTypes.bool, - ign: PropTypes.bool + options: PropTypes.shape({ + cadastres: PropTypes.bool, + mnhn: PropTypes.bool, + ign: PropTypes.bool + }) }; export default MapEditor; diff --git a/app/javascript/components/MapReader/index.js b/app/javascript/components/MapReader/index.js index 4386ba77f..48c86a7ef 100644 --- a/app/javascript/components/MapReader/index.js +++ b/app/javascript/components/MapReader/index.js @@ -16,7 +16,7 @@ import { const Map = ReactMapboxGl({}); -const MapReader = ({ featureCollection, ign }) => { +const MapReader = ({ featureCollection, options }) => { const [currentMap, setCurrentMap] = useState(null); const [style, setStyle] = useState('ortho'); const cadastresFeatureCollection = useMemo( @@ -52,10 +52,10 @@ const MapReader = ({ featureCollection, ign }) => { [selectionsUtilisateurFeatureCollection] ); const hasCadastres = !!cadastresFeatureCollection.length; - const mapStyle = useMemo(() => getMapStyle(style, hasCadastres), [ - style, - cadastresFeatureCollection - ]); + const mapStyle = useMemo( + () => getMapStyle(style, hasCadastres, options.mnhn), + [style, options, cadastresFeatureCollection] + ); const popup = useMemo( () => new Popup({ @@ -184,7 +184,7 @@ const MapReader = ({ featureCollection, ign }) => { /> ) : null} - <SwitchMapStyle style={style} setStyle={setStyle} ign={ign} /> + <SwitchMapStyle style={style} setStyle={setStyle} ign={options.ign} /> <ZoomControl /> </Map> ); @@ -196,7 +196,10 @@ MapReader.propTypes = { bbox: PropTypes.array, features: PropTypes.array }), - ign: PropTypes.bool + options: PropTypes.shape({ + ign: PropTypes.bool, + mnhn: PropTypes.bool + }) }; export default MapReader; diff --git a/app/javascript/components/MapStyles/base-style.js b/app/javascript/components/MapStyles/base-style.js index 8a8ab876c..1443e4500 100644 --- a/app/javascript/components/MapStyles/base-style.js +++ b/app/javascript/components/MapStyles/base-style.js @@ -1,15 +1,36 @@ +const IGN_TOKEN = 'rc1egnbeoss72hxvd143tbyk'; + +function ignServiceURL(layer, format = 'image/png') { + const url = `https://wxs.ign.fr/${IGN_TOKEN}/geoportail/wmts`; + const query = + 'service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&style=normal'; + + return `${url}?${query}&layer=${layer}&format=${format}`; +} + +function rasterSource(tiles, attribution) { + return { + type: 'raster', + tiles, + tileSize: 256, + attribution, + minzoom: 0, + maxzoom: 18 + }; +} + export default { version: 8, metadat: { 'mapbox:autocomposite': false, 'mapbox:groups': { - '1444849242106.713': { collapsed: false, name: 'Places' }, - '1444849334699.1902': { collapsed: true, name: 'Bridges' }, - '1444849345966.4436': { collapsed: false, name: 'Roads' }, - '1444849354174.1904': { collapsed: true, name: 'Tunnels' }, - '1444849364238.8171': { collapsed: false, name: 'Buildings' }, - '1444849382550.77': { collapsed: false, name: 'Water' }, - '1444849388993.3071': { collapsed: false, name: 'Land' } + 1444849242106.713: { collapsed: false, name: 'Places' }, + 1444849334699.1902: { collapsed: true, name: 'Bridges' }, + 1444849345966.4436: { collapsed: false, name: 'Roads' }, + 1444849354174.1904: { collapsed: true, name: 'Tunnels' }, + 1444849364238.8171: { collapsed: false, name: 'Buildings' }, + 1444849382550.77: { collapsed: false, name: 'Water' }, + 1444849388993.3071: { collapsed: false, name: 'Land' } }, 'mapbox:type': 'template', 'openmaptiles:mapbox:owner': 'openmaptiles', @@ -41,20 +62,34 @@ export default { minzoom: 0, maxzoom: 19 }, - 'carte-ign': { - type: 'raster', - tiles: [ - 'https://wxs.ign.fr/rc1egnbeoss72hxvd143tbyk/geoportail/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=GEOGRAPHICALGRIDSYSTEMS.MAPS&format=image/jpeg&style=normal' - ], - tileSize: 256, - attribution: 'IGN-F/Géoportail', - minzoom: 0, - maxzoom: 18 - }, cadastre: { type: 'vector', url: 'https://openmaptiles.geo.data.gouv.fr/data/cadastre.json' - } + }, + 'plan-ign': rasterSource( + [ignServiceURL('GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2')], + 'IGN-F/Géoportail' + ), + 'protectedareas-gp': rasterSource( + [ignServiceURL('PROTECTEDAREAS.GP')], + 'IGN-F/Géoportail/MNHN' + ), + 'protectedareas-pn': rasterSource( + [ignServiceURL('PROTECTEDAREAS.PN')], + 'IGN-F/Géoportail/MNHN' + ), + 'protectedareas-pnr': rasterSource( + [ignServiceURL('PROTECTEDAREAS.PNR')], + 'IGN-F/Géoportail/MNHN' + ), + 'protectedareas-sic': rasterSource( + [ignServiceURL('PROTECTEDAREAS.SIC')], + 'IGN-F/Géoportail/MNHN' + ), + 'protectedareas-zps': rasterSource( + [ignServiceURL('PROTECTEDAREAS.ZPS')], + 'IGN-F/Géoportail/MNHN' + ) }, sprite: 'https://openmaptiles.github.io/osm-bright-gl-style/sprite', glyphs: 'https://openmaptiles.geo.data.gouv.fr/fonts/{fontstack}/{range}.pbf' diff --git a/app/javascript/components/MapStyles/index.js b/app/javascript/components/MapStyles/index.js index 68298a73e..4122f0ef5 100644 --- a/app/javascript/components/MapStyles/index.js +++ b/app/javascript/components/MapStyles/index.js @@ -3,16 +3,16 @@ import cadastre from './cadastre'; import orthoStyle from './ortho-style'; import vectorStyle from './vector-style'; -const ignStyle = [ - { - id: 'carte-ign', +function rasterStyle(source) { + return { + id: source, + source, type: 'raster', - source: 'carte-ign', paint: { 'raster-resampling': 'linear' } - } -]; + }; +} -export function getMapStyle(style, hasCadastres) { +export function getMapStyle(style, hasCadastres, hasMNHN) { const mapStyle = { ...baseStyle }; switch (style) { @@ -27,7 +27,7 @@ export function getMapStyle(style, hasCadastres) { mapStyle.name = 'Carte OSM'; break; case 'ign': - mapStyle.layers = ignStyle; + mapStyle.layers = [rasterStyle('plan-ign')]; mapStyle.id = 'ign'; mapStyle.name = 'Carte IGN'; break; @@ -38,6 +38,17 @@ export function getMapStyle(style, hasCadastres) { mapStyle.id += '-cadastre'; } + if (hasMNHN) { + mapStyle.layers = mapStyle.layers.concat([ + rasterStyle('protectedareas-gp'), + rasterStyle('protectedareas-pn'), + rasterStyle('protectedareas-pnr'), + rasterStyle('protectedareas-sic'), + rasterStyle('protectedareas-zps') + ]); + mapStyle.id += '-mnhn'; + } + return mapStyle; } diff --git a/app/javascript/components/TypesDeChampEditor/components/TypeDeChamp.js b/app/javascript/components/TypesDeChampEditor/components/TypeDeChamp.js index 6d68ffbe1..57131402b 100644 --- a/app/javascript/components/TypesDeChampEditor/components/TypeDeChamp.js +++ b/app/javascript/components/TypesDeChampEditor/components/TypeDeChamp.js @@ -140,6 +140,10 @@ const TypeDeChamp = sortableElement( label="Cadastres" handler={updateHandlers.cadastres} /> + <TypeDeChampCarteOption + label="Zones naturelles protégées" + handler={updateHandlers.mnhn} + /> </TypeDeChampCarteOptions> <TypeDeChampRepetitionOptions isVisible={isRepetition} @@ -206,6 +210,7 @@ function createUpdateHandlers(dispatch, typeDeChamp, index, prefix) { export const FIELDS = [ 'cadastres', + 'mnhn', 'description', 'drop_down_list_value', 'libelle', diff --git a/app/javascript/new_design/dropdown.js b/app/javascript/new_design/dropdown.js index 1614c08d3..c92a8f896 100644 --- a/app/javascript/new_design/dropdown.js +++ b/app/javascript/new_design/dropdown.js @@ -2,16 +2,21 @@ import { delegate } from '@utils'; delegate('click', 'body', (event) => { if (!event.target.closest('.dropdown')) { - [...document.querySelectorAll('.dropdown')].forEach((element) => - element.classList.remove('open', 'fade-in-down') - ); + [...document.querySelectorAll('.dropdown')].forEach((element) => { + const button = element.querySelector('.dropdown-button'); + button.setAttribute('aria-expanded', false); + element.classList.remove('open', 'fade-in-down'); + }); } }); delegate('click', '.dropdown-button', (event) => { event.stopPropagation(); - const parent = event.target.closest('.dropdown-button').parentElement; + const button = event.target.closest('.dropdown-button'); + const parent = button.parentElement; if (parent.classList.contains('dropdown')) { parent.classList.toggle('open'); + var buttonExpanded = button.getAttribute('aria-expanded') === 'true'; + button.setAttribute('aria-expanded', !buttonExpanded); } }); diff --git a/app/models/champs/carte_champ.rb b/app/models/champs/carte_champ.rb index 448baf9b8..b12c85f3a 100644 --- a/app/models/champs/carte_champ.rb +++ b/app/models/champs/carte_champ.rb @@ -57,6 +57,18 @@ class Champs::CarteChamp < Champ type_de_champ&.parcelles_agricoles && type_de_champ.parcelles_agricoles != '0' end + def mnhn? + type_de_champ&.mnhn && type_de_champ.mnhn != '0' + end + + def render_options + { + ign: Flipper.enabled?(:carte_ign, procedure), + mnhn: mnhn?, + cadastres: cadastres? + } + end + def position if dossier.present? dossier.geo_position diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index a3ee48103..02c3425f0 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -56,7 +56,7 @@ class TypeDeChamp < ApplicationRecord belongs_to :parent, class_name: 'TypeDeChamp', optional: true has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', inverse_of: :parent, dependent: :destroy - store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj, :drop_down_options, :skip_pj_validation + store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :mnhn, :old_pj, :drop_down_options, :skip_pj_validation has_many :revision_types_de_champ, class_name: 'ProcedureRevisionTypeDeChamp', dependent: :destroy, inverse_of: :type_de_champ delegate :tags_for_template, to: :dynamic_type @@ -286,12 +286,11 @@ class TypeDeChamp < ApplicationRecord :updated_at ], methods: [ - :cadastres, :drop_down_list_value, - :parcelles_agricoles, :piece_justificative_template_filename, :piece_justificative_template_url, - :quartiers_prioritaires + :cadastres, + :mnhn ] } TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE diff --git a/app/views/admin/procedures/_list.html.haml b/app/views/admin/procedures/_list.html.haml deleted file mode 100644 index 1097076b5..000000000 --- a/app/views/admin/procedures/_list.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -- if smart_listing.present? - %table.table#dossiers-list - %thead - %th#ID= smart_listing.sortable 'ID', 'id' - %th#libelle= smart_listing.sortable 'Libellé', 'libelle' - - if @active_class - %th Lien - - if @active_class || @archived_class - %th#published_at= smart_listing.sortable 'Date publication', 'published_at' - - else - %th#created_at= smart_listing.sortable 'Date création', 'created_at' - %th Actions - - - @procedures.each do |procedure| - - procedure = procedure - - admin_procedure_href = admin_procedure_path(procedure) - %tr{ id: "tr_dossier_#{procedure.id}", data: { href: admin_procedure_href } } - %td= link_to(procedure.id, admin_procedure_href) - %td.col-xs-6= link_to(procedure.libelle, admin_procedure_href) - - if procedure.publiee? - %td.procedure-lien= link_to(procedure_lien(procedure), procedure_lien(procedure)) - - if procedure.locked? - %td= link_to(procedure.published_at.present? ? try_format_datetime(procedure.published_at) : "", admin_procedure_href) - - else - %td= link_to(try_format_datetime(procedure.created_at), admin_procedure_href) - %td - = link_to('Cloner', admin_procedure_clone_path(procedure.id), data: { method: :put }, class: 'btn-sm btn-primary clone-btn') - - if procedure.can_be_deleted_by_administrateur? - = link_to('X', url_for(controller: 'admin/procedures', action: :destroy, id: procedure.id), data: { method: :delete, confirm: "Confirmez-vous la suppression de la démarche ? \n\n Attention : toute suppression est définitive et s’appliquera aux éventuels autres administrateurs de cette démarche !" }, class: 'btn-sm btn-danger') - - = smart_listing.paginate - = smart_listing.pagination_per_page_links - %br - - -- else - %h4.center - Aucune démarche diff --git a/app/views/admin/procedures/_modal_publish.html.haml b/app/views/admin/procedures/_modal_publish.html.haml deleted file mode 100644 index 869e73330..000000000 --- a/app/views/admin/procedures/_modal_publish.html.haml +++ /dev/null @@ -1,49 +0,0 @@ -#publish-modal.modal{ "aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1" } - .modal-dialog.modal-lg{ :role => "document" } - = form_tag admin_procedure_publish_path(procedure_id: procedure.id), method: :put, remote: true do - .modal-content - .modal-header - %button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" } - %span{ "aria-hidden" => "true" } × - %h4#myModalLabel.modal-title - = procedure_modal_text(procedure, :title) - %span#publish-modal-title - .modal-body - .text-info - %p - = procedure_modal_text(procedure, :body) - %b Elle ne pourra plus être modifiée à l’issue de cette publication. - .form-group - %h4 Adresse de la démarche - %p Vous pouvez personnaliser le lien public de la démarche pour en faciliter l’accès. - %p - = commencer_url(path: '') - = text_field_tag(:path, procedure.path, - id: 'procedure_path', - placeholder: 'chemin-de-la-démarche', - required: true, - class: 'form-control', - pattern: '^[a-z0-9_-]{3,50}$', - title: "De 3 à 50 caractères; minuscules, chiffres et tiret seulement", - data: { remote: true, debounce: true, url: admin_procedure_publish_validate_path(procedure) }, - autocomplete: 'off', - style: 'width: 300px; display: inline;') - = render 'publish_path_message', procedure: procedure, administrateur: administrateur - .text-info - Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers #{APPLICATION_NAME}. Ne dites pas non plus aux usagers de se rendre sur le site générique #{APPLICATION_NAME}, donnez-leur toujours le lien complet. - .form-group - %h4 Diffusion de la démarche - %p Où les utilisateurs trouveront-ils le lien de la démarche ? Typiquement, il s’agit d’une page de votre site web. - %p.center - = text_field_tag(:lien_site_web, procedure.lien_site_web, - required: true, - class: 'form-control', - autocomplete: 'off', - placeholder: 'https://exemple.gouv.fr/ma_demarche') - .text-info - Prenez quelques minutes pour savoir comment établir une bonne relation avec les usagers de votre démarche : - = link_to "Regarder la vidéo de 5 minutes.", - "https://vimeo.com/334463514", - target: "_blank" - .modal-footer - = render 'publish_buttons', procedure: procedure, administrateur: administrateur diff --git a/app/views/admin/procedures/_modal_transfer.html.haml b/app/views/admin/procedures/_modal_transfer.html.haml deleted file mode 100644 index 9c8176609..000000000 --- a/app/views/admin/procedures/_modal_transfer.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -#transfer-modal.modal.fade{ "aria-labelledby" => "TransferProcedureModal", :role => "dialog", :tabindex => "-1" } - .modal-dialog.modal-md{ :role => "document" } - = form_tag admin_procedure_transfer_path(procedure_id: @procedure.id), method: :post, remote: true do - .modal-content - .modal-header - %button.close{ "aria-label" => "Close", "data-dismiss" => "modal", :type => "button" } - %span{ "aria-hidden" => "true" } × - - %h4#myModalLabel.modal-title - Envoyer une copie de cette démarche à un autre administrateur - - .modal-body - %p - Cette fonctionnalité vous permet de d'envoyer une copie de votre démarche à un autre administrateur. - - %div{ style:'margin-top:20px' } - = text_field_tag :email_admin, '', { class: 'form-control', - type: 'email', - placeholder: 'Email administrateur cible', - style: 'width: 300px; margin-left:auto; margin-right:auto' } - - #not_found_admin.center.text-danger{ style:'display: none; margin-top: 10px;' } - Cet administrateur n'existe pas. - - .modal-footer - = submit_tag "Envoyer", class: 'btn btn-success' - = button_tag 'Annuler', class: %w(btn btn btn-default), id: 'cancel', data: { dismiss: 'modal' } diff --git a/app/views/admin/procedures/_onglets.html.haml b/app/views/admin/procedures/_onglets.html.haml deleted file mode 100644 index d5bb2970a..000000000 --- a/app/views/admin/procedures/_onglets.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -#onglets - %ul.nav.nav-tabs - %li{ class: @draft_class } - %a{ :href => "#{url_for :admin_procedures_draft}" } - %h5.text-primary - En test - - %li{ class: @active_class } - %a{ :href => "#{url_for :admin_procedures}" } - %h5.text-success - Actives - - %li{ class: @archived_class } - %a{ :href => "#{url_for :admin_procedures_archived}" } - %h5{ style: 'color: black;' } - Closes -%br diff --git a/app/views/admin/procedures/_publish_buttons.html.haml b/app/views/admin/procedures/_publish_buttons.html.haml deleted file mode 100644 index 6630763d8..000000000 --- a/app/views/admin/procedures/_publish_buttons.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -#publish-buttons - = button_tag "Annuler", class: %w(btn btn-default), data: { dismiss: :modal } - - - procedure.validate(:publication) - - errors = procedure.errors - -# Ignore the :taken error if the path can be claimed - - if errors.details[:path]&.pluck(:error)&.include?(:taken) && procedure.path_available?(administrateur, procedure.path) - - errors.delete(:path) - - - options = { class: %w(btn btn-success), id: 'publish' } - - if errors.details[:path].present? - - options[:disabled] = :disabled - = submit_tag procedure_modal_text(@procedure, :submit), options diff --git a/app/views/admin/procedures/_publish_path_message.html.haml b/app/views/admin/procedures/_publish_path_message.html.haml deleted file mode 100644 index 5ed0a1dcd..000000000 --- a/app/views/admin/procedures/_publish_path_message.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -#publish-path-message - - procedure.validate(:publication) - - errors = procedure.errors - -# Ignore the :taken error if the path can be claimed, and instead display the :taken_can_be_claimed error message. - - if errors.details[:path]&.pluck(:error)&.include?(:taken) && procedure.path_available?(administrateur, procedure.path) - .alert.alert-warning - = errors.full_message('Le lien public', errors.generate_message(:path, :taken_can_be_claimed)) - - elsif errors.messages[:path].present? - -# Display the actual errors for :path - .alert.alert-danger - = errors.full_message('Le lien public', errors.messages[:path].first) diff --git a/app/views/admin/procedures/index.html.haml b/app/views/admin/procedures/index.html.haml deleted file mode 100644 index 3f67d6ab5..000000000 --- a/app/views/admin/procedures/index.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -#admins-index - .default-data-block.default_visible - .row.show-block#new_dossiers - .header - .col-lg-10.col-md-10.col-sm-10.col-xs-10.title - .carret-right - .carret-down - Démarches - %a{ href: new_from_existing_admin_procedures_path } - #new-procedure.col-lg-2.col-md-2.col-sm-2.col-xs-2.action - Nouvelle - - .body - = smart_listing_render :procedures diff --git a/app/views/admin/procedures/index.js.erb b/app/views/admin/procedures/index.js.erb deleted file mode 100644 index b2e0bdc6a..000000000 --- a/app/views/admin/procedures/index.js.erb +++ /dev/null @@ -1 +0,0 @@ -<%= smart_listing_update :procedures %> diff --git a/app/views/admin/procedures/publish_validate.js.haml b/app/views/admin/procedures/publish_validate.js.haml deleted file mode 100644 index 74c0681c3..000000000 --- a/app/views/admin/procedures/publish_validate.js.haml +++ /dev/null @@ -1,4 +0,0 @@ -= render_to_element("#publish-path-message", partial: 'publish_path_message', outer: true, - locals: { procedure: @procedure, administrateur: current_administrateur }) -= render_to_element("#publish-buttons", partial: 'publish_buttons', outer: true, - locals: { procedure: @procedure, administrateur: current_administrateur }) diff --git a/app/views/admin/procedures/show.html.haml b/app/views/admin/procedures/show.html.haml deleted file mode 100644 index 6a1c19257..000000000 --- a/app/views/admin/procedures/show.html.haml +++ /dev/null @@ -1,128 +0,0 @@ -= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert' -.row.white-back - = render 'modal_publish', procedure: @procedure, administrateur: @current_administrateur - = render 'modal_transfer' - - #procedure_show - - if @procedure.brouillon? - - if @procedure.missing_steps.present? - - missing_elements = [] - - if @procedure.missing_instructeurs? - - missing_elements << 'des instructeurs' - - if @procedure.service.nil? - - missing_elements << 'un service' - - message = "Affectez #{missing_elements.join(' et ')} à votre démarche." - %button.action_button.btn.btn-success#disabled-publish-procedure{ style: 'float: right; margin-top: 10px;', disabled: true, title: message } - %i.fa.fa-eraser - Publier - - else - %button.btn.btn-success#publish-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px;' } - %i.fa.fa-eraser - Publier - - %button.btn.btn-default#transfer-procedure{ data: { target: '#transfer-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' } - %i.fa.fa-exchange - Envoyer une copie - - - if @procedure.close? || @procedure.depubliee? - %button.btn.btn-default#reopen-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' } - %i.fa.fa-rocket - Réactiver - - - elsif @procedure.publiee? - = form_tag admin_procedure_archive_path(procedure_id: @procedure.id), method: :put, style: 'float: right; margin-top: 10px;' do - %button#archive-procedure.btn.btn-small.btn-default.text-info{ type: :button } - %i.fa.fa-eraser - Archiver - #confirm - %button#valid.btn.btn-small.btn-success{ type: :submit } - %i.fa.fa-check - Valider - %button#cancel.btn.btn-small.btn-danger{ type: :button } - %i.fa.fa-remove - Annuler - - .lien-demarche - %h3 - - if @procedure.brouillon? - Test et publication - - else - Publication - %div{ style: 'margin-top: 30px;' } - - if @procedure.close? - Cette démarche est <strong>close</strong> et n’est donc plus accessible par le public. - - elsif @procedure.publiee? - Cette démarche est <strong>publiée</strong>, certains éléments ne peuvent plus être modifiés. - Pour y accéder vous pouvez utiliser le lien : - = link_to @procedure_lien, sanitize_url(@procedure_lien), target: :blank, rel: :noopener - %br - %br - Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers #{APPLICATION_NAME}. Ne dites pas non plus aux usagers de se rendre sur le site générique #{APPLICATION_NAME}, donnez-leur toujours le lien complet. - - elsif @procedure.brouillon? - - if @procedure.missing_steps.empty? - %p - Cette démarche est actuellement <strong>en test</strong>, - pour y accéder vous pouvez utiliser le lien : - = link_to @procedure_lien, sanitize_url(@procedure_lien), target: :blank, rel: :noopener - %p - Toute personne ayant la connaissance de ce lien pourra ainsi remplir des dossiers de test sur votre démarche. - %br - %h4 Protection des Données personnelles - %p - À ce moment du processus de création, vous devez informer votre Délégué à la Protection des Données personnelles (DPD). - ( - %a{ href:'https://www.cnil.fr/fr/protection-des-donnees-les-bons-reflexes', target:'_blank' } - https://www.cnil.fr/fr/protection-des-donnees-les-bons-reflexes - ) - Si votre démarche propose de collecter des données personnelles, vous devez informer votre DPD. Chaque organisme en a un. - %p - Ce dernier pourra vous aider dans la finalisation de votre démarche, et vous inviter à vous interroger sur les données collectées, et sur la pertinence de ses dernières. - N'oubliez pas : toutes les démarches qui contiennent des données personnelles doivent être consignées dans un registre des traitements : - %a{ href:'https://www.cnil.fr/fr/RGDP-le-registre-des-activites-de-traitement', target:'_blank' } - https://www.cnil.fr/fr/RGDP-le-registre-des-activites-de-traitement - %p - Comment faire : - vous pouvez soit lui communiquer par email le lien vers la démarche en test, ou bien le nommer « administrateur ». Dans tous les cas, ne publiez votre démarche qu’après avoir eu son avis. - - %br - %h4 Ce que vous pouvez faire lorsque vous êtes en test - %p - Profitez de la phase de test pour tester la saisie de dossiers, ainsi que toutes les fonctionnalités associées (instruction, emails automatiques, attestations, etc.). - %p - Vous pouvez effectuer toutes les modifications que vous souhaitez sur votre démarche pendant cette phase de test. - %p - Les dossiers qui seront remplis pendant la phase de test seront automatiquement supprimés lors de la modification ou la publication de votre démarche. - %br - - %h4 Ce qui se passe lorsque vous passez en publication - %p - Une fois que vous êtes prêt à publier définitivement votre démarche, cliquez sur le bouton "Publier" pour choisir le lien définitif de votre démarche, les modifications sur la démarches ne seront alors plus possibles. - - %br - %h4 Prenez quelques minutes pour savoir comment établir une bonne relation avec les usagers de votre démarche: - %p.center - %br - %iframe{ :src =>"https://player.vimeo.com/video/334463514?color=0069CC",:width =>"640",:height =>"360",:frameborder => "0" } - - else - .alert.alert-info - Pour pouvoir tester cette démarche, vous devez d’abord lui affecter - - if @procedure.missing_instructeurs? - = link_to("des instructeurs", admin_procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur)) - - if @procedure.missing_instructeurs? && @procedure.service.nil? - et - - if @procedure.service.nil? - = link_to("un service", admin_services_path(procedure_id: @procedure)) - \. - - else - - if @procedure.missing_steps.include?(:service) - %p.alert.alert-danger - Vous devez renseigner les coordonnées de votre Service administratif avant de pouvoir publier votre démarche. - = link_to 'Cliquez ici.', (@current_administrateur.services.present? ? url_for(admin_services_path(procedure_id: @procedure.id)) : url_for(new_admin_service_path(procedure_id: @procedure.id))) - - - if @procedure.missing_steps.include?(:instructeurs) - %p.alert.alert-danger - Vous devez affecter des instructeurs avant de pouvoir publier votre démarche. - = link_to 'Cliquez ici.', admin_procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur) - - %p.alert.alert-info - Cette démarche n’a pas encore de lien, et n’est pas accessible par le public. diff --git a/app/views/admin/procedures/transfer.js.erb b/app/views/admin/procedures/transfer.js.erb deleted file mode 100644 index df6c21c17..000000000 --- a/app/views/admin/procedures/transfer.js.erb +++ /dev/null @@ -1,10 +0,0 @@ -<%- if response.status == 404 %> - $('#not_found_admin').slideDown(100); -<%- else %> - <%= render_flash %> - - $('#not_found_admin').slideUp(100); - $("#email_admin").val(''); - - $('[role=dialog]').modal('hide'); -<%- end %> diff --git a/app/views/instructeurs/dossiers/_header_actions.html.haml b/app/views/instructeurs/dossiers/_header_actions.html.haml index e83bff6ff..60e0a9214 100644 --- a/app/views/instructeurs/dossiers/_header_actions.html.haml +++ b/app/views/instructeurs/dossiers/_header_actions.html.haml @@ -1,7 +1,7 @@ %span.dropdown.print-menu-opener - %button.button.dropdown-button.icon-only{ title: 'imprimer', 'aria-label': 'imprimer' } + %button.button.dropdown-button.icon-only{ title: 'imprimer', 'aria-label': 'imprimer', 'aria-expanded' => 'false', 'aria-controls' => 'print-menu' } %span.icon.printer - %ul.print-menu.dropdown-content + %ul#print-menu.print-menu.dropdown-content %li = link_to "Tout le dossier", print_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link" %li @@ -14,9 +14,9 @@ - if PiecesJustificativesService.liste_pieces_justificatives(dossier).present? %span.dropdown.print-menu-opener - %button.button.dropdown-button.icon-only + %button.button.dropdown-button.icon-only{ 'aria-expanded' => 'false', 'aria-controls' => 'print-pj-menu' } %span.icon.attached - %ul.print-menu.dropdown-content + %ul#print-pj-menu.print-menu.dropdown-content %li - if PiecesJustificativesService.pieces_justificatives_total_size(dossier) < Dossier::TAILLE_MAX_ZIP = link_to "Télécharger toutes les pièces jointes", telecharger_pjs_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link" diff --git a/app/views/instructeurs/dossiers/_state_button.html.haml b/app/views/instructeurs/dossiers/_state_button.html.haml index f30fd97d5..c6b58fcae 100644 --- a/app/views/instructeurs/dossiers/_state_button.html.haml +++ b/app/views/instructeurs/dossiers/_state_button.html.haml @@ -1,10 +1,10 @@ .dropdown -# Dropdown button title - %button.button.primary.dropdown-button{ class: button_or_label_class(dossier) } + %button.button.primary.dropdown-button{ class: button_or_label_class(dossier), 'aria-expanded' => 'false', 'aria-controls' => 'state-menu' } = dossier_display_state dossier -# Dropdown content - .dropdown-content.fade-in-down + #state-menu.dropdown-content.fade-in-down - if dossier.en_construction? -# ------------------------------------------------------ diff --git a/app/views/instructeurs/procedures/_download_dossiers.html.haml b/app/views/instructeurs/procedures/_download_dossiers.html.haml index a466d3cef..1a28d2292 100644 --- a/app/views/instructeurs/procedures/_download_dossiers.html.haml +++ b/app/views/instructeurs/procedures/_download_dossiers.html.haml @@ -1,8 +1,8 @@ - if procedure.dossiers.state_not_brouillon.any? %span.dropdown - %button.button.dropdown-button + %button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'download-menu' } Télécharger tous les dossiers - .dropdown-content.fade-in-down{ style: 'width: 330px' } + #download-menu.dropdown-content.fade-in-down{ style: 'width: 330px' } %ul.dropdown-items - [[xlsx_export, :xlsx], [ods_export, :ods], [csv_export, :csv]].each do |(export, format)| %li diff --git a/app/views/instructeurs/procedures/show.html.haml b/app/views/instructeurs/procedures/show.html.haml index 948338ee2..520004861 100644 --- a/app/views/instructeurs/procedures/show.html.haml +++ b/app/views/instructeurs/procedures/show.html.haml @@ -78,9 +78,9 @@ - if @dossiers.present? || @current_filters.count > 0 = paginate @dossiers %span.dropdown - %button.button.dropdown-button + %button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'filter-menu' } Filtrer - .dropdown-content.left-aligned.fade-in-down + #filter-menu.dropdown-content.left-aligned.fade-in-down = form_tag add_filter_instructeur_procedure_path(@procedure), method: :post, class: 'dropdown-form large' do = label_tag :field, "Colonne" = select_tag :field, options_for_select(@available_fields_to_filters) @@ -118,9 +118,9 @@ %th.action-col.follow-col %span.dropdown - %button.button.dropdown-button + %button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'custom-menu' } Personnaliser - .dropdown-content.fade-in-down + #custom-menu.dropdown-content.fade-in-down = form_tag update_displayed_fields_instructeur_procedure_path(@procedure), method: :patch, class: 'dropdown-form columns-form' do = select_tag :values, options_for_select(@procedure_presentation.fields_for_select, diff --git a/app/views/invites/_dropdown.html.haml b/app/views/invites/_dropdown.html.haml index 91a451c9e..a927fdafe 100644 --- a/app/views/invites/_dropdown.html.haml +++ b/app/views/invites/_dropdown.html.haml @@ -1,5 +1,5 @@ .dropdown.invite-user-action - %button.button.dropdown-button + %button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'invite-content' } %span.icon.person - if dossier.invites.count > 0 Voir les personnes invitées @@ -10,5 +10,5 @@ - else Inviter une personne à modifier ce dossier - .dropdown-content.fade-in-down + #invite-content.dropdown-content.fade-in-down = render partial: "invites/form", locals: { dossier: dossier } diff --git a/app/views/layouts/_account_dropdown.haml b/app/views/layouts/_account_dropdown.haml index 892a44e0e..b3b0c9a72 100644 --- a/app/views/layouts/_account_dropdown.haml +++ b/app/views/layouts/_account_dropdown.haml @@ -1,8 +1,8 @@ .dropdown.header-menu-opener - %button.button.dropdown-button.header-menu-button{ title: "Mon compte" } + %button.button.dropdown-button.icon-only.header-menu-button{ title: "Mon compte", 'aria-expanded' => 'false', 'aria-controls' => 'mon_compte_menu' } .hidden Mon compte - = image_tag "icons/account-circle.svg", alt: '' - %ul.header-menu.dropdown-content + = image_tag "icons/account-circle.svg", alt: 'Mon compte' + %ul.header-menu.dropdown-content#mon_compte_menu %li .menu-item{ title: current_email } = current_email diff --git a/app/views/new_administrateur/mail_templates/edit.html.haml b/app/views/new_administrateur/mail_templates/edit.html.haml index 7f56949fb..c719e8bfe 100644 --- a/app/views/new_administrateur/mail_templates/edit.html.haml +++ b/app/views/new_administrateur/mail_templates/edit.html.haml @@ -1,3 +1,4 @@ +- content_for(:root_class, 'scroll-margins-for-sticky-footer') - if params[:id] == 'closed_mail' = render partial: 'admin/closed_mail_template_attestation_inconsistency_alert' diff --git a/app/views/new_administrateur/procedures/_procedure_transfert.html.haml b/app/views/new_administrateur/procedures/_procedure_transfert.html.haml new file mode 100644 index 000000000..7bb595947 --- /dev/null +++ b/app/views/new_administrateur/procedures/_procedure_transfert.html.haml @@ -0,0 +1,13 @@ += form_tag admin_procedure_transfer_path(procedure_id: @procedure.id), method: :post, class: 'form' do + .card + %h2.card-title + Envoyer une copie de cette démarche à un autre administrateur + %p.mb-4 + Cette fonctionnalité vous permet de d'envoyer une copie de votre démarche à un autre administrateur. + + %div + = text_field_tag :email_admin, '', { class: 'form-control', + type: 'email', + placeholder: 'Email administrateur cible' } + + = submit_tag "Envoyer à l'administrateur", class: 'button primary' diff --git a/app/views/new_administrateur/procedures/_procedures_list.html.haml b/app/views/new_administrateur/procedures/_procedures_list.html.haml index 2641df629..4f2678533 100644 --- a/app/views/new_administrateur/procedures/_procedures_list.html.haml +++ b/app/views/new_administrateur/procedures/_procedures_list.html.haml @@ -33,9 +33,9 @@ %span.icon.edit Modifier .dropdown - .button.dropdown-button.procedures-actions-btn + .button.dropdown-button.procedures-actions-btn{ 'aria-expanded' => 'false', 'aria-controls' => 'actions-menu' } Actions - .dropdown-content.fade-in-down + #actions-menu.dropdown-content.fade-in-down %ul.dropdown-items.pl-0 - if !procedure.close? %li @@ -63,11 +63,3 @@ %span.icon.refuse .dropdown-description %h4 Supprimer - - - if procedure.close? - %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/_publication_form.html.haml b/app/views/new_administrateur/procedures/_publication_form.html.haml new file mode 100644 index 000000000..523bad031 --- /dev/null +++ b/app/views/new_administrateur/procedures/_publication_form.html.haml @@ -0,0 +1,40 @@ +.card.mb-4 + %h2.card-title Publiez votre démarche + = form_tag admin_procedure_publish_path(procedure_id: procedure.id), method: :put, class: 'form' do + %p.mb-4 Publiez votre démarche, et partagez la à vos usagers. Aucune modification ne sera possible. + %p Personnalisez le lien public de la démarche pour en faciliter l’accès (<strong>obligatoire pour publier votre démarche</strong>) : + %p.empty-text + = commencer_url(path: '') + = text_field_tag(:path, procedure.path, + id: 'procedure_path', + label: 'Adresse de diffusion', + placeholder: 'chemin-de-la-démarche', + required: true, + class: 'form', + pattern: '^[a-z0-9_-]{3,50}$', + title: "De 3 à 50 caractères; minuscules, chiffres et tiret seulement", + data: { debounce: true, url: admin_procedure_publish_validate_path(procedure)}, + autocomplete: 'off', + style: 'width: 300px; display: inline;') + .text-info.mb-4 + Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers #{APPLICATION_NAME}. Ne dites pas non plus aux usagers de se rendre sur le site générique #{APPLICATION_NAME}, donnez-leur toujours le lien complet. + %h2.card-title Diffusion de la démarche + %p Où les utilisateurs trouveront-ils le lien de la démarche ? Typiquement, il s’agit d’une page de votre site web. + %p.center + = text_field_tag(:lien_site_web, procedure.lien_site_web, + required: true, + class: 'form-control', + autocomplete: 'off', + placeholder: 'https://exemple.gouv.fr/ma_demarche') + + - procedure.validate(:publication) + - errors = procedure.errors + -# Ignore the :taken error if the path can be claimed + - if errors.details[:path]&.pluck(:error)&.include?(:taken) && @procedure.path_available?(administrateur, procedure.path) + - errors.delete(:path) + + - options = { class: "button primary", id: 'publish' } + - if errors.details[:path].present? + - options[:disabled] = :disabled + .flex.justify-end + = submit_tag procedure_publish_text(@procedure, :submit), options diff --git a/app/views/new_administrateur/procedures/publication.html.haml b/app/views/new_administrateur/procedures/publication.html.haml new file mode 100644 index 000000000..26d4ed03b --- /dev/null +++ b/app/views/new_administrateur/procedures/publication.html.haml @@ -0,0 +1,90 @@ + += render partial: 'new_administrateur/breadcrumbs', + locals: { steps: [link_to('Démarches', admin_procedures_path), + link_to(@procedure.libelle, admin_procedure_path(@procedure)), + 'Publication'] } +.container + .lien-demarche + %h1 + - if @procedure.brouillon? + Test et publication + - else + Publication + %div{ style: 'margin-top: 30px;' } + - if @procedure.close? || @procedure.depubliee? + %p.mb-4 Cette démarche est <strong>close</strong> et n’est donc plus accessible par le public. Vous pouvez la réactiver : + = render partial: 'publication_form', locals: { procedure: @procedure, administrateur: @current_administrateur } + - elsif @procedure.publiee? + %p Cette démarche est <strong>publiée</strong>, certains éléments ne peuvent plus être modifiés. + Pour y accéder vous pouvez utiliser le lien : + = link_to @procedure_lien, sanitize_url(@procedure_lien), target: :blank, rel: :noopener, class: "mb-4" + + %p.mb-4 Attention, diffusez toujours le <strong>lien complet</strong> affiché ci-dessus, et non pas un lien générique vers #{APPLICATION_NAME}. Ne dites pas non plus aux usagers de se rendre sur le site générique #{APPLICATION_NAME}, donnez-leur toujours le lien complet. + + = render partial: 'procedure_transfert' + - elsif @procedure.brouillon? + - if @procedure.missing_steps.empty? + %p + Cette démarche est actuellement <strong>en test</strong>, + pour y accéder vous pouvez utiliser le lien : + = link_to @procedure_lien, sanitize_url(@procedure_lien), target: :blank, rel: :noopener + %p.mb-4 + Toute personne ayant la connaissance de ce lien pourra ainsi remplir des dossiers de test sur votre démarche. + + .card.mb-4 + %h2.card-title Ce que vous pouvez faire lorsque vous êtes en test + %p + Profitez de la phase de test pour tester la saisie de dossiers, ainsi que toutes les fonctionnalités associées (instruction, emails automatiques, attestations, etc.). + %p + Vous pouvez effectuer toutes les modifications que vous souhaitez sur votre démarche pendant cette phase de test. + %p.mb-4.bold + Les dossiers qui seront remplis pendant la phase de test seront automatiquement supprimés lors de la modification ou la publication de votre démarche. + %p.center + %iframe{ :src =>"https://player.vimeo.com/video/334463514?color=0069CC",:width =>"640",:height =>"360",:frameborder => "0" } + + + .card + %h2.card-title Prêt à publier ? + %p + À ce moment du processus de création, vous devez informer votre Délégué à la Protection des Données personnelles (DPD). + %p + ( + %a{ href:'https://www.cnil.fr/fr/protection-des-donnees-les-bons-reflexes', target:'_blank' } + https://www.cnil.fr/fr/protection-des-donnees-les-bons-reflexes + ) + %p + Si votre démarche propose de collecter des données personnelles, vous devez informer votre DPD. Chaque organisme en a un. + %p + Ce dernier pourra vous aider dans la finalisation de votre démarche, et vous inviter à vous interroger sur les données collectées, et sur la pertinence de ces dernières. + N'oubliez pas : toutes les démarches qui contiennent des données personnelles doivent être consignées dans un registre des traitements : + %a{ href:'https://www.cnil.fr/fr/RGDP-le-registre-des-activites-de-traitement', target:'_blank' } + https://www.cnil.fr/fr/RGDP-le-registre-des-activites-de-traitement + %p.mb-4 + Comment faire : + vous pouvez soit lui communiquer par email le lien vers la démarche en test, ou bien le nommer « administrateur ». Dans tous les cas, ne publiez votre démarche qu’après avoir eu son avis. + + = render partial: 'publication_form', locals: { procedure: @procedure, administrateur: @current_administrateur } + + - else + .alert.alert-info + Pour pouvoir tester cette démarche, vous devez d’abord lui affecter + - if @procedure.missing_instructeurs? + = link_to("des instructeurs", admin_procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur)) + - if @procedure.missing_instructeurs? && @procedure.service.nil? + et + - if @procedure.service.nil? + = link_to("un service", admin_services_path(procedure_id: @procedure)) + \. + - else + - if @procedure.missing_steps.include?(:service) + %p.alert.alert-danger + Vous devez renseigner les coordonnées de votre Service administratif avant de pouvoir publier votre démarche. + = link_to 'Cliquez ici.', (@current_administrateur.services.present? ? url_for(admin_services_path(procedure_id: @procedure.id)) : url_for(new_admin_service_path(procedure_id: @procedure.id))) + + - if @procedure.missing_steps.include?(:instructeurs) + %p.alert.alert-danger + Vous devez affecter des instructeurs avant de pouvoir publier votre démarche. + = link_to 'Cliquez ici.', admin_procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur) + + %p.alert.alert-info + Cette démarche n’a pas encore de lien, et n’est pas accessible par le public. diff --git a/app/views/new_administrateur/procedures/show.html.haml b/app/views/new_administrateur/procedures/show.html.haml index ae27c63e7..455adae5f 100644 --- a/app/views/new_administrateur/procedures/show.html.haml +++ b/app/views/new_administrateur/procedures/show.html.haml @@ -1,9 +1,9 @@ = render partial: 'new_administrateur/breadcrumbs', locals: { steps: [link_to('Démarches', admin_procedures_path), - "#{@procedure.libelle} (crée le #{@procedure.created_at.strftime('%d/%m/%Y')})", "#{@procedure.locked? ? "Publiée" : "Brouillon" }"] } + "#{@procedure.libelle} (crée le #{@procedure.created_at.strftime('%d/%m/%Y')})", "#{@procedure.close? ? "Close" : @procedure.locked? ? "Publiée" : "Brouillon"}"] } .container.procedure-admin-container - = link_to apercu_admin_procedure_path(@procedure), class: 'button' do + = link_to apercu_admin_procedure_path(@procedure), class: 'button', id: "preview-procedure" do %span.icon.preview Prévisualiser @@ -17,11 +17,14 @@ %span.icon.reply Envoyer une copie - - if !@procedure.publiee? + - if !@procedure.publiee? && !@procedure.close? && !@procedure.depubliee? = link_to 'Publier', admin_procedure_publication_path(@procedure), class: 'button primary', id: 'publish-procedure-link', data: { disable_with: "Publication..." } + - if @procedure.close? || @procedure.depubliee? + = link_to 'Réactiver', admin_procedure_publication_path(@procedure), class: 'button primary', id: 'publish-procedure-link', data: { disable_with: "Publication..." } + - 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 + = link_to admin_procedure_archive_path(procedure_id: @procedure.id), method: :put, class: 'button', id: "close-procedure-link", 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 Clore diff --git a/app/views/shared/champs/carte/_show.html.haml b/app/views/shared/champs/carte/_show.html.haml index b3f2a50d0..a4fbda3eb 100644 --- a/app/views/shared/champs/carte/_show.html.haml +++ b/app/views/shared/champs/carte/_show.html.haml @@ -1,4 +1,4 @@ - if champ.geometry? - = react_component("MapReader", { featureCollection: champ.to_feature_collection, ign: feature_enabled_for?(:carte_ign, champ.procedure) } ) + = react_component("MapReader", { featureCollection: champ.to_feature_collection, options: champ.render_options } ) .geo-areas = render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: false } diff --git a/app/views/shared/dossiers/editable_champs/_carte.html.haml b/app/views/shared/dossiers/editable_champs/_carte.html.haml index 720ecde88..6865a8dd1 100644 --- a/app/views/shared/dossiers/editable_champs/_carte.html.haml +++ b/app/views/shared/dossiers/editable_champs/_carte.html.haml @@ -1,5 +1,6 @@ - preview = !champ.persisted? -= react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: champs_carte_features_path(preview ? 'preview' : champ), preview: preview, hasCadastres: !!champ.cadastres?, ign: feature_enabled_for?(:carte_ign, champ.procedure) }, class: "carte-#{champ.id}") +- url = champs_carte_features_path(preview ? 'preview' : champ) += react_component("MapEditor", { featureCollection: champ.to_feature_collection, url: url, preview: preview, options: champ.render_options }, class: "carte-#{champ.id}") .geo-areas = render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, editing: true } diff --git a/app/views/shared/help/_help_dropdown_dossier.html.haml b/app/views/shared/help/_help_dropdown_dossier.html.haml index 7155fedca..581ab3ce2 100644 --- a/app/views/shared/help/_help_dropdown_dossier.html.haml +++ b/app/views/shared/help/_help_dropdown_dossier.html.haml @@ -1,6 +1,6 @@ .dropdown.help-dropdown - %button.button.primary.dropdown-button Aide - .dropdown-content.fade-in-down + %button.button.primary.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'help-menu' } Aide + #help-menu.dropdown-content.fade-in-down %ul.dropdown-items - title = dossier.brouillon? ? "Besoin d’aide pour remplir votre dossier ?" : "Une question sur votre dossier ?" diff --git a/app/views/shared/help/_help_dropdown_instructeur.html.haml b/app/views/shared/help/_help_dropdown_instructeur.html.haml index 37581fb91..1da8b5835 100644 --- a/app/views/shared/help/_help_dropdown_instructeur.html.haml +++ b/app/views/shared/help/_help_dropdown_instructeur.html.haml @@ -1,6 +1,6 @@ .dropdown.help-dropdown - %button.button.primary.dropdown-button Aide - .dropdown-content.fade-in-down + %button.button.primary.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'help-menu' } Aide + #help-menu.dropdown-content.fade-in-down %ul.dropdown-items = render partial: 'shared/help/dropdown_items/faq_item' = render partial: 'shared/help/dropdown_items/email_item' diff --git a/app/views/shared/help/_help_dropdown_procedure.html.haml b/app/views/shared/help/_help_dropdown_procedure.html.haml index 333e59bac..18f2ca096 100644 --- a/app/views/shared/help/_help_dropdown_procedure.html.haml +++ b/app/views/shared/help/_help_dropdown_procedure.html.haml @@ -1,6 +1,6 @@ .dropdown.help-dropdown - %button.button.primary.dropdown-button Aide - .dropdown-content.fade-in-down + %button.button.primary.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'help-menu' } Aide + #help-menu.dropdown-content.fade-in-down %ul.dropdown-items - if procedure.service.present? = render partial: 'shared/help/dropdown_items/service_item', diff --git a/app/views/users/dossiers/_dossier_actions.html.haml b/app/views/users/dossiers/_dossier_actions.html.haml index 36d9c290d..1ae1a87f6 100644 --- a/app/views/users/dossiers/_dossier_actions.html.haml +++ b/app/views/users/dossiers/_dossier_actions.html.haml @@ -5,9 +5,9 @@ - if has_actions .dropdown.user-dossier-actions - %button.button.dropdown-button + %button.button.dropdown-button{ 'aria-expanded' => 'false', 'aria-controls' => 'actions-menu' } Actions - .dropdown-content.fade-in-down + #actions-menu.dropdown-content.fade-in-down %ul.dropdown-items - if !dossier.read_only? - if dossier.brouillon? diff --git a/app/views/users/dossiers/show/_header.html.haml b/app/views/users/dossiers/show/_header.html.haml index 5d490f5e1..905f34f42 100644 --- a/app/views/users/dossiers/show/_header.html.haml +++ b/app/views/users/dossiers/show/_header.html.haml @@ -16,9 +16,9 @@ - if dossier.can_be_updated_by_user? && !current_page?(modifier_dossier_path(dossier)) = link_to "Modifier mon 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: 'imprimer', 'aria-label': 'imprimer' } + %button.button.dropdown-button.icon-only{ title: 'imprimer', 'aria-label': 'imprimer', 'aria-expanded' => 'false', 'aria-controls' => 'print-menu' } %span.icon.printer - %ul.print-menu.dropdown-content + %ul#print-menu.print-menu.dropdown-content %li = link_to "Tout le dossier", dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link" diff --git a/config/routes.rb b/config/routes.rb index 043fc16d8..932c7c4c9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -176,7 +176,6 @@ Rails.application.routes.draw do patch 'activate' => '/administrateurs/activate#create' get 'procedures/archived' => 'procedures#archived' get 'procedures/draft' => 'procedures#draft' - get 'procedures/:id/publication' => 'procedures#show', as: :procedure_publication resources :procedures, only: [:destroy] do collection do @@ -191,8 +190,6 @@ Rails.application.routes.draw do put 'archive' => 'procedures#archive', as: :archive get 'publish_validate' => 'procedures#publish_validate', as: :publish_validate - put 'publish' => 'procedures#publish', as: :publish - post 'transfer' => 'procedures#transfer', as: :transfer put 'clone' => 'procedures#clone', as: :clone end @@ -371,6 +368,10 @@ Rails.application.routes.draw do patch 'update_jeton' end + get 'publication' => 'procedures#publication', as: :publication + put 'publish' => 'procedures#publish', as: :publish + post 'transfer' => 'procedures#transfer', as: :transfer + resources :mail_templates, only: [:edit, :update] resources :groupe_instructeurs, only: [:index, :show, :create, :update, :destroy] do diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index 2390b965e..2ebfc636f 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -35,48 +35,12 @@ describe Admin::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 #archived' do - subject { get :archived } - - it { expect(response.status).to eq(200) } - end - - describe 'GET #archived with sorting and pagination' do - subject { - get :archived, params: { - 'procedures_smart_listing[page]': 1, - 'procedures_smart_listing[per_page]': 10, - 'procedures_smart_listing[sort][libelle]': 'asc' - } - } - - it { expect(subject.status).to eq(200) } - end - describe 'GET #published' do subject { get :published } it { expect(response.status).to eq(200) } end - describe 'GET #draft with sorting and pagination' do - subject { - get :draft, params: { - 'procedures_smart_listing[page]': 1, - 'procedures_smart_listing[per_page]': 10, - 'procedures_smart_listing[sort][published_at]': 'asc' - } - } - - it { expect(subject.status).to eq(200) } - end - describe 'DELETE #destroy' do let(:procedure_draft) { create(:procedure, administrateurs: [admin]) } let(:procedure_published) { create(:procedure, :published, administrateurs: [admin]) } @@ -142,118 +106,6 @@ describe Admin::ProceduresController, type: :controller do end end - describe 'PUT #publish' do - let(:procedure) { create(:procedure, administrateur: admin, lien_site_web: lien_site_web) } - let(:procedure2) { create(:procedure, :published, administrateur: admin, lien_site_web: lien_site_web) } - let(:procedure3) { create(:procedure, :published, lien_site_web: lien_site_web) } - let(:lien_site_web) { 'http://some.administration/' } - - context 'when admin is the owner of the procedure' do - before do - put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web }, format: 'js' - procedure.reload - procedure2.reload - end - - context 'procedure path does not exist' do - let(:path) { 'new_path' } - let(:lien_site_web) { 'http://mon-site.gouv.fr' } - - it 'publish the given procedure' do - expect(procedure.publiee?).to be_truthy - expect(procedure.path).to eq(path) - expect(procedure.lien_site_web).to eq(lien_site_web) - end - - it 'redirects to the procedures page' do - expect(response.status).to eq 200 - expect(response.body).to include(admin_procedures_path) - expect(flash[:notice]).to have_content 'Démarche publiée' - end - end - - context 'procedure path exists and is owned by current administrator' do - let(:path) { procedure2.path } - let(:lien_site_web) { 'http://mon-site.gouv.fr' } - - it 'publish the given procedure' do - expect(procedure.publiee?).to be_truthy - expect(procedure.path).to eq(path) - expect(procedure.lien_site_web).to eq(lien_site_web) - end - - it 'depubliee previous procedure' do - expect(procedure2.depubliee?).to be_truthy - end - - it 'redirects to the procedures page' do - expect(response.status).to eq 200 - expect(response.body).to include(admin_procedures_path) - expect(flash[:notice]).to have_content 'Démarche publiée' - end - end - - context 'procedure path exists and is not owned by current administrator' do - let(:path) { procedure3.path } - let(:lien_site_web) { 'http://mon-site.gouv.fr' } - - it 'does not publish the given procedure' do - expect(procedure.publiee?).to be_falsey - expect(procedure.path).not_to match(path) - expect(procedure.lien_site_web).to match(lien_site_web) - end - - it 'previous procedure remains published' do - expect(procedure2.publiee?).to be_truthy - expect(procedure2.close?).to be_falsey - expect(procedure2.path).to match(/fake_path/) - end - end - - context 'procedure path is invalid' do - let(:path) { 'Invalid Procedure Path' } - let(:lien_site_web) { 'http://mon-site.gouv.fr' } - - it 'does not publish the given procedure' do - expect(procedure.publiee?).to be_falsey - expect(procedure.path).not_to match(path) - expect(procedure.lien_site_web).to match(lien_site_web) - end - end - end - - context 'when admin is not the owner of the procedure' do - let(:admin_2) { create(:administrateur) } - - before do - sign_out(admin.user) - sign_in(admin_2.user) - - put :publish, params: { procedure_id: procedure.id, path: 'fake_path' }, format: 'js' - procedure.reload - end - - it 'fails' do - expect(response).to have_http_status(404) - end - end - - context 'when the admin does not provide a lien_site_web' do - before do - put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web }, format: 'js' - procedure.reload - end - context 'procedure path is valid but lien_site_web is missing' do - let(:path) { 'new_path2' } - let(:lien_site_web) { nil } - - it 'does not publish the given procedure' do - expect(procedure.publiee?).to be_falsey - end - end - end - end - describe 'PUT #archive' do let(:procedure) { create(:procedure, :published, administrateur: admin, lien_site_web: lien_site_web) } @@ -268,21 +120,6 @@ describe Admin::ProceduresController, type: :controller do it { expect(response).to redirect_to :admin_procedures } it { expect(flash[:notice]).to have_content 'Démarche close' } end - - context 'when owner want to re-enable procedure' do - before do - put :publish, params: { procedure_id: procedure.id, path: 'fake_path', lien_site_web: lien_site_web } - procedure.reload - end - - it { expect(procedure.publiee?).to be_truthy } - - it 'redirects to the procedures page' do - expect(response.status).to eq 200 - expect(response.body).to include(admin_procedures_path) - expect(flash[:notice]).to have_content 'Démarche publiée' - end - end end context 'when admin is not the owner of the procedure' do @@ -391,53 +228,6 @@ describe Admin::ProceduresController, type: :controller do end end - describe 'POST #transfer' do - let!(:procedure) { create :procedure, :with_service, administrateur: admin } - - subject do - post :transfer, params: { email_admin: email_admin, procedure_id: procedure.id }, format: 'js' - end - - context 'when admin is unknow' do - let(:email_admin) { 'plop' } - - it { expect(subject.status).to eq 404 } - end - - context 'when admin is known' do - let!(:new_admin) { create :administrateur, email: 'new_admin@admin.com' } - - context "and its email address is correct" do - let(:email_admin) { 'new_admin@admin.com' } - - it { expect(subject.status).to eq 200 } - it { expect { subject }.to change(new_admin.procedures, :count).by(1) } - - it "should create a new service" do - subject - expect(new_admin.procedures.last.service_id).not_to eq(procedure.service_id) - end - end - - context 'when admin is know but its email was not downcased' do - let(:email_admin) { "NEW_admin@adMIN.com" } - - it { expect(subject.status).to eq 200 } - it { expect { subject }.to change(Procedure, :count).by(1) } - end - - describe "correctly assigns the new admin" do - let(:email_admin) { 'new_admin@admin.com' } - - before do - subject - end - - it { expect(Procedure.last.administrateurs).to eq [new_admin] } - end - end - end - describe "DELETE #delete_deliberation" do context "with a demarche the admin owns" do let(:procedure) { create(:procedure, :with_deliberation, administrateur: admin) } diff --git a/spec/controllers/new_administrateur/procedures_controller_spec.rb b/spec/controllers/new_administrateur/procedures_controller_spec.rb index 36cc682c4..be3a6845b 100644 --- a/spec/controllers/new_administrateur/procedures_controller_spec.rb +++ b/spec/controllers/new_administrateur/procedures_controller_spec.rb @@ -340,4 +340,152 @@ describe NewAdministrateur::ProceduresController, type: :controller do expect(procedure.reload.api_entreprise_token).to eq(valid_token) end end + + describe 'PUT #publish' do + let(:procedure) { create(:procedure, administrateur: admin, lien_site_web: lien_site_web) } + let(:procedure2) { create(:procedure, :published, administrateur: admin, lien_site_web: lien_site_web) } + let(:procedure3) { create(:procedure, :published, lien_site_web: lien_site_web) } + let(:lien_site_web) { 'http://some.administration/' } + + context 'when admin is the owner of the procedure' do + context 'procedure path does not exist' do + let(:path) { 'new_path' } + let(:lien_site_web) { 'http://mon-site.gouv.fr' } + + before do + put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web } + procedure.reload + end + + it 'publish the given procedure' do + expect(procedure.publiee?).to be_truthy + expect(procedure.path).to eq(path) + expect(procedure.lien_site_web).to eq(lien_site_web) + end + + it 'redirects to the procedure page' do + expect(response.status).to eq 302 + expect(response.body).to include(admin_procedure_path(procedure.id)) + expect(flash[:notice]).to have_content 'Démarche publiée' + end + end + + context 'procedure path exists and is owned by current administrator' do + before do + put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web } + procedure.reload + procedure2.reload + end + + let(:path) { procedure2.path } + let(:lien_site_web) { 'http://mon-site.gouv.fr' } + + it 'publish the given procedure' do + expect(procedure.publiee?).to be_truthy + expect(procedure.path).to eq(path) + expect(procedure.lien_site_web).to eq(lien_site_web) + end + + it 'depubliee previous procedure' do + expect(procedure2.depubliee?).to be_truthy + end + + it 'redirects to the procedures page' do + expect(response.status).to eq 302 + expect(response.body).to include(admin_procedure_path(procedure.id)) + expect(flash[:notice]).to have_content 'Démarche publiée' + end + end + + context 'procedure path exists and is not owned by current administrator' do + let(:path) { procedure3.path } + let(:lien_site_web) { 'http://mon-site.gouv.fr' } + it { expect { put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web } }.to raise_error(ActiveRecord::RecordInvalid) } + end + + context 'procedure path is invalid' do + let(:lien_site_web) { 'http://mon-site.gouv.fr' } + let(:path) { 'Invalid Procedure Path' } + it { expect { put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web } }.to raise_error(ActiveRecord::RecordInvalid) } + end + end + + context 'when admin is not the owner of the procedure' do + let(:admin_2) { create(:administrateur) } + before do + sign_out(admin.user) + sign_in(admin_2.user) + + put :publish, params: { procedure_id: procedure.id, path: 'fake_path' } + procedure.reload + end + + it 'fails' do + expect(response).to have_http_status(404) + end + end + + context 'when the admin does not provide a lien_site_web' do + context 'procedure path is valid but lien_site_web is missing' do + let(:path) { 'new_path2' } + let(:lien_site_web) { nil } + it { expect { put :publish, params: { procedure_id: procedure.id, path: path, lien_site_web: lien_site_web } }.to raise_error(ActiveRecord::RecordInvalid) } + end + end + end + + describe 'POST #transfer' do + let!(:procedure) { create :procedure, :with_service, administrateur: admin } + + before do + post :transfer, params: { email_admin: email_admin, procedure_id: procedure.id } + procedure.reload + end + + subject do + post :transfer, params: { email_admin: email_admin, procedure_id: procedure.id } + end + + context 'when admin is unknow' do + let(:email_admin) { 'plop' } + + it { expect(subject.status).to eq 302 } + it { expect(response.body).to include(admin_procedure_publication_path(procedure.id)) } + it { expect(flash[:alert]).to be_present } + it { expect(flash[:alert]).to eq("Envoi vers #{email_admin} impossible : cet administrateur n'existe pas") } + end + + context 'when admin is known' do + let!(:new_admin) { create :administrateur, email: 'new_admin@admin.com' } + + context "and its email address is correct" do + let(:email_admin) { 'new_admin@admin.com' } + + it { expect(subject.status).to eq 302 } + it { expect { subject }.to change(new_admin.procedures, :count).by(1) } + + it "should create a new service" do + subject + expect(new_admin.procedures.last.service_id).not_to eq(procedure.service_id) + end + end + + context 'when admin is know but its email was not downcased' do + let(:email_admin) { "NEW_admin@adMIN.com" } + + it { expect(subject.status).to eq 302 } + it { expect { subject }.to change(Procedure, :count).by(1) } + end + + describe "correctly assigns the new admin" do + let(:email_admin) { 'new_admin@admin.com' } + + before do + subject + end + + it { expect(Procedure.last.administrateurs).to eq [new_admin] } + end + end + end end diff --git a/spec/features/admin/procedure_cloning_spec.rb b/spec/features/admin/procedure_cloning_spec.rb index 3d490f9c0..9a7019d55 100644 --- a/spec/features/admin/procedure_cloning_spec.rb +++ b/spec/features/admin/procedure_cloning_spec.rb @@ -20,26 +20,21 @@ feature 'As an administrateur I wanna clone a procedure', js: true do 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 + visit admin_procedures_path(statut: "brouillons") expect(page.find_by_id('procedures')['data-item-count']).to eq('1') click_on Procedure.last.libelle expect(page).to have_current_path(admin_procedure_path(Procedure.last)) find('#publish-procedure-link').click - find('#publish-procedure').click - - within '#publish-modal' do - expect(find_field('procedure_path').value).to eq 'libelle-de-la-procedure' - expect(page).to have_text('ancienne sera dépubliée') - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'publish' - end + expect(find_field('procedure_path').value).to eq 'libelle-de-la-procedure' + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'publish' page.refresh - visit admin_procedures_archived_path + visit admin_procedures_path(statut: "archivees") expect(page.find_by_id('procedures')['data-item-count']).to eq('1') - visit admin_procedures_draft_path + visit admin_procedures_path(statut: "brouillons") expect(page.find_by_id('procedures')['data-item-count']).to eq('0') end end diff --git a/spec/features/admin/procedure_creation_spec.rb b/spec/features/admin/procedure_creation_spec.rb index 943aa622d..17993f4de 100644 --- a/spec/features/admin/procedure_creation_spec.rb +++ b/spec/features/admin/procedure_creation_spec.rb @@ -77,13 +77,11 @@ feature 'As an administrateur I wanna create a new procedure', js: true do expect(page).to have_selector('#champ-1-libelle') click_on Procedure.last.libelle - find('#publish-procedure-link').click - preview_window = window_opened_by { click_on 'onglet-preview' } - within_window(preview_window) do - expect(page).to have_current_path(apercu_admin_procedure_path(Procedure.last)) - expect(page).to have_field('libelle de champ') - end + find('#preview-procedure').click + + expect(page).to have_current_path(apercu_admin_procedure_path(Procedure.last)) + expect(page).to have_field('libelle de champ') end scenario 'After adding champ and file, make publication' do @@ -102,17 +100,12 @@ feature 'As an administrateur I wanna create a new procedure', js: true do # (Capybara runs the app on an arbitrary host/port.) expect(page).to have_link(nil, href: /#{commencer_test_path(Procedure.last.path)}/) - expect(page).to have_selector('#publish-procedure', visible: true) - find('#publish-procedure').click - - within '#publish-modal' do - expect(find_field('procedure_path').value).to eq 'libelle-de-la-procedure' - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'publish' - end + expect(page).to have_selector('#procedure_path', visible: true) + expect(find_field('procedure_path').value).to eq 'libelle-de-la-procedure' + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'publish' expect(page).to have_text('Démarche publiée') - expect(page).to have_selector('.procedure-lien') end end end diff --git a/spec/features/admin/procedure_publish_spec.rb b/spec/features/admin/procedure_publish_spec.rb index 0ea7f67fd..957084e13 100644 --- a/spec/features/admin/procedure_publish_spec.rb +++ b/spec/features/admin/procedure_publish_spec.rb @@ -20,21 +20,15 @@ feature 'Publication de démarches', js: true do context 'lorsqu’une démarche est en test' do scenario 'un administrateur peut la publier' do - visit admin_procedures_draft_path + visit admin_procedures_path(statut: "brouillons") click_on procedure.libelle find('#publish-procedure-link').click - within "#procedure_show" do - click_on "Publier" - end - - within '#publish-modal' do - expect(find_field('procedure_path').value).to eq procedure.path - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'publish' - end + expect(find_field('procedure_path').value).to eq procedure.path + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'Publier' expect(page).to have_text('Démarche publiée') - expect(page).to have_selector('.procedure-lien') + expect(page).to have_selector('#preview-procedure') end end @@ -50,21 +44,16 @@ feature 'Publication de démarches', js: true do end scenario 'un administrateur peut la publier' do - visit admin_procedures_archived_path + visit admin_procedures_path(statut: "archivees") click_on procedure.libelle find('#publish-procedure-link').click - within "#procedure_show" do - click_on "Réactiver" - end - within '#publish-modal' do - expect(find_field('procedure_path').value).to eq procedure.path - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'publish' - end + expect(find_field('procedure_path').value).to eq procedure.path + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'publish' expect(page).to have_text('Démarche publiée') - expect(page).to have_selector('.procedure-lien') + expect(page).to have_selector('#preview-procedure') end end @@ -80,21 +69,16 @@ feature 'Publication de démarches', js: true do end scenario 'un administrateur peut la publier' do - visit admin_procedures_archived_path + visit admin_procedures_path(statut: "archivees") click_on procedure.libelle find('#publish-procedure-link').click - within "#procedure_show" do - click_on "Réactiver" - end - within '#publish-modal' do - expect(find_field('procedure_path').value).to eq procedure.path - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'publish' - end + expect(find_field('procedure_path').value).to eq procedure.path + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'Publier' expect(page).to have_text('Démarche publiée') - expect(page).to have_selector('.procedure-lien') + expect(page).to have_selector('#preview-procedure') end end end diff --git a/spec/features/admin/procedure_update_spec.rb b/spec/features/admin/procedure_update_spec.rb index 24adb1f02..0e13b5646 100644 --- a/spec/features/admin/procedure_update_spec.rb +++ b/spec/features/admin/procedure_update_spec.rb @@ -25,7 +25,7 @@ feature 'Administrateurs can edit procedures', js: true do end scenario 'the administrator can edit the libelle' do - visit admin_procedures_draft_path + visit admin_procedures_path(statut: "brouillons") click_on procedure.libelle find('#presentation').click diff --git a/spec/features/routing/full_scenario_spec.rb b/spec/features/routing/full_scenario_spec.rb index b23f74762..dcd4ad238 100644 --- a/spec/features/routing/full_scenario_spec.rb +++ b/spec/features/routing/full_scenario_spec.rb @@ -174,11 +174,8 @@ feature 'The routing', js: true do def publish_procedure(procedure) click_on procedure.libelle find('#publish-procedure-link').click - find('#publish-procedure').click - within '#publish-modal' do - fill_in 'lien_site_web', with: 'http://some.website' - click_on 'Publier' - end + fill_in 'lien_site_web', with: 'http://some.website' + click_on 'Publier' expect(page).to have_text('Démarche publiée') end diff --git a/spec/views/admin/procedures/show.html.haml_spec.rb b/spec/views/admin/procedures/show.html.haml_spec.rb deleted file mode 100644 index 7fdad4628..000000000 --- a/spec/views/admin/procedures/show.html.haml_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -describe 'admin/procedures/show.html.haml', type: :view do - let(:closed_at) { nil } - let(:procedure) { create(:procedure, :with_service, closed_at: closed_at) } - - before do - assign(:procedure, procedure) - assign(:procedure_lien, commencer_url(path: procedure.path)) - end - - describe 'procedure is draft' do - context 'when procedure does not have a instructeur affected' do - before do - render - end - - describe 'publish button is not visible' do - it { expect(rendered).not_to have_css('button#publish-procedure') } - it { expect(rendered).not_to have_css('button#archive-procedure') } - it { expect(rendered).not_to have_css('button#reopen-procedure') } - end - end - - context 'when procedure have a instructeur affected' do - before do - create(:instructeur).assign_to_procedure(procedure) - render - end - - describe 'publish button is visible' do - it { expect(rendered).to have_css('button#publish-procedure') } - it { expect(rendered).not_to have_css('button#archive-procedure') } - it { expect(rendered).not_to have_css('button#reopen-procedure') } - end - - describe 'procedure path is not customized' do - it { expect(rendered).to have_content('Cette démarche est actuellement en test') } - end - end - end - - describe 'procedure is published' do - before do - procedure.publish! - procedure.reload - render - end - - describe 'archive button is visible', js: true do - it { expect(rendered).not_to have_css('button#publish-procedure') } - it { expect(rendered).to have_css('button#archive-procedure') } - it { expect(rendered).not_to have_css('button#reopen-procedure') } - end - - describe 'procedure link is present' do - it { expect(rendered).to have_content(commencer_url(path: procedure.path)) } - end - end - - describe 'procedure is closed' do - before do - procedure.publish! - procedure.close! - procedure.reload - render - end - - describe 'Re-enable button is visible' do - it { expect(rendered).not_to have_css('button#publish-procedure') } - it { expect(rendered).not_to have_css('button#archive-procedure') } - it { expect(rendered).to have_css('button#reopen-procedure') } - end - - describe 'procedure link is present' do - it { expect(rendered).to have_content('Cette démarche est close et n’est donc plus accessible par le public.') } - end - end -end diff --git a/spec/views/new_administrateur/procedures/show.html.haml_spec.rb b/spec/views/new_administrateur/procedures/show.html.haml_spec.rb new file mode 100644 index 000000000..d5477a021 --- /dev/null +++ b/spec/views/new_administrateur/procedures/show.html.haml_spec.rb @@ -0,0 +1,55 @@ +describe 'new_administrateur/procedures/show.html.haml', type: :view do + let(:closed_at) { nil } + let(:procedure) { create(:procedure, :with_service, closed_at: closed_at) } + + before do + assign(:procedure, procedure) + assign(:procedure_lien, commencer_url(path: procedure.path)) + end + + describe 'procedure is draft' do + context 'when procedure have a instructeur affected' do + before do + create(:instructeur).assign_to_procedure(procedure) + render + end + + describe 'publish button is visible' do + it { expect(rendered).to have_css('#publish-procedure-link') } + it { expect(rendered).not_to have_css('#close-procedure-link') } + end + + describe 'procedure path is not customized' do + it { expect(rendered).to have_content('Brouillon') } + end + end + end + + describe 'procedure is published' do + before do + procedure.publish! + procedure.reload + render + end + + describe 'archive button is visible', js: true do + it { expect(rendered).not_to have_css('#publish-procedure-link') } + it { expect(rendered).to have_css('#close-procedure-link') } + end + end + + describe 'procedure is closed' do + before do + procedure.publish! + procedure.close! + procedure.reload + render + end + + describe 'Re-enable button is visible' do + it { expect(rendered).not_to have_css('#close-procedure-link') } + it { expect(rendered).to have_css('#publish-procedure-link') } + it { expect(rendered).to have_content('Réactiver') } + end + end +end