Merge pull request #5142 from betagouv/dev

This commit is contained in:
Pierre de La Morinerie 2020-05-13 11:16:24 +02:00 committed by GitHub
commit b28866dbc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 848 additions and 814 deletions

View file

@ -1,3 +1,4 @@
module.exports = { module.exports = {
singleQuote: true singleQuote: true,
trailingComma: 'none'
}; };

View file

@ -71,7 +71,6 @@ gem 'skylight'
gem 'smart_listing' gem 'smart_listing'
gem 'spreadsheet_architect' gem 'spreadsheet_architect'
gem 'sprockets', '< 4' gem 'sprockets', '< 4'
gem 'turbolinks' # Turbolinks makes following links in your web application faster
gem 'typhoeus' gem 'typhoeus'
gem 'warden' gem 'warden'
gem 'webpacker' gem 'webpacker'

View file

@ -361,7 +361,7 @@ GEM
railties (>= 4) railties (>= 4)
request_store (~> 1.0) request_store (~> 1.0)
logstash-event (1.2.02) logstash-event (1.2.02)
loofah (2.4.0) loofah (2.5.0)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
lumberjack (1.0.13) lumberjack (1.0.13)
@ -613,6 +613,7 @@ GEM
selenium-webdriver (3.141.0) selenium-webdriver (3.141.0)
childprocess (~> 0.5) childprocess (~> 0.5)
rubyzip (~> 1.2, >= 1.2.2) rubyzip (~> 1.2, >= 1.2.2)
semantic_range (2.3.0)
sentry-raven (2.7.4) sentry-raven (2.7.4)
faraday (>= 0.7.6, < 1.0) faraday (>= 0.7.6, < 1.0)
sexp_processor (4.14.1) sexp_processor (4.14.1)
@ -662,12 +663,9 @@ GEM
tilt (2.0.10) tilt (2.0.10)
timecop (0.9.1) timecop (0.9.1)
ttfunk (1.5.1) ttfunk (1.5.1)
turbolinks (5.2.0)
turbolinks-source (~> 5.2)
turbolinks-source (5.2.0)
typhoeus (1.3.1) typhoeus (1.3.1)
ethon (>= 0.9.0) ethon (>= 0.9.0)
tzinfo (1.2.6) tzinfo (1.2.7)
thread_safe (~> 0.1) thread_safe (~> 0.1)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
@ -698,10 +696,11 @@ GEM
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff
webpacker (4.0.2) webpacker (5.1.1)
activesupport (>= 4.2) activesupport (>= 5.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 5.2)
semantic_range (>= 2.3.0)
websocket-driver (0.7.1) websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4) websocket-extensions (0.1.4)
@ -821,7 +820,6 @@ DEPENDENCIES
spring-commands-rspec spring-commands-rspec
sprockets (< 4) sprockets (< 4)
timecop timecop
turbolinks
typhoeus typhoeus
vcr vcr
warden warden

View file

@ -16,18 +16,3 @@
//= require smart_listing //= require smart_listing
//= require bootstrap-wysihtml5 //= require bootstrap-wysihtml5
//= require bootstrap-wysihtml5/locales/fr-FR //= require bootstrap-wysihtml5/locales/fr-FR
/* globals $ */
$(document).on('turbolinks:load', application_init);
function application_init() {
tooltip_init();
}
function tooltip_init() {
$('.action_button[data-toggle="tooltip"]').tooltip({
delay: { show: 100, hide: 100 }
});
$('[data-toggle="tooltip"]').tooltip({ delay: { show: 800, hide: 100 } });
}

View file

@ -2,19 +2,10 @@
$(document).on('click', '.delete', function () { $(document).on('click', '.delete', function () {
$(this).hide(); $(this).hide();
$(this) $(this).closest('td').find('.confirm').show();
.closest('td')
.find('.confirm')
.show();
}); });
$(document).on('click', '.cancel', function () { $(document).on('click', '.cancel', function () {
$(this) $(this).closest('td').find('.delete').show();
.closest('td') $(this).closest('td').find('.confirm').hide();
.find('.delete')
.show();
$(this)
.closest('td')
.find('.confirm')
.hide();
}); });

View file

