Merge pull request #5142 from betagouv/dev
This commit is contained in:
commit
b28866dbc9
67 changed files with 848 additions and 814 deletions
|
@ -1,3 +1,4 @@
|
|||
module.exports = {
|
||||
singleQuote: true
|
||||
singleQuote: true,
|
||||
trailingComma: 'none'
|
||||
};
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -71,7 +71,6 @@ gem 'skylight'
|
|||
gem 'smart_listing'
|
||||
gem 'spreadsheet_architect'
|
||||
gem 'sprockets', '< 4'
|
||||
gem 'turbolinks' # Turbolinks makes following links in your web application faster
|
||||
gem 'typhoeus'
|
||||
gem 'warden'
|
||||
gem 'webpacker'
|
||||
|
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -361,7 +361,7 @@ GEM
|
|||
railties (>= 4)
|
||||
request_store (~> 1.0)
|
||||
logstash-event (1.2.02)
|
||||
loofah (2.4.0)
|
||||
loofah (2.5.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.0.13)
|
||||
|
@ -613,6 +613,7 @@ GEM
|
|||
selenium-webdriver (3.141.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.2, >= 1.2.2)
|
||||
semantic_range (2.3.0)
|
||||
sentry-raven (2.7.4)
|
||||
faraday (>= 0.7.6, < 1.0)
|
||||
sexp_processor (4.14.1)
|
||||
|
@ -662,12 +663,9 @@ GEM
|
|||
tilt (2.0.10)
|
||||
timecop (0.9.1)
|
||||
ttfunk (1.5.1)
|
||||
turbolinks (5.2.0)
|
||||
turbolinks-source (~> 5.2)
|
||||
turbolinks-source (5.2.0)
|
||||
typhoeus (1.3.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.6)
|
||||
tzinfo (1.2.7)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
|
@ -698,10 +696,11 @@ GEM
|
|||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
webpacker (4.0.2)
|
||||
activesupport (>= 4.2)
|
||||
webpacker (5.1.1)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 4.2)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
websocket-driver (0.7.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.4)
|
||||
|
@ -821,7 +820,6 @@ DEPENDENCIES
|
|||
spring-commands-rspec
|
||||
sprockets (< 4)
|
||||
timecop
|
||||
turbolinks
|
||||
typhoeus
|
||||
vcr
|
||||
warden
|
||||
|
|
|
@ -16,18 +16,3 @@
|
|||
//= require smart_listing
|
||||
//= require bootstrap-wysihtml5
|
||||
//= 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 } });
|
||||
}
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('click', '.delete', function() {
|
||||
$(document).on('click', '.delete', function () {
|
||||
$(this).hide();
|
||||
$(this)
|
||||
.closest('td')
|
||||
.find('.confirm')
|
||||
.show();
|
||||
$(this).closest('td').find('.confirm').show();
|
||||
});
|
||||
|
||||
$(document).on('click', '.cancel', function() {
|
||||
$(this)
|
||||
.closest('td')
|
||||
.find('.delete')
|
||||
.show();
|
||||
$(this)
|
||||
.closest('td')
|
||||
.find('.confirm')
|
||||
.hide();
|
||||
$(document).on('click', '.cancel', function () {
|
||||
$(this).closest('td').find('.delete').show();
|
||||
$(this).closest('td').find('.confirm').hide();
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('click', 'button#archive-procedure', function() {
|
||||
$(document).on('click', 'button#archive-procedure', function () {
|
||||
$('button#archive-procedure').hide();
|
||||
$('#confirm').show();
|
||||
});
|
||||
|
||||
$(document).on('click', '#confirm #cancel', function() {
|
||||
$(document).on('click', '#confirm #cancel', function () {
|
||||
$('button#archive-procedure').show();
|
||||
$('#confirm').hide();
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', wysihtml5_active);
|
||||
$(document).on('DOMContentLoaded', wysihtml5_active);
|
||||
|
||||
function wysihtml5_active() {
|
||||
$('.wysihtml5').each(function(i, elem) {
|
||||
$('.wysihtml5').each(function (i, elem) {
|
||||
$(elem).wysihtml5({
|
||||
toolbar: {
|
||||
fa: true,
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', init_default_data_block);
|
||||
$(document).on('DOMContentLoaded', init_default_data_block);
|
||||
|
||||
function init_default_data_block() {
|
||||
$('.default-data-block #dossier .body').toggle();
|
||||
$('.default-data-block #dossier .carret-right').toggle();
|
||||
$('.default-data-block #dossier .carret-down').toggle();
|
||||
|
||||
$('.default-data-block .title').click(function() {
|
||||
$('.default-data-block .title').click(function () {
|
||||
toggle_default_data_bloc(this, 400);
|
||||
});
|
||||
|
||||
$('.new-action').click(function() {
|
||||
$('.new-action').click(function () {
|
||||
var messages_block = $(this)
|
||||
.parents()
|
||||
.closest('.default-data-block')
|
||||
|
@ -19,7 +19,7 @@ function init_default_data_block() {
|
|||
toggle_default_data_bloc(messages_block, 400);
|
||||
});
|
||||
|
||||
$('.default-data-block.default_visible').each(function() {
|
||||
$('.default-data-block.default_visible').each(function () {
|
||||
toggle_default_data_bloc($(this).find('.title'), 0);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,32 +1,25 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', filters_init);
|
||||
$(document).on('DOMContentLoaded', filters_init);
|
||||
|
||||
function filters_init() {
|
||||
$('html').click(function(event) {
|
||||
$('html').click(function (event) {
|
||||
var visible_filter = $('.filter_framed:visible');
|
||||
if (visible_filter.length) {
|
||||
if (
|
||||
!$(event.target)
|
||||
.closest('.filter_framed')
|
||||
.is(':visible')
|
||||
) {
|
||||
if (!$(event.target).closest('.filter_framed').is(':visible')) {
|
||||
visible_filter.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.filter').on('click', function(event) {
|
||||
$('.filter').on('click', function (event) {
|
||||
filter_framed_show(event);
|
||||
filter_framed_close_all_excepted(framed_id(event));
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
$('.erase-filter').on('click', function() {
|
||||
$(this)
|
||||
.parent()
|
||||
.find('.filter_input')
|
||||
.val('');
|
||||
$('.erase-filter').on('click', function () {
|
||||
$(this).parent().find('.filter_input').val('');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('click', '#dossiers-list tr', function(event) {
|
||||
$(document).on('click', '#dossiers-list tr', function (event) {
|
||||
var href = $(this).data('href');
|
||||
if (href && event.target.tagName !== 'A') {
|
||||
location.href = href;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', action_type_de_champs);
|
||||
$(document).on('DOMContentLoaded', action_type_de_champs);
|
||||
|
||||
function action_type_de_champs() {
|
||||
$("input[type='email']").on('change', function() {
|
||||
$("input[type='email']").on('change', function () {
|
||||
toggleErrorClass(this, validateEmail($(this).val()));
|
||||
});
|
||||
|
||||
$("input[type='number']").on('change', function() {
|
||||
$("input[type='number']").on('change', function () {
|
||||
toggleErrorClass(this, validateNumber($(this).val()));
|
||||
});
|
||||
|
||||
$("input[type='phone']").on('change', function() {
|
||||
$("input[type='phone']").on('change', function () {
|
||||
var val = $(this).val();
|
||||
val = val.replace(/[ ]/g, '');
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', modal_action);
|
||||
$(document).on('DOMContentLoaded', modal_action);
|
||||
|
||||
function modal_action() {
|
||||
$('#pj-modal').on('show.bs.modal', function(event) {
|
||||
$('#pj-modal').on('show.bs.modal', function (event) {
|
||||
$('#pj-modal .modal-body .table .tr-content').hide();
|
||||
|
||||
var button = $(event.relatedTarget); // Button that triggered the modal
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* globals $ */
|
||||
|
||||
$(document).on('turbolinks:load', button_edit_procedure_init);
|
||||
$(document).on('DOMContentLoaded', button_edit_procedure_init);
|
||||
|
||||
function button_edit_procedure_init() {
|
||||
buttons_api_carto();
|
||||
|
@ -8,7 +8,7 @@ function button_edit_procedure_init() {
|
|||
}
|
||||
|
||||
function buttons_api_carto() {
|
||||
$('#procedure-module-api-carto-use-api-carto').on('change', function() {
|
||||
$('#procedure-module-api-carto-use-api-carto').on('change', function () {
|
||||
$('#modules-api-carto').toggle();
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@ function buttons_api_carto() {
|
|||
}
|
||||
|
||||
function button_individual() {
|
||||
$('#procedure_for_individual').on('change', function() {
|
||||
$('#procedure_for_individual').on('change', function () {
|
||||
$('#individual-with-siret').toggle();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
@import "constants";
|
||||
|
||||
.turbolinks-progress-bar {
|
||||
background-color: $light-blue;
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
//
|
||||
// = require _card
|
||||
// = require _helpers
|
||||
// = require _turbolinks
|
||||
// = require admin_type_de_champ
|
||||
// = require carte
|
||||
// = require custom_mails
|
||||
|
|
|
@ -72,7 +72,7 @@ class Admin::ProceduresController < AdminController
|
|||
@procedure.publish_or_reopen!(current_administrateur)
|
||||
|
||||
flash.notice = "Démarche publiée"
|
||||
redirect_to admin_procedures_path
|
||||
render js: "window.location='#{admin_procedures_path}'"
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render 'publish_validate', formats: :js
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ import Chartkick from 'chartkick';
|
|||
import Highcharts from 'highcharts';
|
||||
import { toggle, delegate } from '@utils';
|
||||
|
||||
export default function() {
|
||||
export default function () {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@ import Loadable from 'react-loadable';
|
|||
|
||||
const loading = () => <div className="spinner left" />;
|
||||
|
||||
export default function(loader) {
|
||||
export default function (loader) {
|
||||
return Loadable({ loader, loading });
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ import '@reach/combobox/styles.css';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
let cache = {};
|
||||
const useAddressSearch = searchTerm => {
|
||||
const useAddressSearch = (searchTerm) => {
|
||||
const [addresses, setAddresses] = useState([]);
|
||||
useEffect(() => {
|
||||
if (searchTerm.trim() !== '') {
|
||||
let isFresh = true;
|
||||
fetchAddresses(searchTerm).then(addresses => {
|
||||
fetchAddresses(searchTerm).then((addresses) => {
|
||||
if (isFresh) setAddresses(addresses);
|
||||
});
|
||||
return () => (isFresh = false);
|
||||
|
@ -25,12 +25,12 @@ const useAddressSearch = searchTerm => {
|
|||
return addresses;
|
||||
};
|
||||
|
||||
const fetchAddresses = value => {
|
||||
const fetchAddresses = (value) => {
|
||||
if (cache[value]) {
|
||||
return Promise.resolve(cache[value]);
|
||||
}
|
||||
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) {
|
||||
cache[value] = result;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ const fetchAddresses = value => {
|
|||
const SearchInput = ({ getCoords }) => {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const addresses = useAddressSearch(searchTerm);
|
||||
const handleSearchTermChange = event => {
|
||||
const handleSearchTermChange = (event) => {
|
||||
setSearchTerm(event.target.value);
|
||||
};
|
||||
return (
|
||||
|
@ -72,7 +72,7 @@ const SearchInput = ({ getCoords }) => {
|
|||
>
|
||||
{addresses.features.length > 0 ? (
|
||||
<ComboboxList>
|
||||
{addresses.features.map(feature => {
|
||||
{addresses.features.map((feature) => {
|
||||
const str = `${feature.properties.name}, ${feature.properties.city}`;
|
||||
return (
|
||||
<ComboboxOption
|
||||
|
|
|
@ -9,7 +9,8 @@ const SwitchMapStyle = ({ isVector }) => {
|
|||
|
||||
const imgStyle = {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
height: '100%',
|
||||
cursor: 'pointer'
|
||||
};
|
||||
|
||||
const textStyle = {
|
||||
|
@ -24,11 +25,6 @@ const SwitchMapStyle = ({ isVector }) => {
|
|||
<div className="text" style={textStyle}>
|
||||
{style}
|
||||
</div>
|
||||
<style jsx>{`
|
||||
img:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ function filterFeatureCollection(featureCollection, source) {
|
|||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: featureCollection.features.filter(
|
||||
feature => feature.properties.source === source
|
||||
(feature) => feature.properties.source === source
|
||||
)
|
||||
};
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ const MapEditor = ({ featureCollection, url }) => {
|
|||
updateFeaturesList(features);
|
||||
}
|
||||
|
||||
const onMapLoad = map => {
|
||||
const onMapLoad = (map) => {
|
||||
setCurrentMap(map);
|
||||
|
||||
drawControl.current.draw.set(
|
||||
|
@ -83,7 +83,7 @@ const MapEditor = ({ featureCollection, url }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const onCadastresUpdate = evt => {
|
||||
const onCadastresUpdate = (evt) => {
|
||||
if (currentMap) {
|
||||
currentMap
|
||||
.getSource('cadastres-layer')
|
||||
|
@ -93,10 +93,10 @@ const MapEditor = ({ featureCollection, url }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const onGpxImport = e => {
|
||||
const onGpxImport = (e) => {
|
||||
let reader = new FileReader();
|
||||
reader.readAsText(e.target.files[0], 'UTF-8');
|
||||
reader.onload = async event => {
|
||||
reader.onload = async (event) => {
|
||||
const featureCollection = gpx(
|
||||
new DOMParser().parseFromString(event.target.result, 'text/xml')
|
||||
);
|
||||
|
@ -149,14 +149,14 @@ const MapEditor = ({ featureCollection, url }) => {
|
|||
}}
|
||||
>
|
||||
<SearchInput
|
||||
getCoords={searchTerm => {
|
||||
getCoords={(searchTerm) => {
|
||||
setCoords(searchTerm);
|
||||
setZoom([17]);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Map
|
||||
onStyleLoad={map => onMapLoad(map)}
|
||||
onStyleLoad={(map) => onMapLoad(map)}
|
||||
fitBounds={bbox}
|
||||
fitBoundsOptions={{ padding: 100 }}
|
||||
center={coords}
|
|
@ -12,25 +12,25 @@ const MapReader = ({ featureCollection }) => {
|
|||
[b1, b2]
|
||||
];
|
||||
|
||||
const selectionsFeatureCollection = {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
const cadastresFeatureCollection = {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
|
||||
for (let feature of featureCollection.features) {
|
||||
switch (feature.properties.source) {
|
||||
case 'selection_utilisateur':
|
||||
selectionsFeatureCollection.features.push(feature);
|
||||
break;
|
||||
case 'cadastre':
|
||||
cadastresFeatureCollection.features.push(feature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const selectionsLineFeatureCollection = {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
|
||||
const selectionsPolygonFeatureCollection = {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
|
||||
const selectionsPointFeatureCollection = {
|
||||
type: 'FeatureCollection',
|
||||
features: []
|
||||
};
|
||||
|
||||
const polygonSelectionFill = {
|
||||
'fill-color': '#EC3323',
|
||||
|
@ -42,6 +42,15 @@ const MapReader = ({ featureCollection }) => {
|
|||
'line-width': 4
|
||||
};
|
||||
|
||||
const lineStringSelectionLine = {
|
||||
'line-color': 'rgba(55, 42, 127, 1.00)',
|
||||
'line-width': 3
|
||||
};
|
||||
|
||||
const pointSelectionFill = {
|
||||
'circle-color': '#EC3323'
|
||||
};
|
||||
|
||||
const polygonCadastresFill = {
|
||||
'fill-color': '#9CA090',
|
||||
'fill-opacity': 0.5
|
||||
|
@ -53,6 +62,27 @@ const MapReader = ({ featureCollection }) => {
|
|||
'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()) {
|
||||
return (
|
||||
<p>
|
||||
|
@ -74,10 +104,18 @@ const MapReader = ({ featureCollection }) => {
|
|||
}}
|
||||
>
|
||||
<GeoJSONLayer
|
||||
data={selectionsFeatureCollection}
|
||||
data={selectionsPolygonFeatureCollection}
|
||||
fillPaint={polygonSelectionFill}
|
||||
linePaint={polygonSelectionLine}
|
||||
/>
|
||||
<GeoJSONLayer
|
||||
data={selectionsLineFeatureCollection}
|
||||
linePaint={lineStringSelectionLine}
|
||||
/>
|
||||
<GeoJSONLayer
|
||||
data={selectionsPointFeatureCollection}
|
||||
circlePaint={pointSelectionFill}
|
||||
/>
|
||||
<GeoJSONLayer
|
||||
data={cadastresFeatureCollection}
|
||||
fillPaint={polygonCadastresFill}
|
|
@ -72,7 +72,7 @@ function onFileChange(handler, directUploadUrl) {
|
|||
|
||||
function uploadFile(input, file, directUploadUrl) {
|
||||
const controller = new Uploader(input, file, directUploadUrl);
|
||||
return controller.start().then(signedId => {
|
||||
return controller.start().then((signedId) => {
|
||||
input.value = null;
|
||||
return signedId;
|
||||
});
|
||||
|
|
|
@ -17,7 +17,9 @@ function TypeDeChampRepetitionOptions({
|
|||
return (
|
||||
<div className="repetition flex-grow cell">
|
||||
<SortableContainer
|
||||
onSortEnd={params => dispatch({ type: 'onSortTypeDeChamps', params })}
|
||||
onSortEnd={(params) =>
|
||||
dispatch({ type: 'onSortTypeDeChamps', params })
|
||||
}
|
||||
useDragHandle
|
||||
>
|
||||
{state.typeDeChamps.map((typeDeChamp, index) => (
|
||||
|
|
|
@ -12,12 +12,14 @@ function TypeDeChamps({ state: rootState, typeDeChamps }) {
|
|||
typeDeChamps
|
||||
});
|
||||
|
||||
const hasUnsavedChamps = state.typeDeChamps.some(tdc => tdc.id == undefined);
|
||||
const hasUnsavedChamps = state.typeDeChamps.some(
|
||||
(tdc) => tdc.id == undefined
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="champs-editor">
|
||||
<SortableContainer
|
||||
onSortEnd={params => dispatch({ type: 'onSortTypeDeChamps', params })}
|
||||
onSortEnd={(params) => dispatch({ type: 'onSortTypeDeChamps', params })}
|
||||
lockAxis="y"
|
||||
useDragHandle
|
||||
>
|
||||
|
|
|
@ -5,7 +5,7 @@ export function createTypeDeChampOperation(typeDeChamp, queue) {
|
|||
method: 'post',
|
||||
payload: { type_de_champ: typeDeChamp }
|
||||
})
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
handleResponseData(typeDeChamp, data);
|
||||
});
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ export function updateTypeDeChampOperation(typeDeChamp, queue) {
|
|||
method: 'patch',
|
||||
payload: { type_de_champ: typeDeChamp }
|
||||
})
|
||||
.then(data => {
|
||||
.then((data) => {
|
||||
handleResponseData(typeDeChamp, data);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
if (insertAfter) {
|
||||
|
@ -127,7 +127,7 @@ function updateTypeDeChamp(
|
|||
function removeTypeDeChamp(state, typeDeChamps, { typeDeChamp }) {
|
||||
destroyTypeDeChampOperation(typeDeChamp, state.queue)
|
||||
.then(() => state.flash.success())
|
||||
.catch(message => state.flash.error(message));
|
||||
.catch((message) => state.flash.error(message));
|
||||
|
||||
return {
|
||||
...state,
|
||||
|
@ -141,7 +141,7 @@ function moveTypeDeChampUp(state, typeDeChamps, { typeDeChamp }) {
|
|||
|
||||
moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue)
|
||||
.then(() => state.flash.success())
|
||||
.catch(message => state.flash.error(message));
|
||||
.catch((message) => state.flash.error(message));
|
||||
|
||||
return {
|
||||
...state,
|
||||
|
@ -155,7 +155,7 @@ function moveTypeDeChampDown(state, typeDeChamps, { typeDeChamp }) {
|
|||
|
||||
moveTypeDeChampOperation(typeDeChamp, newIndex, state.queue)
|
||||
.then(() => state.flash.success())
|
||||
.catch(message => state.flash.error(message));
|
||||
.catch((message) => state.flash.error(message));
|
||||
|
||||
return {
|
||||
...state,
|
||||
|
@ -166,7 +166,7 @@ function moveTypeDeChampDown(state, typeDeChamps, { typeDeChamp }) {
|
|||
function onSortTypeDeChamps(state, typeDeChamps, { oldIndex, newIndex }) {
|
||||
moveTypeDeChampOperation(typeDeChamps[oldIndex], newIndex, state.queue)
|
||||
.then(() => state.flash.success())
|
||||
.catch(message => state.flash.error(message));
|
||||
.catch((message) => state.flash.error(message));
|
||||
|
||||
return {
|
||||
...state,
|
||||
|
@ -191,13 +191,13 @@ function getUpdateHandler(typeDeChamp, { queue, flash }) {
|
|||
let handler = updateHandlers.get(typeDeChamp);
|
||||
if (!handler) {
|
||||
handler = debounce(
|
||||
done =>
|
||||
(done) =>
|
||||
updateTypeDeChampOperation(typeDeChamp, queue)
|
||||
.then(() => {
|
||||
flash.success();
|
||||
done();
|
||||
})
|
||||
.catch(message => flash.error(message)),
|
||||
.catch((message) => flash.error(message)),
|
||||
200
|
||||
);
|
||||
updateHandlers.set(typeDeChamp, handler);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/MapEditor/MapEditor'));
|
||||
export default Loadable(() => import('../components/MapEditor'));
|
||||
|
|
|
@ -25,7 +25,7 @@ async function loadAndRedrawMap(element, data) {
|
|||
redrawMap(element, data);
|
||||
}
|
||||
|
||||
addEventListener('turbolinks:load', initialize);
|
||||
addEventListener('DOMContentLoaded', initialize);
|
||||
|
||||
addEventListener('carte:update', ({ detail: { selector, data } }) => {
|
||||
const element = document.querySelector(selector);
|
||||
|
|
|
@ -4,7 +4,7 @@ const PRIMARY_SELECTOR = 'select[data-secondary-options]';
|
|||
const SECONDARY_SELECTOR = 'select[data-secondary]';
|
||||
const CHAMP_SELECTOR = '.editable-champ';
|
||||
|
||||
delegate('change', PRIMARY_SELECTOR, evt => {
|
||||
delegate('change', PRIMARY_SELECTOR, (evt) => {
|
||||
const primary = evt.target;
|
||||
const secondary = primary
|
||||
.closest(CHAMP_SELECTOR)
|
||||
|
|
|
@ -4,7 +4,7 @@ const BUTTON_SELECTOR = '.button.remove-row';
|
|||
const DESTROY_INPUT_SELECTOR = 'input[type=hidden][name*=_destroy]';
|
||||
const CHAMP_SELECTOR = '.editable-champ';
|
||||
|
||||
delegate('click', BUTTON_SELECTOR, evt => {
|
||||
delegate('click', BUTTON_SELECTOR, (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const row = evt.target.closest('.row');
|
||||
|
|
|
@ -41,7 +41,7 @@ export default class AutoSaveController {
|
|||
headers: { Accept: 'application/json' }
|
||||
};
|
||||
|
||||
return window.fetch(form.action, fetchOptions).then(response => {
|
||||
return window.fetch(form.action, fetchOptions).then((response) => {
|
||||
if (response.ok) {
|
||||
resolve(response);
|
||||
} else {
|
||||
|
@ -64,7 +64,7 @@ export default class AutoSaveController {
|
|||
const fileInputs = form.querySelectorAll(
|
||||
'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
|
||||
let formData = null;
|
||||
|
@ -75,7 +75,7 @@ export default class AutoSaveController {
|
|||
return [null, error];
|
||||
} finally {
|
||||
// Re-enable disabled file inputs
|
||||
fileInputs.forEach(fileInput => (fileInput.disabled = false));
|
||||
fileInputs.forEach((fileInput) => (fileInput.disabled = false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ addEventListener('autosave:end', () => {
|
|||
hideSucceededStatusAfterDelay();
|
||||
});
|
||||
|
||||
addEventListener('autosave:error', event => {
|
||||
addEventListener('autosave:error', (event) => {
|
||||
enable(document.querySelector('button.autosave-retry'));
|
||||
setState('failed');
|
||||
logError(event.detail);
|
||||
|
|
|
@ -5,18 +5,18 @@ import { delegate } from '@utils';
|
|||
const autoUploadsControllers = new AutoUploadsControllers();
|
||||
|
||||
function startUpload(input) {
|
||||
Array.from(input.files).forEach(file => {
|
||||
Array.from(input.files).forEach((file) => {
|
||||
autoUploadsControllers.upload(input, file);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
const retryButtonSelector = `button.attachment-error-retry`;
|
||||
delegate('click', retryButtonSelector, function() {
|
||||
delegate('click', retryButtonSelector, function () {
|
||||
const inputSelector = this.dataset.inputTarget;
|
||||
const input = document.querySelector(inputSelector);
|
||||
startUpload(input);
|
||||
|
|
|
@ -40,18 +40,18 @@ export default class AutoUploadsControllers {
|
|||
if (form) {
|
||||
form
|
||||
.querySelectorAll('button[type=submit]')
|
||||
.forEach(submitButton => Rails.disableElement(submitButton));
|
||||
.forEach((submitButton) => Rails.disableElement(submitButton));
|
||||
}
|
||||
|
||||
//
|
||||
// DEBUG: hook into FileReader onload event
|
||||
//
|
||||
if (FileReader.prototype.addEventListener === originalImpl) {
|
||||
FileReader.prototype.addEventListener = function() {
|
||||
FileReader.prototype.addEventListener = function () {
|
||||
// When DirectUploads attempts to add an event listener for "error",
|
||||
// also insert a custom event listener of our that will report errors to Sentry.
|
||||
if (arguments[0] == 'error') {
|
||||
let handler = event => {
|
||||
let handler = (event) => {
|
||||
let message = `FileReader ${event.target.error.name}: ${event.target.error.message}`;
|
||||
fire(document, 'sentry:capture-exception', new Error(message));
|
||||
};
|
||||
|
@ -71,7 +71,7 @@ export default class AutoUploadsControllers {
|
|||
if (this.inFlightUploadsCount == 0 && form) {
|
||||
form
|
||||
.querySelectorAll('button[type=submit]')
|
||||
.forEach(submitButton => Rails.enableElement(submitButton));
|
||||
.forEach((submitButton) => Rails.enableElement(submitButton));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { delegate } from '@utils';
|
||||
|
||||
delegate('click', 'body', event => {
|
||||
delegate('click', 'body', (event) => {
|
||||
if (!event.target.closest('.dropdown')) {
|
||||
[...document.querySelectorAll('.dropdown')].forEach(element =>
|
||||
[...document.querySelectorAll('.dropdown')].forEach((element) =>
|
||||
element.classList.remove('open', 'fade-in-down')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
delegate('click', '.dropdown-button', event => {
|
||||
delegate('click', '.dropdown-button', (event) => {
|
||||
event.stopPropagation();
|
||||
const parent = event.target.closest('.dropdown-button').parentElement;
|
||||
if (parent.classList.contains('dropdown')) {
|
||||
|
|
|
@ -5,15 +5,15 @@ import { isNumeric } from '@utils';
|
|||
const { api_geo_url, api_adresse_url } = gon.autocomplete || {};
|
||||
|
||||
const language = {
|
||||
errorLoading: function() {
|
||||
errorLoading: function () {
|
||||
return 'Les résultats ne peuvent pas être chargés.';
|
||||
},
|
||||
inputTooLong: function(args) {
|
||||
inputTooLong: function (args) {
|
||||
var overChars = args.input.length - args.maximum;
|
||||
|
||||
return 'Supprimez ' + overChars + ' caractère' + (overChars > 1 ? 's' : '');
|
||||
},
|
||||
inputTooShort: function(args) {
|
||||
inputTooShort: function (args) {
|
||||
var remainingChars = args.minimum - args.input.length;
|
||||
|
||||
return (
|
||||
|
@ -23,10 +23,10 @@ const language = {
|
|||
(remainingChars > 1 ? 's' : '')
|
||||
);
|
||||
},
|
||||
loadingMore: function() {
|
||||
loadingMore: function () {
|
||||
return 'Chargement de résultats supplémentaires…';
|
||||
},
|
||||
maximumSelected: function(args) {
|
||||
maximumSelected: function (args) {
|
||||
return (
|
||||
'Vous pouvez seulement sélectionner ' +
|
||||
args.maximum +
|
||||
|
@ -34,13 +34,13 @@ const language = {
|
|||
(args.maximum > 1 ? 's' : '')
|
||||
);
|
||||
},
|
||||
noResults: function() {
|
||||
noResults: function () {
|
||||
return 'Aucun résultat trouvé';
|
||||
},
|
||||
searching: function() {
|
||||
searching: function () {
|
||||
return 'Recherche en cours…';
|
||||
},
|
||||
removeAllItems: function() {
|
||||
removeAllItems: function () {
|
||||
return 'Supprimer tous les éléments';
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import '../shared/polyfills';
|
||||
import Turbolinks from 'turbolinks';
|
||||
import Rails from '@rails/ujs';
|
||||
import * as ActiveStorage from '@rails/activestorage';
|
||||
import jQuery from 'jquery';
|
||||
|
@ -13,7 +12,6 @@ import '../shared/franceconnect';
|
|||
|
||||
// Start Rails helpers
|
||||
Rails.start();
|
||||
Turbolinks.start();
|
||||
ActiveStorage.start();
|
||||
|
||||
// Disable jQuery-driven animations during tests
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import '../shared/polyfills';
|
||||
import Turbolinks from 'turbolinks';
|
||||
import Rails from '@rails/ujs';
|
||||
import * as ActiveStorage from '@rails/activestorage';
|
||||
import '@rails/actiontext';
|
||||
|
@ -57,13 +56,10 @@ const DS = {
|
|||
|
||||
// Start Rails helpers
|
||||
Rails.start();
|
||||
Turbolinks.start();
|
||||
ActiveStorage.start();
|
||||
|
||||
// Expose globals
|
||||
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
|
||||
// eslint-disable-next-line no-undef
|
||||
|
|
|
@ -12,7 +12,7 @@ const ERROR_EVENT = 'direct-upload:error';
|
|||
const END_EVENT = 'direct-upload:end';
|
||||
|
||||
function addUploadEventListener(type, handler) {
|
||||
addEventListener(type, event => {
|
||||
addEventListener(type, (event) => {
|
||||
// Internet Explorer and Edge will sometime replay Javascript events
|
||||
// that were dispatched just before a page navigation (!), but without
|
||||
// the event payload.
|
||||
|
@ -43,7 +43,7 @@ addUploadEventListener(PROGRESS_EVENT, ({ detail: { id, progress } }) => {
|
|||
ProgressBar.progress(id, progress);
|
||||
});
|
||||
|
||||
addUploadEventListener(ERROR_EVENT, event => {
|
||||
addUploadEventListener(ERROR_EVENT, (event) => {
|
||||
let id = event.detail.id;
|
||||
let errorMsg = event.detail.error;
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ export default class Uploader {
|
|||
}
|
||||
|
||||
directUploadWillStoreFileWithXHR(xhr) {
|
||||
xhr.upload.addEventListener('progress', event =>
|
||||
xhr.upload.addEventListener('progress', (event) =>
|
||||
this.uploadRequestDidProgress(event)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ function initMap(element, { position }) {
|
|||
}
|
||||
|
||||
function toLatLngs({ coordinates }) {
|
||||
return coordinates.map(polygon =>
|
||||
polygon[0].map(point => L.GeoJSON.coordsToLatLng(point))
|
||||
return coordinates.map((polygon) =>
|
||||
polygon[0].map((point) => L.GeoJSON.coordsToLatLng(point))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ function findInput(selector) {
|
|||
}
|
||||
|
||||
function clearLayers(map) {
|
||||
map.eachLayer(layer => {
|
||||
map.eachLayer((layer) => {
|
||||
if (layer instanceof L.GeoJSON) {
|
||||
map.removeLayer(layer);
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ const RPG_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, {
|
|||
fillColor: '#31708f'
|
||||
});
|
||||
|
||||
delegate('click', '.carte.edit', event => {
|
||||
delegate('click', '.carte.edit', (event) => {
|
||||
const map = getCurrentMap(event.target);
|
||||
|
||||
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();
|
||||
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 { geometry } = event.params.data;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ function toggleElement(event) {
|
|||
function closeFCPopin(event) {
|
||||
event.preventDefault();
|
||||
fconnect.popin.className = 'fade-out';
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(fconnect.popin);
|
||||
}, 200);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ function openFCPopin() {
|
|||
|
||||
fconnect.popin.appendChild(iframe);
|
||||
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
fconnect.popin.className = 'fade-in';
|
||||
}, 200);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ var messageEvent = eventMethod == 'attachEvent' ? 'onmessage' : 'message';
|
|||
// Listen to message from child window
|
||||
eventer(
|
||||
messageEvent,
|
||||
function(e) {
|
||||
function (e) {
|
||||
var key = e.message ? 'message' : 'data';
|
||||
var data = e[key];
|
||||
if (data === 'close_popup') {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { fire } from '@utils';
|
||||
|
||||
addEventListener('turbolinks:load', function() {
|
||||
addEventListener('DOMContentLoaded', function () {
|
||||
fire(document, 'ds:page:update');
|
||||
});
|
||||
|
||||
addEventListener('ajax:success', function() {
|
||||
addEventListener('ajax:success', function () {
|
||||
fire(document, 'ds:page:update');
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ function clearDataset(event) {
|
|||
}
|
||||
|
||||
function toCamelCase(string) {
|
||||
return string.replace(dash, function(_, letter) {
|
||||
return string.replace(dash, function (_, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ import jQuery from 'jquery';
|
|||
// https://github.com/Sology/smart_listing/blob/master/app/assets/javascripts/smart_listing.coffee.erb#L9
|
||||
addEventListener('load', () => {
|
||||
const { href, handleRemote } = Rails;
|
||||
Rails.href = function(element) {
|
||||
Rails.href = function (element) {
|
||||
return element.href || href(element);
|
||||
};
|
||||
Rails.handleRemote = function(e) {
|
||||
Rails.handleRemote = function (e) {
|
||||
if (this instanceof HTMLElement) {
|
||||
handleRemote.call(this, e);
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ajax, delegate } from '@utils';
|
||||
|
||||
addEventListener('turbolinks:load', () => {
|
||||
addEventListener('DOMContentLoaded', () => {
|
||||
attachementPoller.deactivate();
|
||||
exportPoller.deactivate();
|
||||
|
||||
|
@ -24,7 +24,7 @@ addEventListener('export:update', ({ detail: { url } }) => {
|
|||
exportPoller.add(url);
|
||||
});
|
||||
|
||||
delegate('click', '[data-attachment-refresh]', event => {
|
||||
delegate('click', '[data-attachment-refresh]', (event) => {
|
||||
event.preventDefault();
|
||||
attachementPoller.check();
|
||||
});
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
// https://stackoverflow.com/questions/49614091/safari-11-1-ajax-xhr-form-submission-fails-when-inputtype-file-is-empty
|
||||
// https://github.com/rails/rails/issues/32440
|
||||
|
||||
document.addEventListener('ajax:before', function(e) {
|
||||
document.addEventListener('ajax:before', function (e) {
|
||||
let inputs = e.target.querySelectorAll('input[type="file"]:not([disabled])');
|
||||
inputs.forEach(function(input) {
|
||||
inputs.forEach(function (input) {
|
||||
if (input.files.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -15,11 +15,11 @@ document.addEventListener('ajax:before', function(e) {
|
|||
});
|
||||
|
||||
// You should call this by yourself when you aborted an ajax request by stopping a event in ajax:before hook.
|
||||
document.addEventListener('ajax:beforeSend', function(e) {
|
||||
document.addEventListener('ajax:beforeSend', function (e) {
|
||||
let inputs = e.target.querySelectorAll(
|
||||
'input[type="file"][data-safari-temp-disabled]'
|
||||
);
|
||||
inputs.forEach(function(input) {
|
||||
inputs.forEach(function (input) {
|
||||
input.removeAttribute('data-safari-temp-disabled');
|
||||
input.removeAttribute('disabled');
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import { delegate, toggle } from '@utils';
|
|||
|
||||
const TOGGLE_SOURCE_SELECTOR = '[data-toggle-target]';
|
||||
|
||||
delegate('click', TOGGLE_SOURCE_SELECTOR, evt => {
|
||||
delegate('click', TOGGLE_SOURCE_SELECTOR, (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const targetSelector = evt.target.dataset.toggleTarget;
|
||||
|
|
|
@ -25,23 +25,4 @@ if (enabled) {
|
|||
script.async = true;
|
||||
script.src = jsUrl;
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ const { key, enabled, user, environment, browser } = gon.sentry || {};
|
|||
if (enabled && key) {
|
||||
Sentry.init({ dsn: key, environment });
|
||||
|
||||
Sentry.configureScope(scope => {
|
||||
Sentry.configureScope((scope) => {
|
||||
scope.setUser(user);
|
||||
scope.setExtra('browser', browser.modern ? 'modern' : 'legacy');
|
||||
});
|
||||
|
||||
// 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;
|
||||
Sentry.captureException(error);
|
||||
});
|
||||
|
|
|
@ -46,7 +46,7 @@ export function removeClass(el, cssClass) {
|
|||
export function delegate(eventNames, selector, callback) {
|
||||
eventNames
|
||||
.split(' ')
|
||||
.forEach(eventName =>
|
||||
.forEach((eventName) =>
|
||||
Rails.delegate(document, selector, eventName, callback)
|
||||
);
|
||||
}
|
||||
|
@ -90,13 +90,13 @@ export function scrollToBottom(container) {
|
|||
}
|
||||
|
||||
export function on(selector, eventName, fn) {
|
||||
[...document.querySelectorAll(selector)].forEach(element =>
|
||||
element.addEventListener(eventName, event => fn(event, event.detail))
|
||||
[...document.querySelectorAll(selector)].forEach((element) =>
|
||||
element.addEventListener(eventName, (event) => fn(event, event.detail))
|
||||
);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -516,6 +516,7 @@ class Dossier < ApplicationRecord
|
|||
end
|
||||
|
||||
def after_repasser_en_instruction(instructeur)
|
||||
self.archived = false
|
||||
self.processed_at = nil
|
||||
self.motivation = nil
|
||||
attestation&.destroy
|
||||
|
|
|
@ -85,6 +85,6 @@
|
|||
- if @attestation_template.new_record? || !@attestation_template.activated
|
||||
%button.btn.btn-success Activer l'attestation
|
||||
- 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
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
target: "_blank"
|
||||
|
||||
:javascript
|
||||
document.addEventListener("turbolinks:load", function() {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
$crisp.push(["do", "trigger:run", ["admin-signup"]]);
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
- 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{ 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
|
||||
Publier
|
||||
- else
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
%h1= procedure_libelle @procedure
|
||||
= 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?
|
||||
|
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
%h1= procedure_libelle @procedure
|
||||
= 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?
|
||||
|
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
\-
|
||||
= 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'
|
||||
\-
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
%head
|
||||
%meta{ "http-equiv": "Content-Type", content: "text/html; charset=UTF-8" }
|
||||
%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" }
|
||||
= csrf_meta_tags
|
||||
|
||||
|
@ -15,9 +14,9 @@
|
|||
= favicon_link_tag(image_url("favicons/96x96.png"), type: "image/png", sizes: "96x96")
|
||||
|
||||
- packs = ['application', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
|
||||
= javascript_packs_with_chunks_tag *packs, defer: true, 'data-turbolinks-track': 'reload'
|
||||
= stylesheet_link_tag 'new_design/new_application', media: 'all', 'data-turbolinks-track': 'reload'
|
||||
= stylesheet_link_tag 'new_design/print', media: 'print', 'data-turbolinks-track': 'reload'
|
||||
= javascript_packs_with_chunks_tag *packs, defer: true
|
||||
= stylesheet_link_tag 'new_design/new_application', media: 'all'
|
||||
= stylesheet_link_tag 'new_design/print', media: 'print'
|
||||
|
||||
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
%html
|
||||
%head
|
||||
%meta{ :content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type" }/
|
||||
%meta{ name: "turbolinks-cache-control", content: "no-cache" }
|
||||
%title
|
||||
= t('dynamics.page_title')
|
||||
%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/96x96.png"), type: "image/png", sizes: "96x96")
|
||||
|
||||
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': "reload"
|
||||
= stylesheet_link_tag 'print', media: 'print', 'data-turbolinks-track': "reload"
|
||||
= stylesheet_link_tag 'application', media: 'all'
|
||||
= stylesheet_link_tag 'print', media: 'print'
|
||||
- packs = ['application-old', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
|
||||
= javascript_packs_with_chunks_tag *packs, defer: true, 'data-turbolinks-track': 'reload'
|
||||
= javascript_include_tag 'application', defer: true, 'data-turbolinks-track': 'reload'
|
||||
= javascript_packs_with_chunks_tag *packs, defer: true
|
||||
= javascript_include_tag 'application', defer: true
|
||||
= csrf_meta_tags
|
||||
= Gon::Base.render_data(camel_case: true, init: true)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
%li.footer-link
|
||||
= link_to "Nouveautés", "https://github.com/betagouv/demarches-simplifiees.fr/releases", :class => "footer-link", :title => "Nos nouveautés"
|
||||
%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
|
||||
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
|
||||
%li.footer-link
|
||||
|
|
53
package.json
53
package.json
|
@ -1,35 +1,35 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@babel/preset-react": "^7.8.3",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.26",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.12.0",
|
||||
"@fortawesome/react-fontawesome": "^0.1.8",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||
"@fortawesome/react-fontawesome": "^0.1.9",
|
||||
"@mapbox/mapbox-gl-draw": "^1.1.2",
|
||||
"@rails/actiontext": "^6.0.2-1",
|
||||
"@rails/activestorage": "^6.0.2-1",
|
||||
"@rails/ujs": "^6.0.2-1",
|
||||
"@rails/webpacker": "4.2.2",
|
||||
"@reach/combobox": "^0.10.0",
|
||||
"@sentry/browser": "^5.11.2",
|
||||
"@rails/actiontext": "^6.0.2-2",
|
||||
"@rails/activestorage": "^6.0.2-2",
|
||||
"@rails/ujs": "^6.0.2-2",
|
||||
"@rails/webpacker": "5.1.1",
|
||||
"@reach/combobox": "^0.10.1",
|
||||
"@sentry/browser": "^5.15.5",
|
||||
"@tmcw/togeojson": "^4.0.0",
|
||||
"@turf/area": "^6.0.1",
|
||||
"babel-plugin-macros": "^2.8.0",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||
"chartkick": "^3.2.0",
|
||||
"core-js": "^3.6.4",
|
||||
"core-js": "^3.6.5",
|
||||
"debounce": "^1.2.0",
|
||||
"dom4": "^2.1.5",
|
||||
"email-butler": "^1.0.13",
|
||||
"highcharts": "^8.0.0",
|
||||
"intersection-observer": "^0.7.0",
|
||||
"highcharts": "^8.0.4",
|
||||
"intersection-observer": "^0.10.0",
|
||||
"jquery": "^3.5.0",
|
||||
"leaflet": "^1.6.0",
|
||||
"leaflet-freedraw": "^2.12.0",
|
||||
"mapbox-gl": "^1.9.0",
|
||||
"mapbox-gl": "^1.10.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-intersection-observer": "^8.25.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-intersection-observer": "^8.26.2",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-mapbox-gl": "^4.8.3",
|
||||
"react-mapbox-gl-draw": "^2.0.4",
|
||||
|
@ -37,21 +37,20 @@
|
|||
"react-sortable-hoc": "^1.11.0",
|
||||
"react_ujs": "^2.6.1",
|
||||
"select2": "^4.0.13",
|
||||
"trix": "^1.2.2",
|
||||
"turbolinks": "^5.2.0",
|
||||
"trix": "^1.2.3",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eclint": "^2.8.1",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-config-prettier": "^6.10.0",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-react": "^7.18.0",
|
||||
"eslint-plugin-react-hooks": "^2.3.0",
|
||||
"prettier": "^1.19.1",
|
||||
"webpack-bundle-analyzer": "^3.6.0",
|
||||
"webpack-dev-server": "^3.10.0"
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-react": "^7.19.0",
|
||||
"eslint-plugin-react-hooks": "^3.0.0",
|
||||
"prettier": "^2.0.5",
|
||||
"webpack-bundle-analyzer": "^3.7.0",
|
||||
"webpack-dev-server": "^3.10.3"
|
||||
},
|
||||
"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)",
|
||||
|
|
|
@ -180,7 +180,11 @@ describe Admin::ProceduresController, type: :controller do
|
|||
expect(procedure.publiee?).to be_truthy
|
||||
expect(procedure.path).to eq(path)
|
||||
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'
|
||||
end
|
||||
end
|
||||
|
@ -193,13 +197,17 @@ describe Admin::ProceduresController, type: :controller do
|
|||
expect(procedure.publiee?).to be_truthy
|
||||
expect(procedure.path).to eq(path)
|
||||
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
|
||||
|
||||
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
|
||||
|
@ -285,8 +293,12 @@ describe Admin::ProceduresController, type: :controller do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ feature 'The routing', js: true do
|
|||
click_on 'suivi'
|
||||
click_on litteraire_user.email
|
||||
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')
|
||||
log_out
|
||||
|
||||
|
|
|
@ -1056,7 +1056,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
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(:last_operation) { dossier.dossier_operation_logs.last }
|
||||
|
||||
|
@ -1069,6 +1069,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
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.motivation).to be_nil }
|
||||
it { expect(dossier.attestation).to be_nil }
|
||||
|
|
Loading…
Reference in a new issue