@ -1,6 +1,6 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', wysihtml5_active); $(document).on('DOMContentLoaded', wysihtml5_active);
function wysihtml5_active() { function wysihtml5_active() {
$('.wysihtml5').each(function (i, elem) { $('.wysihtml5').each(function (i, elem) {

View file

@ -1,6 +1,6 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', init_default_data_block); $(document).on('DOMContentLoaded', init_default_data_block);
function init_default_data_block() { function init_default_data_block() {
$('.default-data-block #dossier .body').toggle(); $('.default-data-block #dossier .body').toggle();

View file

@ -1,16 +1,12 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', filters_init); $(document).on('DOMContentLoaded', filters_init);
function filters_init() { function filters_init() {
$('html').click(function (event) { $('html').click(function (event) {
var visible_filter = $('.filter_framed:visible'); var visible_filter = $('.filter_framed:visible');
if (visible_filter.length) { if (visible_filter.length) {
if ( if (!$(event.target).closest('.filter_framed').is(':visible')) {
!$(event.target)
.closest('.filter_framed')
.is(':visible')
) {
visible_filter.hide(); visible_filter.hide();
} }
} }
@ -23,10 +19,7 @@ function filters_init() {
}); });
$('.erase-filter').on('click', function () { $('.erase-filter').on('click', function () {
$(this) $(this).parent().find('.filter_input').val('');
.parent()
.find('.filter_input')
.val('');
}); });
} }

View file

@ -1,6 +1,6 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', action_type_de_champs); $(document).on('DOMContentLoaded', action_type_de_champs);
function action_type_de_champs() { function action_type_de_champs() {
$("input[type='email']").on('change', function () { $("input[type='email']").on('change', function () {

View file

@ -1,6 +1,6 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', modal_action); $(document).on('DOMContentLoaded', modal_action);
function modal_action() { function modal_action() {
$('#pj-modal').on('show.bs.modal', function (event) { $('#pj-modal').on('show.bs.modal', function (event) {

View file

@ -1,6 +1,6 @@
/* globals $ */ /* globals $ */
$(document).on('turbolinks:load', button_edit_procedure_init); $(document).on('DOMContentLoaded', button_edit_procedure_init);
function button_edit_procedure_init() { function button_edit_procedure_init() {
buttons_api_carto(); buttons_api_carto();

View file

@ -1,5 +0,0 @@
@import "constants";
.turbolinks-progress-bar {
background-color: $light-blue;
}

View file

@ -11,7 +11,6 @@
// //
// = require _card // = require _card
// = require _helpers // = require _helpers
// = require _turbolinks
// = require admin_type_de_champ // = require admin_type_de_champ
// = require carte // = require carte
// = require custom_mails // = require custom_mails

View file

@ -72,7 +72,7 @@ class Admin::ProceduresController < AdminController
@procedure.publish_or_reopen!(current_administrateur) @procedure.publish_or_reopen!(current_administrateur)
flash.notice = "Démarche publiée" flash.notice = "Démarche publiée"
redirect_to admin_procedures_path render js: "window.location='#{admin_procedures_path}'"
rescue ActiveRecord::RecordInvalid rescue ActiveRecord::RecordInvalid
render 'publish_validate', formats: :js render 'publish_validate', formats: :js
end end

View file

@ -11,12 +11,12 @@ import '@reach/combobox/styles.css';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
let cache = {}; let cache = {};
const useAddressSearch = searchTerm => { const useAddressSearch = (searchTerm) => {
const [addresses, setAddresses] = useState([]); const [addresses, setAddresses] = useState([]);
useEffect(() => { useEffect(() => {
if (searchTerm.trim() !== '') { if (searchTerm.trim() !== '') {
let isFresh = true; let isFresh = true;
fetchAddresses(searchTerm).then(addresses => { fetchAddresses(searchTerm).then((addresses) => {
if (isFresh) setAddresses(addresses); if (isFresh) setAddresses(addresses);
}); });
return () => (isFresh = false); return () => (isFresh = false);
@ -25,12 +25,12 @@ const useAddressSearch = searchTerm => {
return addresses; return addresses;
}; };
const fetchAddresses = value => { const fetchAddresses = (value) => {
if (cache[value]) { if (cache[value]) {
return Promise.resolve(cache[value]); return Promise.resolve(cache[value]);
} }
const url = `https://api-adresse.data.gouv.fr/search/`; const url = `https://api-adresse.data.gouv.fr/search/`;
return getJSON(url, { q: value, limit: 5 }, 'get').then(result => { return getJSON(url, { q: value, limit: 5 }, 'get').then((result) => {
if (result) { if (result) {
cache[value] = result; cache[value] = result;
} }
@ -41,7 +41,7 @@ const fetchAddresses = value => {
const SearchInput = ({ getCoords }) => { const SearchInput = ({ getCoords }) => {
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState('');
const addresses = useAddressSearch(searchTerm); const addresses = useAddressSearch(searchTerm);
const handleSearchTermChange = event => { const handleSearchTermChange = (event) => {
setSearchTerm(event.target.value); setSearchTerm(event.target.value);
}; };
return ( return (
@ -72,7 +72,7 @@ const SearchInput = ({ getCoords }) => {
> >
{addresses.features.length > 0 ? ( {addresses.features.length > 0 ? (
<ComboboxList> <ComboboxList>
{addresses.features.map(feature => { {addresses.features.map((feature) => {
const str = `${feature.properties.name}, ${feature.properties.city}`; const str = `${feature.properties.name}, ${feature.properties.city}`;
return ( return (
<ComboboxOption <ComboboxOption

View file

@ -9,7 +9,8 @@ const SwitchMapStyle = ({ isVector }) => {
const imgStyle = { const imgStyle = {
width: '100%', width: '100%',
height: '100%' height: '100%',
cursor: 'pointer'
}; };
const textStyle = { const textStyle = {
@ -24,11 +25,6 @@ const SwitchMapStyle = ({ isVector }) => {
<div className="text" style={textStyle}> <div className="text" style={textStyle}>
{style} {style}
</div> </div>
<style jsx>{`
img:hover {
cursor: pointer;
}
`}</style>
</div> </div>
); );
}; };

View file

@ -18,7 +18,7 @@ function filterFeatureCollection(featureCollection, source) {
return { return {
type: 'FeatureCollection', type: 'FeatureCollection',
features: featureCollection.features.filter( features: featureCollection.features.filter(
feature => feature.properties.source === source (feature) => feature.properties.source === source
) )
}; };
} }
@ -75,7 +75,7 @@ const MapEditor = ({ featureCollection, url }) => {
updateFeaturesList(features); updateFeaturesList(features);
} }
const onMapLoad = map => { const onMapLoad = (map) => {
setCurrentMap(map); setCurrentMap(map);
drawControl.current.draw.set( drawControl.current.draw.set(
@ -83,7 +83,7 @@ const MapEditor = ({ featureCollection, url }) => {
); );
}; };
const onCadastresUpdate = evt => { const onCadastresUpdate = (evt) => {
if (currentMap) { if (currentMap) {
currentMap currentMap
.getSource('cadastres-layer') .getSource('cadastres-layer')
@ -93,10 +93,10 @@ const MapEditor = ({ featureCollection, url }) => {
} }
}; };
const onGpxImport = e => { const onGpxImport = (e) => {
let reader = new FileReader(); let reader = new FileReader();
reader.readAsText(e.target.files[0], 'UTF-8'); reader.readAsText(e.target.files[0], 'UTF-8');
reader.onload = async event => { reader.onload = async (event) => {
const featureCollection = gpx( const featureCollection = gpx(
new DOMParser().parseFromString(event.target.result, 'text/xml') new DOMParser().parseFromString(event.target.result, 'text/xml')
); );
@ -149,14 +149,14 @@ const MapEditor = ({ featureCollection, url }) => {
}} }}
> >
<SearchInput <SearchInput
getCoords={searchTerm => { getCoords={(searchTerm) => {
setCoords(searchTerm); setCoords(searchTerm);
setZoom([17]); setZoom([17]);
}} }}
/> />
</div> </div>
<Map <Map
onStyleLoad={map => onMapLoad(map)} onStyleLoad={(map) => onMapLoad(map)}
fitBounds={bbox} fitBounds={bbox}
fitBoundsOptions={{ padding: 100 }} fitBoundsOptions={{ padding: 100 }}
center={coords} center={coords}

View file

@ -12,25 +12,25 @@ const MapReader = ({ featureCollection }) => {
[b1, b2] [b1, b2]
]; ];
const selectionsFeatureCollection = {
type: 'FeatureCollection',
features: []
};
const cadastresFeatureCollection = { const cadastresFeatureCollection = {
type: 'FeatureCollection', type: 'FeatureCollection',
features: [] features: []
}; };
for (let feature of featureCollection.features) { const selectionsLineFeatureCollection = {
switch (feature.properties.source) { type: 'FeatureCollection',
case 'selection_utilisateur': features: []
selectionsFeatureCollection.features.push(feature); };
break;
case 'cadastre': const selectionsPolygonFeatureCollection = {
cadastresFeatureCollection.features.push(feature); type: 'FeatureCollection',
break; features: []
} };
}
const selectionsPointFeatureCollection = {
type: 'FeatureCollection',
features: []
};
const polygonSelectionFill = { const polygonSelectionFill = {
'fill-color': '#EC3323', 'fill-color': '#EC3323',
@ -42,6 +42,15 @@ const MapReader = ({ featureCollection }) => {
'line-width': 4 'line-width': 4
}; };
const lineStringSelectionLine = {
'line-color': 'rgba(55, 42, 127, 1.00)',
'line-width': 3
};
const pointSelectionFill = {
'circle-color': '#EC3323'
};
const polygonCadastresFill = { const polygonCadastresFill = {
'fill-color': '#9CA090', 'fill-color': '#9CA090',
'fill-opacity': 0.5 'fill-opacity': 0.5
@ -53,6 +62,27 @@ const MapReader = ({ featureCollection }) => {
'line-dasharray': [1, 1] 'line-dasharray': [1, 1]
}; };
for (let feature of featureCollection.features) {
switch (feature.properties.source) {
case 'selection_utilisateur':
switch (feature.geometry.type) {
case 'LineString':
selectionsLineFeatureCollection.features.push(feature);
break;
case 'Polygon':
selectionsPolygonFeatureCollection.features.push(feature);
break;
case 'Point':
selectionsPointFeatureCollection.features.push(feature);
break;
}
break;
case 'cadastre':
cadastresFeatureCollection.features.push(feature);
break;
}
}
if (!mapboxgl.supported()) { if (!mapboxgl.supported()) {
return ( return (
<p> <p>
@ -74,10 +104,18 @@ const MapReader = ({ featureCollection }) => {
}} }}
> >
<GeoJSONLayer <GeoJSONLayer
data={selectionsFeatureCollection} data={selectionsPolygonFeatureCollection}
fillPaint={polygonSelectionFill} fillPaint={polygonSelectionFill}
linePaint={polygonSelectionLine} linePaint={polygonSelectionLine}
/> />
<GeoJSONLayer
data={selectionsLineFeatureCollection}
linePaint={lineStringSelectionLine}
/>
<GeoJSONLayer
data={selectionsPointFeatureCollection}
circlePaint={pointSelectionFill}
/>
<GeoJSONLayer <GeoJSONLayer
data={cadastresFeatureCollection} data={cadastresFeatureCollection}
fillPaint={polygonCadastresFill} fillPaint={polygonCadastresFill}

View file

@ -72,7 +72,7 @@ function onFileChange(handler, directUploadUrl) {
function uploadFile(input, file, directUploadUrl) { function uploadFile(input, file, directUploadUrl) {
const controller = new Uploader(input, file, directUploadUrl); const controller = new Uploader(input, file, directUploadUrl);
return controller.start().then(signedId => { return controller.start().then((signedId) => {
input.value = null; input.value = null;
return signedId; return signedId;
}); });

View file

@ -17,7 +17,9 @@ function TypeDeChampRepetitionOptions({
return ( return (
<div className="repetition flex-grow cell"> <div className="repetition flex-grow cell">
<SortableContainer <SortableContainer
onSortEnd={params => dispatch({ type: 'onSortTypeDeChamps', params })} onSortEnd={(params) =>
dispatch({ type: 'onSortTypeDeChamps', params })
}
useDragHandle useDragHandle
> >
{state.typeDeChamps.map((typeDeChamp, index) => ( {state.typeDeChamps.map((typeDeChamp, index) => (

View file

@ -12,12 +12,14 @@ function TypeDeChamps({ state: rootState, typeDeChamps }) {
typeDeChamps typeDeChamps
}); });
const hasUnsavedChamps = state.typeDeChamps.some(tdc => tdc.id == undefined); const hasUnsavedChamps = state.typeDeChamps.some(
(tdc) => tdc.id == undefined
);
return ( return (
<div className="champs-editor"> <div className="champs-editor">
<SortableContainer <SortableContainer
onSortEnd={params => dispatch({ type: 'onSortTypeDeChamps', params })} onSortEnd={(params) => dispatch({ type: 'onSortTypeDeChamps', params })}
lockAxis="y" lockAxis="y"
useDragHandle useDragHandle
> >

View file

@ -5,7 +5,7 @@ export function createTypeDeChampOperation(typeDeChamp, queue) {
method: 'post', method: 'post',
payload: { type_de_champ: typeDeChamp } payload: { type_de_champ: typeDeChamp }
}) })
.then(data => { .then((data) => {
handleResponseData(typeDeChamp, data); handleResponseData(typeDeChamp, data);
}); });
} }
@ -33,7 +33,7 @@ export function updateTypeDeChampOperation(typeDeChamp, queue) {
method: 'patch', method: 'patch',
payload: { type_de_champ: typeDeChamp } payload: { type_de_champ: typeDeChamp }
}) })
.then(data => { .then((data) => {
handleResponseData(typeDeChamp, data); handleResponseData(typeDeChamp, data);
}); });
} }

View file

@ -59,7 +59,7 @@ function addTypeDeChamp(state, typeDeChamps, insertAfter, done) {
}); });
} }
}) })
.catch(message => state.flash.error(message)); .catch((message) => state.flash.error(message));
let newTypeDeChamps = [...typeDeChamps, typeDeChamp]; let newTypeDeChamps = [...typeDeChamps, typeDeChamp];
if (insertAfter) { if (insertAfter) {
@ -127,7 +127,7 @@ function updateTypeDeChamp(
function removeTypeDeChamp(state, typeDeChamps, { typeDeChamp }) { function removeTypeDeChamp(state, typeDeChamps, { typeDeChamp }) {
destroyTypeDeChampOperation(typeDeChamp, state.queue) destroyTypeDeChampOperation(typeDeChamp, state.queue)
.then(() => state.flash.success()) .then(() => state.flash.success())
.catch(message => state.flash.error(message)); .catch((message) => state.flash.error(message));
return { return {
...state, ...state,
@ -141,7 +141,7 @@ function moveTypeDeChampUp(state, typeDeChamps, { typeDeChamp }) {
moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue) moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue)
.then(() => state.flash.success()) .then(() => state.flash.success())
.catch(message => state.flash.error(message)); .catch((message) => state.flash.error(message));
return { return {
...state, ...state,
@ -155,7 +155,7 @@ function moveTypeDeChampDown(state, typeDeChamps, { typeDeChamp }) {
moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue) moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue)
.then(() => state.flash.success()) .then(() => state.flash.success())
.catch(message => state.flash.error(message)); .catch((message) => state.flash.error(message));
return { return {
...state, ...state,
@ -166,7 +166,7 @@ function moveTypeDeChampDown(state, typeDeChamps, { typeDeChamp }) {
function onSortTypeDeChamps(state, typeDeChamps, { oldIndex, newIndex }) { function onSortTypeDeChamps(state, typeDeChamps, { oldIndex, newIndex }) {
moveTypeDeChampOperation(typeDeChamps[oldIndex], newIndex, state.queue) moveTypeDeChampOperation(typeDeChamps[oldIndex], newIndex, state.queue)
.then(() => state.flash.success()) .then(() => state.flash.success())
.catch(message => state.flash.error(message)); .catch((message) => state.flash.error(message));
return { return {
...state, ...state,
@ -191,13 +191,13 @@ function getUpdateHandler(typeDeChamp, { queue, flash }) {
let handler = updateHandlers.get(typeDeChamp); let handler = updateHandlers.get(typeDeChamp);
if (!handler) { if (!handler) {
handler = debounce( handler = debounce(
done => (done) =>
updateTypeDeChampOperation(typeDeChamp, queue) updateTypeDeChampOperation(typeDeChamp, queue)
.then(() => { .then(() => {
flash.success(); flash.success();
done(); done();
}) })
.catch(message => flash.error(message)), .catch((message) => flash.error(message)),
200 200
); );
updateHandlers.set(typeDeChamp, handler); updateHandlers.set(typeDeChamp, handler);

View file

@ -1,3 +1,3 @@
import Loadable from '../components/Loadable'; import Loadable from '../components/Loadable';
export default Loadable(() => import('../components/MapEditor/MapEditor')); export default Loadable(() => import('../components/MapEditor'));

View file

@ -25,7 +25,7 @@ async function loadAndRedrawMap(element, data) {
redrawMap(element, data); redrawMap(element, data);
} }
addEventListener('turbolinks:load', initialize); addEventListener('DOMContentLoaded', initialize);
addEventListener('carte:update', ({ detail: { selector, data } }) => { addEventListener('carte:update', ({ detail: { selector, data } }) => {
const element = document.querySelector(selector); const element = document.querySelector(selector);

View file

@ -4,7 +4,7 @@ const PRIMARY_SELECTOR = 'select[data-secondary-options]';
const SECONDARY_SELECTOR = 'select[data-secondary]'; const SECONDARY_SELECTOR = 'select[data-secondary]';
const CHAMP_SELECTOR = '.editable-champ'; const CHAMP_SELECTOR = '.editable-champ';
delegate('change', PRIMARY_SELECTOR, evt => { delegate('change', PRIMARY_SELECTOR, (evt) => {
const primary = evt.target; const primary = evt.target;
const secondary = primary const secondary = primary
.closest(CHAMP_SELECTOR) .closest(CHAMP_SELECTOR)

View file

@ -4,7 +4,7 @@ const BUTTON_SELECTOR = '.button.remove-row';
const DESTROY_INPUT_SELECTOR = 'input[type=hidden][name*=_destroy]'; const DESTROY_INPUT_SELECTOR = 'input[type=hidden][name*=_destroy]';
const CHAMP_SELECTOR = '.editable-champ'; const CHAMP_SELECTOR = '.editable-champ';
delegate('click', BUTTON_SELECTOR, evt => { delegate('click', BUTTON_SELECTOR, (evt) => {
evt.preventDefault(); evt.preventDefault();
const row = evt.target.closest('.row'); const row = evt.target.closest('.row');

View file

@ -41,7 +41,7 @@ export default class AutoSaveController {
headers: { Accept: 'application/json' } headers: { Accept: 'application/json' }
}; };
return window.fetch(form.action, fetchOptions).then(response => { return window.fetch(form.action, fetchOptions).then((response) => {
if (response.ok) { if (response.ok) {
resolve(response); resolve(response);
} else { } else {
@ -64,7 +64,7 @@ export default class AutoSaveController {
const fileInputs = form.querySelectorAll( const fileInputs = form.querySelectorAll(
'input[type="file"]:not([disabled]), .editable-champ-piece_justificative input:not([disabled])' 'input[type="file"]:not([disabled]), .editable-champ-piece_justificative input:not([disabled])'
); );
fileInputs.forEach(fileInput => (fileInput.disabled = true)); fileInputs.forEach((fileInput) => (fileInput.disabled = true));
// Generate the form data // Generate the form data
let formData = null; let formData = null;
@ -75,7 +75,7 @@ export default class AutoSaveController {
return [null, error]; return [null, error];
} finally { } finally {
// Re-enable disabled file inputs // Re-enable disabled file inputs
fileInputs.forEach(fileInput => (fileInput.disabled = false)); fileInputs.forEach((fileInput) => (fileInput.disabled = false));
} }
} }

View file

@ -47,7 +47,7 @@ addEventListener('autosave:end', () => {
hideSucceededStatusAfterDelay(); hideSucceededStatusAfterDelay();
}); });
addEventListener('autosave:error', event => { addEventListener('autosave:error', (event) => {
enable(document.querySelector('button.autosave-retry')); enable(document.querySelector('button.autosave-retry'));
setState('failed'); setState('failed');
logError(event.detail); logError(event.detail);

View file

@ -5,13 +5,13 @@ import { delegate } from '@utils';
const autoUploadsControllers = new AutoUploadsControllers(); const autoUploadsControllers = new AutoUploadsControllers();
function startUpload(input) { function startUpload(input) {
Array.from(input.files).forEach(file => { Array.from(input.files).forEach((file) => {
autoUploadsControllers.upload(input, file); autoUploadsControllers.upload(input, file);
}); });
} }
const fileInputSelector = `input[type=file][data-direct-upload-url][data-auto-attach-url]:not([disabled])`; const fileInputSelector = `input[type=file][data-direct-upload-url][data-auto-attach-url]:not([disabled])`;
delegate('change', fileInputSelector, event => { delegate('change', fileInputSelector, (event) => {
startUpload(event.target); startUpload(event.target);
}); });

View file

@ -40,7 +40,7 @@ export default class AutoUploadsControllers {
if (form) { if (form) {
form form
.querySelectorAll('button[type=submit]') .querySelectorAll('button[type=submit]')
.forEach(submitButton => Rails.disableElement(submitButton)); .forEach((submitButton) => Rails.disableElement(submitButton));
} }
// //
@ -51,7 +51,7 @@ export default class AutoUploadsControllers {
// When DirectUploads attempts to add an event listener for "error", // When DirectUploads attempts to add an event listener for "error",
// also insert a custom event listener of our that will report errors to Sentry. // also insert a custom event listener of our that will report errors to Sentry.
if (arguments[0] == 'error') { if (arguments[0] == 'error') {
let handler = event => { let handler = (event) => {
let message = `FileReader ${event.target.error.name}: ${event.target.error.message}`; let message = `FileReader ${event.target.error.name}: ${event.target.error.message}`;
fire(document, 'sentry:capture-exception', new Error(message)); fire(document, 'sentry:capture-exception', new Error(message));
}; };
@ -71,7 +71,7 @@ export default class AutoUploadsControllers {
if (this.inFlightUploadsCount == 0 && form) { if (this.inFlightUploadsCount == 0 && form) {
form form
.querySelectorAll('button[type=submit]') .querySelectorAll('button[type=submit]')
.forEach(submitButton => Rails.enableElement(submitButton)); .forEach((submitButton) => Rails.enableElement(submitButton));
} }
// //

View file

@ -1,14 +1,14 @@
import { delegate } from '@utils'; import { delegate } from '@utils';
delegate('click', 'body', event => { delegate('click', 'body', (event) => {
if (!event.target.closest('.dropdown')) { if (!event.target.closest('.dropdown')) {
[...document.querySelectorAll('.dropdown')].forEach(element => [...document.querySelectorAll('.dropdown')].forEach((element) =>
element.classList.remove('open', 'fade-in-down') element.classList.remove('open', 'fade-in-down')
); );
} }
}); });
delegate('click', '.dropdown-button', event => { delegate('click', '.dropdown-button', (event) => {
event.stopPropagation(); event.stopPropagation();
const parent = event.target.closest('.dropdown-button').parentElement; const parent = event.target.closest('.dropdown-button').parentElement;
if (parent.classList.contains('dropdown')) { if (parent.classList.contains('dropdown')) {

View file

@ -1,5 +1,4 @@
import '../shared/polyfills'; import '../shared/polyfills';
import Turbolinks from 'turbolinks';
import Rails from '@rails/ujs'; import Rails from '@rails/ujs';
import * as ActiveStorage from '@rails/activestorage'; import * as ActiveStorage from '@rails/activestorage';
import jQuery from 'jquery'; import jQuery from 'jquery';
@ -13,7 +12,6 @@ import '../shared/franceconnect';
// Start Rails helpers // Start Rails helpers
Rails.start(); Rails.start();
Turbolinks.start();
ActiveStorage.start(); ActiveStorage.start();
// Disable jQuery-driven animations during tests // Disable jQuery-driven animations during tests

View file

@ -1,5 +1,4 @@
import '../shared/polyfills'; import '../shared/polyfills';
import Turbolinks from 'turbolinks';
import Rails from '@rails/ujs'; import Rails from '@rails/ujs';
import * as ActiveStorage from '@rails/activestorage'; import * as ActiveStorage from '@rails/activestorage';
import '@rails/actiontext'; import '@rails/actiontext';
@ -57,13 +56,10 @@ const DS = {
// Start Rails helpers // Start Rails helpers
Rails.start(); Rails.start();
Turbolinks.start();
ActiveStorage.start(); ActiveStorage.start();
// Expose globals // Expose globals
window.DS = window.DS || DS; window.DS = window.DS || DS;
// (Both Rails redirects and ReactRailsUJS expect Turbolinks to be globally available)
window.Turbolinks = Turbolinks;
// Now that Turbolinks is globally exposed,configure ReactRailsUJS // Now that Turbolinks is globally exposed,configure ReactRailsUJS
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef

View file

@ -12,7 +12,7 @@ const ERROR_EVENT = 'direct-upload:error';
const END_EVENT = 'direct-upload:end'; const END_EVENT = 'direct-upload:end';
function addUploadEventListener(type, handler) { function addUploadEventListener(type, handler) {
addEventListener(type, event => { addEventListener(type, (event) => {
// Internet Explorer and Edge will sometime replay Javascript events // Internet Explorer and Edge will sometime replay Javascript events
// that were dispatched just before a page navigation (!), but without // that were dispatched just before a page navigation (!), but without
// the event payload. // the event payload.
@ -43,7 +43,7 @@ addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
ProgressBar.progress(id, progress); ProgressBar.progress(id, progress);
}); });
addUploadEventListener(ERROR_EVENT, event => { addUploadEventListener(ERROR_EVENT, (event) => {
let id = event.detail.id; let id = event.detail.id;
let errorMsg = event.detail.error; let errorMsg = event.detail.error;

View file

@ -92,7 +92,7 @@ export default class Uploader {
} }
directUploadWillStoreFileWithXHR(xhr) { directUploadWillStoreFileWithXHR(xhr) {
xhr.upload.addEventListener('progress', event => xhr.upload.addEventListener('progress', (event) =>
this.uploadRequestDidProgress(event) this.uploadRequestDidProgress(event)
); );
} }

View file

@ -63,8 +63,8 @@ function initMap(element, { position }) {
} }
function toLatLngs({ coordinates }) { function toLatLngs({ coordinates }) {
return coordinates.map(polygon => return coordinates.map((polygon) =>
polygon[0].map(point => L.GeoJSON.coordsToLatLng(point)) polygon[0].map((point) => L.GeoJSON.coordsToLatLng(point))
); );
} }
@ -137,7 +137,7 @@ function findInput(selector) {
} }
function clearLayers(map) { function clearLayers(map) {
map.eachLayer(layer => { map.eachLayer((layer) => {
if (layer instanceof L.GeoJSON) { if (layer instanceof L.GeoJSON) {
map.removeLayer(layer); map.removeLayer(layer);
} }
@ -185,7 +185,7 @@ const RPG_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, {
fillColor: '#31708f' fillColor: '#31708f'
}); });
delegate('click', '.carte.edit', event => { delegate('click', '.carte.edit', (event) => {
const map = getCurrentMap(event.target); const map = getCurrentMap(event.target);
if (map) { if (map) {
@ -200,7 +200,7 @@ delegate('click', '.carte.edit', event => {
} }
}); });
delegate('click', '.toolbar .new-area', event => { delegate('click', '.toolbar .new-area', (event) => {
event.preventDefault(); event.preventDefault();
const map = getCurrentMap(event.target); const map = getCurrentMap(event.target);
@ -209,7 +209,7 @@ delegate('click', '.toolbar .new-area', event => {
} }
}); });
$(document).on('select2:select', 'select[data-address]', event => { $(document).on('select2:select', 'select[data-address]', (event) => {
const map = getCurrentMap(event.target); const map = getCurrentMap(event.target);
const { geometry } = event.params.data; const { geometry } = event.params.data;

View file

@ -1,6 +1,6 @@
import { fire } from '@utils'; import { fire } from '@utils';
addEventListener('turbolinks:load', function() { addEventListener('DOMContentLoaded', function () {
fire(document, 'ds:page:update'); fire(document, 'ds:page:update');
}); });

View file

@ -1,6 +1,6 @@
import { ajax, delegate } from '@utils'; import { ajax, delegate } from '@utils';
addEventListener('turbolinks:load', () => { addEventListener('DOMContentLoaded', () => {
attachementPoller.deactivate(); attachementPoller.deactivate();
exportPoller.deactivate(); exportPoller.deactivate();
@ -24,7 +24,7 @@ addEventListener('export:update', ({ detail: { url } }) => {
exportPoller.add(url); exportPoller.add(url);
}); });
delegate('click', '[data-attachment-refresh]', event => { delegate('click', '[data-attachment-refresh]', (event) => {
event.preventDefault(); event.preventDefault();
attachementPoller.check(); attachementPoller.check();
}); });

View file

@ -9,7 +9,7 @@ import { delegate, toggle } from '@utils';
const TOGGLE_SOURCE_SELECTOR = '[data-toggle-target]'; const TOGGLE_SOURCE_SELECTOR = '[data-toggle-target]';
delegate('click', TOGGLE_SOURCE_SELECTOR, evt => { delegate('click', TOGGLE_SOURCE_SELECTOR, (evt) => {
evt.preventDefault(); evt.preventDefault();
const targetSelector = evt.target.dataset.toggleTarget; const targetSelector = evt.target.dataset.toggleTarget;

View file

@ -25,23 +25,4 @@ if (enabled) {
script.async = true; script.async = true;
script.src = jsUrl; script.src = jsUrl;
firstScript.parentNode.insertBefore(script, firstScript); firstScript.parentNode.insertBefore(script, firstScript);
// Send Matomo a new event when navigating to a new page using Turbolinks
// (see https://developer.matomo.org/guides/spa-tracking)
let previousPageUrl = null;
addEventListener('turbolinks:load', event => {
if (previousPageUrl) {
window._paq.push(['setReferrerUrl', previousPageUrl]);
window._paq.push(['setCustomUrl', window.location.href]);
window._paq.push(['setDocumentTitle', document.title]);
if (event.data && event.data.timing) {
window._paq.push([
'setGenerationTimeMs',
event.data.timing.visitEnd - event.data.timing.visitStart
]);
}
window._paq.push(['trackPageView']);
}
previousPageUrl = window.location.href;
});
} }

View file

@ -6,13 +6,13 @@ const { key, enabled, user, environment, browser } = gon.sentry || {};
if (enabled && key) { if (enabled && key) {
Sentry.init({ dsn: key, environment }); Sentry.init({ dsn: key, environment });
Sentry.configureScope(scope => { Sentry.configureScope((scope) => {
scope.setUser(user); scope.setUser(user);
scope.setExtra('browser', browser.modern ? 'modern' : 'legacy'); scope.setExtra('browser', browser.modern ? 'modern' : 'legacy');
}); });
// Register a way to explicitely capture messages from a different bundle. // Register a way to explicitely capture messages from a different bundle.
addEventListener('sentry:capture-exception', event => { addEventListener('sentry:capture-exception', (event) => {
const error = event.detail; const error = event.detail;
Sentry.captureException(error); Sentry.captureException(error);
}); });

View file

@ -46,7 +46,7 @@ export function removeClass(el, cssClass) {
export function delegate(eventNames, selector, callback) { export function delegate(eventNames, selector, callback) {
eventNames eventNames
.split(' ') .split(' ')
.forEach(eventName => .forEach((eventName) =>
Rails.delegate(document, selector, eventName, callback) Rails.delegate(document, selector, eventName, callback)
); );
} }
@ -90,13 +90,13 @@ export function scrollToBottom(container) {
} }
export function on(selector, eventName, fn) { export function on(selector, eventName, fn) {
[...document.querySelectorAll(selector)].forEach(element => [...document.querySelectorAll(selector)].forEach((element) =>
element.addEventListener(eventName, event => fn(event, event.detail)) element.addEventListener(eventName, (event) => fn(event, event.detail))
); );
} }
export function to(promise) { export function to(promise) {
return promise.then(result => [result]).catch(error => [null, error]); return promise.then((result) => [result]).catch((error) => [null, error]);
} }
export function isNumeric(n) { export function isNumeric(n) {

View file

@ -516,6 +516,7 @@ class Dossier < ApplicationRecord
end end
def after_repasser_en_instruction(instructeur) def after_repasser_en_instruction(instructeur)
self.archived = false
self.processed_at = nil self.processed_at = nil
self.motivation = nil self.motivation = nil
attestation&.destroy attestation&.destroy

View file

@ -85,6 +85,6 @@
- if @attestation_template.new_record? || !@attestation_template.activated - if @attestation_template.new_record? || !@attestation_template.activated
%button.btn.btn-success Activer l'attestation %button.btn.btn-success Activer l'attestation
- else - else
- save_data = @procedure.locked? ? { toggle: :tooltip, confirm: "Attention: les modifications n'affecteront pas les attestations déjà délivrées." } : nil - save_data = @procedure.locked? ? { confirm: "Attention: les modifications n'affecteront pas les attestations déjà délivrées." } : nil
%button.btn.btn-success{ data: save_data } Enregistrer %button.btn.btn-success{ data: save_data } Enregistrer

View file

@ -27,7 +27,7 @@
target: "_blank" target: "_blank"
:javascript :javascript
document.addEventListener("turbolinks:load", function() { document.addEventListener("DOMContentLoaded", function() {
$crisp.push(["do", "trigger:run", ["admin-signup"]]); $crisp.push(["do", "trigger:run", ["admin-signup"]]);
}); });

View file

@ -12,7 +12,7 @@
- if @procedure.service.nil? - if @procedure.service.nil?
- missing_elements << 'un service' - missing_elements << 'un service'
- message = "Affectez #{missing_elements.join(' et ')} à votre démarche." - message = "Affectez #{missing_elements.join(' et ')} à votre démarche."
%button.action_button.btn.btn-success#disabled-publish-procedure{ data: { toggle: :tooltip, placement: :bottom }, style: 'float: right; margin-top: 10px;', disabled: true, title: message } %button.action_button.btn.btn-success#disabled-publish-procedure{ style: 'float: right; margin-top: 10px;', disabled: true, title: message }
%i.fa.fa-eraser %i.fa.fa-eraser
Publier Publier
- else - else

View file

@ -11,7 +11,7 @@
%h1= procedure_libelle @procedure %h1= procedure_libelle @procedure
= link_to 'gestion des notifications', email_notifications_instructeur_procedure_path(@procedure), class: 'header-link' = link_to 'gestion des notifications', email_notifications_instructeur_procedure_path(@procedure), class: 'header-link'
| |
= link_to 'statistiques', stats_instructeur_procedure_path(@procedure), class: 'header-link', data: { turbolinks: false } # Turbolinks disabled for Chartkick. See Issue #350 = link_to 'statistiques', stats_instructeur_procedure_path(@procedure), class: 'header-link'
- if @procedure.routee? - if @procedure.routee?
| |

View file

@ -11,7 +11,7 @@
%h1= procedure_libelle @procedure %h1= procedure_libelle @procedure
= link_to 'gestion des notifications', email_notifications_instructeur_procedure_path(@procedure), class: 'header-link' = link_to 'gestion des notifications', email_notifications_instructeur_procedure_path(@procedure), class: 'header-link'
| |
= link_to 'statistiques', stats_instructeur_procedure_path(@procedure), class: 'header-link', data: { turbolinks: false } # Turbolinks disabled for Chartkick. See Issue #350 = link_to 'statistiques', stats_instructeur_procedure_path(@procedure), class: 'header-link'
- if @procedure.routee? - if @procedure.routee?
| |

View file

@ -5,7 +5,7 @@
\- \-
= link_to 'Nouveautés', 'https://doc.demarches-simplifiees.fr/nouveautes', target: '_blank' = link_to 'Nouveautés', 'https://doc.demarches-simplifiees.fr/nouveautes', target: '_blank'
\- \-
= link_to 'Statistiques', stats_path, data: { turbolinks: false } # Turbolinks disabled for Chartkick. See Issue #350 = link_to 'Statistiques', stats_path
\- \-
= link_to 'CGU / Mentions légales', CGU_URL, target: '_blank' = link_to 'CGU / Mentions légales', CGU_URL, target: '_blank'
\- \-

View file

@ -3,7 +3,6 @@
%head %head
%meta{ "http-equiv": "Content-Type", content: "text/html; charset=UTF-8" } %meta{ "http-equiv": "Content-Type", content: "text/html; charset=UTF-8" }
%meta{ "http-equiv": "X-UA-Compatible", content: "IE=edge" } %meta{ "http-equiv": "X-UA-Compatible", content: "IE=edge" }
%meta{ name: "turbolinks-cache-control", content: "no-cache" }
%meta{ name: "viewport", content: "width=device-width, initial-scale=1" } %meta{ name: "viewport", content: "width=device-width, initial-scale=1" }
= csrf_meta_tags = csrf_meta_tags
@ -15,9 +14,9 @@
= favicon_link_tag(image_url("favicons/96x96.png"), type: "image/png", sizes: "96x96") = favicon_link_tag(image_url("favicons/96x96.png"), type: "image/png", sizes: "96x96")
- packs = ['application', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact - packs = ['application', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
= javascript_packs_with_chunks_tag *packs, defer: true, 'data-turbolinks-track': 'reload' = javascript_packs_with_chunks_tag *packs, defer: true
= stylesheet_link_tag 'new_design/new_application', media: 'all', 'data-turbolinks-track': 'reload' = stylesheet_link_tag 'new_design/new_application', media: 'all'
= stylesheet_link_tag 'new_design/print', media: 'print', 'data-turbolinks-track': 'reload' = stylesheet_link_tag 'new_design/print', media: 'print'
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce) = Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)

View file

@ -1,7 +1,6 @@
%html %html
%head %head
%meta{ :content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/ %meta{ :content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
%meta{ name: "turbolinks-cache-control", content: "no-cache" }
%title %title
= t('dynamics.page_title') = t('dynamics.page_title')
%meta{ 'http-equiv' => "X-UA-Compatible", :content => "IE=edge" } %meta{ 'http-equiv' => "X-UA-Compatible", :content => "IE=edge" }
@ -10,11 +9,11 @@
= favicon_link_tag(image_url("favicons/32x32.png"), type: "image/png", sizes: "32x32") = favicon_link_tag(image_url("favicons/32x32.png"), type: "image/png", sizes: "32x32")
= favicon_link_tag(image_url("favicons/96x96.png"), type: "image/png", sizes: "96x96") = favicon_link_tag(image_url("favicons/96x96.png"), type: "image/png", sizes: "96x96")
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': "reload" = stylesheet_link_tag 'application', media: 'all'
= stylesheet_link_tag 'print', media: 'print', 'data-turbolinks-track': "reload" = stylesheet_link_tag 'print', media: 'print'
- packs = ['application-old', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact - packs = ['application-old', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
= javascript_packs_with_chunks_tag *packs, defer: true, 'data-turbolinks-track': 'reload' = javascript_packs_with_chunks_tag *packs, defer: true
= javascript_include_tag 'application', defer: true, 'data-turbolinks-track': 'reload' = javascript_include_tag 'application', defer: true
= csrf_meta_tags = csrf_meta_tags
= Gon::Base.render_data(camel_case: true, init: true) = Gon::Base.render_data(camel_case: true, init: true)

View file

@ -23,7 +23,7 @@
%li.footer-link %li.footer-link
= link_to "Nouveautés", "https://github.com/betagouv/demarches-simplifiees.fr/releases", :class => "footer-link", :title => "Nos nouveautés" = link_to "Nouveautés", "https://github.com/betagouv/demarches-simplifiees.fr/releases", :class => "footer-link", :title => "Nos nouveautés"
%li.footer-link %li.footer-link
= link_to "Statistiques", stats_path, :class => "footer-link", data: { turbolinks: false } # Turbolinks disabled for Chartkick. See Issue #350 = link_to "Statistiques", stats_path, :class => "footer-link"
%li.footer-link %li.footer-link
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link %li.footer-link

View file

@ -1,35 +1,35 @@
{ {
"dependencies": { "dependencies": {
"@babel/preset-react": "^7.8.3", "@babel/preset-react": "^7.9.4",
"@fortawesome/fontawesome-svg-core": "^1.2.26", "@fortawesome/fontawesome-svg-core": "^1.2.28",
"@fortawesome/free-solid-svg-icons": "^5.12.0", "@fortawesome/free-solid-svg-icons": "^5.13.0",
"@fortawesome/react-fontawesome": "^0.1.8", "@fortawesome/react-fontawesome": "^0.1.9",
"@mapbox/mapbox-gl-draw": "^1.1.2", "@mapbox/mapbox-gl-draw": "^1.1.2",
"@rails/actiontext": "^6.0.2-1", "@rails/actiontext": "^6.0.2-2",
"@rails/activestorage": "^6.0.2-1", "@rails/activestorage": "^6.0.2-2",
"@rails/ujs": "^6.0.2-1", "@rails/ujs": "^6.0.2-2",
"@rails/webpacker": "4.2.2", "@rails/webpacker": "5.1.1",
"@reach/combobox": "^0.10.0", "@reach/combobox": "^0.10.1",
"@sentry/browser": "^5.11.2", "@sentry/browser": "^5.15.5",
"@tmcw/togeojson": "^4.0.0", "@tmcw/togeojson": "^4.0.0",
"@turf/area": "^6.0.1", "@turf/area": "^6.0.1",
"babel-plugin-macros": "^2.8.0", "babel-plugin-macros": "^2.8.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24", "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"chartkick": "^3.2.0", "chartkick": "^3.2.0",
"core-js": "^3.6.4", "core-js": "^3.6.5",
"debounce": "^1.2.0", "debounce": "^1.2.0",
"dom4": "^2.1.5", "dom4": "^2.1.5",
"email-butler": "^1.0.13", "email-butler": "^1.0.13",
"highcharts": "^8.0.0", "highcharts": "^8.0.4",
"intersection-observer": "^0.7.0", "intersection-observer": "^0.10.0",
"jquery": "^3.5.0", "jquery": "^3.5.0",
"leaflet": "^1.6.0", "leaflet": "^1.6.0",
"leaflet-freedraw": "^2.12.0", "leaflet-freedraw": "^2.12.0",
"mapbox-gl": "^1.9.0", "mapbox-gl": "^1.10.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^16.12.0", "react": "^16.13.1",
"react-dom": "^16.12.0", "react-dom": "^16.13.1",
"react-intersection-observer": "^8.25.2", "react-intersection-observer": "^8.26.2",
"react-loadable": "^5.5.0", "react-loadable": "^5.5.0",
"react-mapbox-gl": "^4.8.3", "react-mapbox-gl": "^4.8.3",
"react-mapbox-gl-draw": "^2.0.4", "react-mapbox-gl-draw": "^2.0.4",
@ -37,21 +37,20 @@
"react-sortable-hoc": "^1.11.0", "react-sortable-hoc": "^1.11.0",
"react_ujs": "^2.6.1", "react_ujs": "^2.6.1",
"select2": "^4.0.13", "select2": "^4.0.13",
"trix": "^1.2.2", "trix": "^1.2.3",
"turbolinks": "^5.2.0",
"whatwg-fetch": "^3.0.0" "whatwg-fetch": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.0.3", "babel-eslint": "^10.1.0",
"eclint": "^2.8.1", "eclint": "^2.8.1",
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-config-prettier": "^6.10.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.2", "eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react": "^7.18.0", "eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.3.0", "eslint-plugin-react-hooks": "^3.0.0",
"prettier": "^1.19.1", "prettier": "^2.0.5",
"webpack-bundle-analyzer": "^3.6.0", "webpack-bundle-analyzer": "^3.7.0",
"webpack-dev-server": "^3.10.0" "webpack-dev-server": "^3.10.3"
}, },
"scripts": { "scripts": {
"lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)", "lint:ec": "eclint check $({ git ls-files | grep -v app/graphql/schema.graphql ; find vendor -type f ; echo 'db/schema.rb' ; } | sort | uniq -u)",

View file

@ -180,7 +180,11 @@ describe Admin::ProceduresController, type: :controller do
expect(procedure.publiee?).to be_truthy expect(procedure.publiee?).to be_truthy
expect(procedure.path).to eq(path) expect(procedure.path).to eq(path)
expect(procedure.lien_site_web).to eq(lien_site_web) expect(procedure.lien_site_web).to eq(lien_site_web)
expect(response.status).to eq 302 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' expect(flash[:notice]).to have_content 'Démarche publiée'
end end
end end
@ -193,13 +197,17 @@ describe Admin::ProceduresController, type: :controller do
expect(procedure.publiee?).to be_truthy expect(procedure.publiee?).to be_truthy
expect(procedure.path).to eq(path) expect(procedure.path).to eq(path)
expect(procedure.lien_site_web).to eq(lien_site_web) expect(procedure.lien_site_web).to eq(lien_site_web)
expect(response.status).to eq 302
expect(flash[:notice]).to have_content 'Démarche publiée'
end end
it 'depubliee previous procedure' do it 'depubliee previous procedure' do
expect(procedure2.depubliee?).to be_truthy expect(procedure2.depubliee?).to be_truthy
end 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 end
context 'procedure path exists and is not owned by current administrator' do context 'procedure path exists and is not owned by current administrator' do
@ -285,8 +293,12 @@ describe Admin::ProceduresController, type: :controller do
end end
it { expect(procedure.publiee?).to be_truthy } it { expect(procedure.publiee?).to be_truthy }
it { expect(response.status).to eq 302 }
it { expect(flash[:notice]).to have_content 'Démarche publiée' } 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
end end

View file

@ -133,7 +133,7 @@ feature 'The routing', js: true do
click_on 'suivi' click_on 'suivi'
click_on litteraire_user.email click_on litteraire_user.email
expect(page).to have_current_path(instructeur_dossier_path(procedure, litteraire_user.dossiers.first)) expect(page).to have_current_path(instructeur_dossier_path(procedure, litteraire_user.dossiers.first))
expect(page).to have_text('Annotations privées') # ensure Turbolinks DID load the DOM content expect(page).to have_text('Annotations privées')
expect(find('.tabs')).to have_css('span.notifications') expect(find('.tabs')).to have_css('span.notifications')
log_out log_out

View file

@ -1056,7 +1056,7 @@ describe Dossier do
end end
describe '#repasser_en_instruction!' do describe '#repasser_en_instruction!' do
let(:dossier) { create(:dossier, :refuse, :with_attestation) } let(:dossier) { create(:dossier, :refuse, :with_attestation, archived: true) }
let!(:instructeur) { create(:instructeur) } let!(:instructeur) { create(:instructeur) }
let(:last_operation) { dossier.dossier_operation_logs.last } let(:last_operation) { dossier.dossier_operation_logs.last }
@ -1069,6 +1069,7 @@ describe Dossier do
end end
it { expect(dossier.state).to eq('en_instruction') } it { expect(dossier.state).to eq('en_instruction') }
it { expect(dossier.archived).to be_falsey }
it { expect(dossier.processed_at).to be_nil } it { expect(dossier.processed_at).to be_nil }
it { expect(dossier.motivation).to be_nil } it { expect(dossier.motivation).to be_nil }
it { expect(dossier.attestation).to be_nil } it { expect(dossier.attestation).to be_nil }

1161
yarn.lock

File diff suppressed because it is too large Load diff