commit
79e4fd90da
43 changed files with 740 additions and 364 deletions
|
@ -11,3 +11,7 @@
|
|||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.form [data-react-class='MapEditor'] [data-reach-combobox-input] {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -290,6 +290,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
[data-reach-combobox-input] {
|
||||
padding: 16px;
|
||||
width: 100%;
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
min-height: 62px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
[data-reach-combobox-input]:focus {
|
||||
border-color: $blue;
|
||||
}
|
||||
|
||||
.select2 {
|
||||
min-width: 50%;
|
||||
}
|
||||
|
@ -465,3 +479,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-reach-combobox-option] {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
[data-reach-combobox-option][aria-selected="true"] {
|
||||
background: $light-blue !important;
|
||||
color: $white;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@ class APIGeoTestController < ActionController::Base
|
|||
end
|
||||
|
||||
def communes
|
||||
render json: [{ nom: 'Ambléon' }]
|
||||
render json: [{ nom: 'Ambléon', code: '01006', codesPostaux: ['01300'] }]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module Instructeurs
|
|||
before_action :check_if_avis_revoked, only: [:show]
|
||||
before_action :redirect_if_no_sign_up_needed, only: [:sign_up]
|
||||
before_action :check_avis_exists_and_email_belongs_to_avis, only: [:sign_up, :create_instructeur]
|
||||
before_action :set_avis_and_dossier, only: [:show, :instruction, :messagerie, :create_commentaire, :update]
|
||||
before_action :set_avis_and_dossier, only: [:show, :instruction, :update]
|
||||
|
||||
A_DONNER_STATUS = 'a-donner'
|
||||
DONNES_STATUS = 'donnes'
|
||||
|
@ -53,23 +53,6 @@ module Instructeurs
|
|||
end
|
||||
end
|
||||
|
||||
def messagerie
|
||||
@commentaire = Commentaire.new
|
||||
end
|
||||
|
||||
def create_commentaire
|
||||
@commentaire = CommentaireService.build(current_instructeur, avis.dossier, commentaire_params)
|
||||
|
||||
if @commentaire.save
|
||||
@commentaire.dossier.update!(last_commentaire_updated_at: Time.zone.now)
|
||||
flash.notice = "Message envoyé"
|
||||
redirect_to messagerie_instructeur_avis_path(avis.procedure, avis)
|
||||
else
|
||||
flash.alert = @commentaire.errors.full_messages
|
||||
render :messagerie
|
||||
end
|
||||
end
|
||||
|
||||
def create_avis
|
||||
@procedure = Procedure.find(params[:procedure_id])
|
||||
if !feature_enabled_for?(:expert_not_allowed_to_invite, @procedure)
|
||||
|
|
|
@ -14,7 +14,7 @@ module Types
|
|||
|
||||
global_id_field :id
|
||||
field :source, GeoAreaSource, null: false
|
||||
field :geometry, Types::GeoJSON, null: false
|
||||
field :geometry, Types::GeoJSON, null: false, method: :safe_geometry
|
||||
|
||||
definition_methods do
|
||||
def resolve_type(object, context)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Chartkick from 'chartkick';
|
||||
import Highcharts from 'highcharts';
|
||||
import { toggle, delegate } from '@utils';
|
||||
import { toggle, delegate, fire } from '@utils';
|
||||
|
||||
export default function () {
|
||||
return null;
|
||||
|
@ -34,3 +34,4 @@ delegate('click', '[data-toggle-chart]', toggleChart);
|
|||
|
||||
Chartkick.use(Highcharts);
|
||||
window.Chartkick = Chartkick;
|
||||
fire(window, 'chartkick:ready');
|
||||
|
|
44
app/javascript/components/ComboAdresseSearch.js
Normal file
44
app/javascript/components/ComboAdresseSearch.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { ReactQueryCacheProvider } from 'react-query';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import ComboSearch from './ComboSearch';
|
||||
import { queryCache } from './shared/queryCache';
|
||||
|
||||
function ComboAdresseSearch({
|
||||
mandatory,
|
||||
placeholder,
|
||||
hiddenFieldId,
|
||||
onChange,
|
||||
transformResult = ({ properties: { label } }) => [label, label],
|
||||
allowInputValues = true
|
||||
}) {
|
||||
const transformResults = useCallback((_, { features }) => features);
|
||||
|
||||
return (
|
||||
<ReactQueryCacheProvider queryCache={queryCache}>
|
||||
<ComboSearch
|
||||
placeholder={placeholder}
|
||||
required={mandatory}
|
||||
hiddenFieldId={hiddenFieldId}
|
||||
onChange={onChange}
|
||||
allowInputValues={allowInputValues}
|
||||
scope="adresse"
|
||||
minimumInputLength={2}
|
||||
transformResult={transformResult}
|
||||
transformResults={transformResults}
|
||||
/>
|
||||
</ReactQueryCacheProvider>
|
||||
);
|
||||
}
|
||||
|
||||
ComboAdresseSearch.propTypes = {
|
||||
placeholder: PropTypes.string,
|
||||
mandatory: PropTypes.bool,
|
||||
hiddenFieldId: PropTypes.string,
|
||||
transformResult: PropTypes.func,
|
||||
allowInputValues: PropTypes.bool,
|
||||
onChange: PropTypes.func
|
||||
};
|
||||
|
||||
export default ComboAdresseSearch;
|
24
app/javascript/components/ComboCommunesSearch.js
Normal file
24
app/javascript/components/ComboCommunesSearch.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { ReactQueryCacheProvider } from 'react-query';
|
||||
|
||||
import ComboSearch from './ComboSearch';
|
||||
import { queryCache } from './shared/queryCache';
|
||||
|
||||
function ComboCommunesSearch(params) {
|
||||
return (
|
||||
<ReactQueryCacheProvider queryCache={queryCache}>
|
||||
<ComboSearch
|
||||
required={params.mandatory}
|
||||
hiddenFieldId={params.hiddenFieldId}
|
||||
scope="communes"
|
||||
minimumInputLength={2}
|
||||
transformResult={({ code, nom, codesPostaux }) => [
|
||||
code,
|
||||
`${nom} (${codesPostaux[0]})`
|
||||
]}
|
||||
/>
|
||||
</ReactQueryCacheProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComboCommunesSearch;
|
32
app/javascript/components/ComboDepartementsSearch.js
Normal file
32
app/javascript/components/ComboDepartementsSearch.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { ReactQueryCacheProvider } from 'react-query';
|
||||
import matchSorter from 'match-sorter';
|
||||
|
||||
import ComboSearch from './ComboSearch';
|
||||
import { queryCache } from './shared/queryCache';
|
||||
|
||||
const extraTerms = [{ code: '99', nom: 'Etranger' }];
|
||||
|
||||
function ComboDepartementsSearch(params) {
|
||||
const transformResults = useCallback((term, results) => [
|
||||
...results,
|
||||
...matchSorter(extraTerms, term, {
|
||||
keys: ['nom', 'code']
|
||||
})
|
||||
]);
|
||||
|
||||
return (
|
||||
<ReactQueryCacheProvider queryCache={queryCache}>
|
||||
<ComboSearch
|
||||
required={params.mandatory}
|
||||
hiddenFieldId={params.hiddenFieldId}
|
||||
scope="departements"
|
||||
minimumInputLength={1}
|
||||
transformResult={({ code, nom }) => [code, `${code} - ${nom}`]}
|
||||
transformResults={transformResults}
|
||||
/>
|
||||
</ReactQueryCacheProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComboDepartementsSearch;
|
21
app/javascript/components/ComboRegionsSearch.js
Normal file
21
app/javascript/components/ComboRegionsSearch.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import { ReactQueryCacheProvider } from 'react-query';
|
||||
|
||||
import ComboSearch from './ComboSearch';
|
||||
import { queryCache } from './shared/queryCache';
|
||||
|
||||
function ComboRegionsSearch(params) {
|
||||
return (
|
||||
<ReactQueryCacheProvider queryCache={queryCache}>
|
||||
<ComboSearch
|
||||
required={params.mandatory}
|
||||
hiddenFieldId={params.hiddenFieldId}
|
||||
scope="regions"
|
||||
minimumInputLength={0}
|
||||
transformResult={({ code, nom }) => [code, nom]}
|
||||
/>
|
||||
</ReactQueryCacheProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComboRegionsSearch;
|
129
app/javascript/components/ComboSearch.js
Normal file
129
app/javascript/components/ComboSearch.js
Normal file
|
@ -0,0 +1,129 @@
|
|||
import React, { useState, useMemo, useCallback, useRef } from 'react';
|
||||
import { useDebounce } from 'react-use';
|
||||
import { useQuery } from 'react-query';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxInput,
|
||||
ComboboxPopover,
|
||||
ComboboxList,
|
||||
ComboboxOption
|
||||
} from '@reach/combobox';
|
||||
import '@reach/combobox/styles.css';
|
||||
|
||||
function defaultTransformResults(_, results) {
|
||||
return results;
|
||||
}
|
||||
|
||||
function ComboSearch({
|
||||
placeholder,
|
||||
required,
|
||||
hiddenFieldId,
|
||||
onChange,
|
||||
scope,
|
||||
minimumInputLength,
|
||||
transformResult,
|
||||
allowInputValues = false,
|
||||
transformResults = defaultTransformResults
|
||||
}) {
|
||||
const label = scope;
|
||||
const hiddenField = useMemo(
|
||||
() => document.querySelector(`input[data-uuid="${hiddenFieldId}"]`),
|
||||
[hiddenFieldId]
|
||||
);
|
||||
const initialValue = hiddenField && hiddenField.value;
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('');
|
||||
const [value, setValue] = useState(initialValue);
|
||||
const resultsMap = useRef({});
|
||||
const setExternalValue = useCallback((value) => {
|
||||
if (hiddenField) {
|
||||
hiddenField.setAttribute('value', value);
|
||||
}
|
||||
if (onChange) {
|
||||
const result = resultsMap.current[value];
|
||||
onChange(value, result);
|
||||
}
|
||||
});
|
||||
|
||||
useDebounce(
|
||||
() => {
|
||||
setDebouncedSearchTerm(searchTerm);
|
||||
},
|
||||
300,
|
||||
[searchTerm]
|
||||
);
|
||||
|
||||
const handleOnChange = useCallback(
|
||||
({ target: { value } }) => {
|
||||
setValue(value);
|
||||
if (value.length >= minimumInputLength) {
|
||||
setSearchTerm(value.trim());
|
||||
if (allowInputValues) {
|
||||
setExternalValue(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
[minimumInputLength]
|
||||
);
|
||||
|
||||
const handleOnSelect = useCallback((value) => {
|
||||
setExternalValue(value);
|
||||
setValue(value);
|
||||
});
|
||||
|
||||
const { isSuccess, data } = useQuery([scope, debouncedSearchTerm], {
|
||||
enabled: !!debouncedSearchTerm,
|
||||
notifyOnStatusChange: false,
|
||||
refetchOnMount: false
|
||||
});
|
||||
const results = isSuccess ? transformResults(debouncedSearchTerm, data) : [];
|
||||
|
||||
return (
|
||||
<Combobox aria-label={label} onSelect={handleOnSelect}>
|
||||
<ComboboxInput
|
||||
placeholder={placeholder}
|
||||
onChange={handleOnChange}
|
||||
value={value}
|
||||
required={required}
|
||||
/>
|
||||
{isSuccess && (
|
||||
<ComboboxPopover className="shadow-popup">
|
||||
{results.length > 0 ? (
|
||||
<ComboboxList>
|
||||
{results.map((result) => {
|
||||
const [key, str] = transformResult(result);
|
||||
resultsMap.current[str] = result;
|
||||
return (
|
||||
<ComboboxOption
|
||||
key={key}
|
||||
value={str}
|
||||
data-option-value={str}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ComboboxList>
|
||||
) : (
|
||||
<span style={{ display: 'block', margin: 8 }}>
|
||||
Aucun résultat trouvé
|
||||
</span>
|
||||
)}
|
||||
</ComboboxPopover>
|
||||
)}
|
||||
</Combobox>
|
||||
);
|
||||
}
|
||||
|
||||
ComboSearch.propTypes = {
|
||||
placeholder: PropTypes.string,
|
||||
required: PropTypes.bool,
|
||||
hiddenFieldId: PropTypes.string,
|
||||
scope: PropTypes.string,
|
||||
minimumInputLength: PropTypes.number,
|
||||
transformResult: PropTypes.func,
|
||||
transformResults: PropTypes.func,
|
||||
allowInputValues: PropTypes.bool,
|
||||
onChange: PropTypes.func
|
||||
};
|
||||
|
||||
export default ComboSearch;
|
|
@ -1,88 +0,0 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { getJSON } from '@utils';
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxInput,
|
||||
ComboboxPopover,
|
||||
ComboboxList,
|
||||
ComboboxOption
|
||||
} from '@reach/combobox';
|
||||
import '@reach/combobox/styles.css';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
let cache = {};
|
||||
const useAddressSearch = (searchTerm) => {
|
||||
const [addresses, setAddresses] = useState([]);
|
||||
useEffect(() => {
|
||||
if (searchTerm.trim() !== '') {
|
||||
let isFresh = true;
|
||||
fetchAddresses(searchTerm).then((addresses) => {
|
||||
if (isFresh) setAddresses(addresses);
|
||||
});
|
||||
return () => (isFresh = false);
|
||||
}
|
||||
}, [searchTerm]);
|
||||
return addresses;
|
||||
};
|
||||
|
||||
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) => {
|
||||
if (result) {
|
||||
cache[value] = result;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
const SearchInput = ({ getCoords }) => {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const addresses = useAddressSearch(searchTerm);
|
||||
const handleSearchTermChange = (event) => {
|
||||
setSearchTerm(event.target.value);
|
||||
};
|
||||
return (
|
||||
<Combobox aria-label="addresses">
|
||||
<ComboboxInput
|
||||
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
|
||||
className="address-search-input"
|
||||
style={{
|
||||
font: 'inherit',
|
||||
padding: '.25rem .5rem',
|
||||
width: '100%',
|
||||
minHeight: '62px'
|
||||
}}
|
||||
onChange={handleSearchTermChange}
|
||||
/>
|
||||
{addresses.features && (
|
||||
<ComboboxPopover className="shadow-popup">
|
||||
{addresses.features.length > 0 ? (
|
||||
<ComboboxList>
|
||||
{addresses.features.map((feature) => {
|
||||
const str = `${feature.properties.name}, ${feature.properties.city}`;
|
||||
return (
|
||||
<ComboboxOption
|
||||
onClick={() => getCoords(feature.geometry.coordinates)}
|
||||
key={str}
|
||||
value={str}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ComboboxList>
|
||||
) : (
|
||||
<span style={{ display: 'block', margin: 8 }}>Aucun résultat</span>
|
||||
)}
|
||||
</ComboboxPopover>
|
||||
)}
|
||||
</Combobox>
|
||||
);
|
||||
};
|
||||
|
||||
SearchInput.propTypes = {
|
||||
getCoords: PropTypes.func
|
||||
};
|
||||
|
||||
export default SearchInput;
|
|
@ -9,7 +9,7 @@ import { getJSON, ajax, fire } from '@utils';
|
|||
|
||||
import { getMapStyle, SwitchMapStyle } from '../MapStyles';
|
||||
|
||||
import SearchInput from './SearchInput';
|
||||
import ComboAdresseSearch from '../ComboAdresseSearch';
|
||||
import {
|
||||
polygonCadastresFill,
|
||||
polygonCadastresLine,
|
||||
|
@ -279,9 +279,11 @@ function MapEditor({ featureCollection, url, preview, options }) {
|
|||
marginBottom: '50px'
|
||||
}}
|
||||
>
|
||||
<SearchInput
|
||||
getCoords={(searchTerm) => {
|
||||
setCoords(searchTerm);
|
||||
<ComboAdresseSearch
|
||||
placeholder="Rechercher une adresse : saisissez au moins 2 caractères"
|
||||
allowInputValues={false}
|
||||
onChange={(_, { geometry: { coordinates } }) => {
|
||||
setCoords(coordinates);
|
||||
setZoom([17]);
|
||||
}}
|
||||
/>
|
||||
|
|
6
app/javascript/components/Trix.js
Normal file
6
app/javascript/components/Trix.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import 'trix';
|
||||
import '@rails/actiontext';
|
||||
|
||||
export default function () {
|
||||
return null;
|
||||
}
|
39
app/javascript/components/shared/queryCache.js
Normal file
39
app/javascript/components/shared/queryCache.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { QueryCache } from 'react-query';
|
||||
import { isNumeric } from '@utils';
|
||||
|
||||
const { api_geo_url, api_adresse_url } = gon.autocomplete || {};
|
||||
|
||||
export const queryCache = new QueryCache({
|
||||
defaultConfig: {
|
||||
queries: {
|
||||
queryFn: defaultQueryFn
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function buildURL(scope, term) {
|
||||
if (scope === 'adresse') {
|
||||
return `${api_adresse_url}/search?q=${term}&limit=5`;
|
||||
} else if (isNumeric(term)) {
|
||||
const code = term.padStart(2, '0');
|
||||
return `${api_geo_url}/${scope}?code=${code}&limit=5`;
|
||||
}
|
||||
return `${api_geo_url}/${scope}?nom=${term}&limit=5`;
|
||||
}
|
||||
|
||||
function buildOptions() {
|
||||
if (window.AbortController) {
|
||||
const controller = new AbortController();
|
||||
const signal = controller.signal;
|
||||
return [{ signal }, controller];
|
||||
}
|
||||
return [{}, null];
|
||||
}
|
||||
|
||||
async function defaultQueryFn(scope, term) {
|
||||
const url = buildURL(scope, term);
|
||||
const [options, controller] = buildOptions();
|
||||
const promise = fetch(url, options).then((response) => response.json());
|
||||
promise.cancel = () => controller && controller.abort();
|
||||
return promise;
|
||||
}
|
3
app/javascript/loaders/ComboAdresseSearch.js
Normal file
3
app/javascript/loaders/ComboAdresseSearch.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/ComboAdresseSearch'));
|
3
app/javascript/loaders/ComboCommunesSearch.js
Normal file
3
app/javascript/loaders/ComboCommunesSearch.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/ComboCommunesSearch'));
|
3
app/javascript/loaders/ComboDepartementsSearch.js
Normal file
3
app/javascript/loaders/ComboDepartementsSearch.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/ComboDepartementsSearch'));
|
3
app/javascript/loaders/ComboRegionsSearch.js
Normal file
3
app/javascript/loaders/ComboRegionsSearch.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/ComboRegionsSearch'));
|
3
app/javascript/loaders/Trix.js
Normal file
3
app/javascript/loaders/Trix.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/Trix'));
|
41
app/javascript/new_design/chartkick.js
Normal file
41
app/javascript/new_design/chartkick.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Ruby chartkick helper implementation assumes Chartkick is already loaded.
|
||||
// It has no way to delay execution. So we wrap all the Chartkick classes
|
||||
// to queue rendering for when Chartkick is loaded.
|
||||
|
||||
class AreaChart {
|
||||
constructor(...args) {
|
||||
charts.add(['AreaChart', args]);
|
||||
}
|
||||
}
|
||||
|
||||
class PieChart {
|
||||
constructor(...args) {
|
||||
charts.add(['PieChart', args]);
|
||||
}
|
||||
}
|
||||
|
||||
class LineChart {
|
||||
constructor(...args) {
|
||||
charts.add(['LineChart', args]);
|
||||
}
|
||||
}
|
||||
|
||||
class ColumnChart {
|
||||
constructor(...args) {
|
||||
charts.add(['ColumnChart', args]);
|
||||
}
|
||||
}
|
||||
|
||||
const charts = new Set();
|
||||
|
||||
function initialize() {
|
||||
for (const [ChartType, args] of charts) {
|
||||
new window.Chartkick[ChartType](...args);
|
||||
}
|
||||
charts.clear();
|
||||
}
|
||||
|
||||
if (!window.Chartkick) {
|
||||
window.Chartkick = { AreaChart, PieChart, LineChart, ColumnChart };
|
||||
addEventListener('chartkick:ready', initialize);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { scrollTo, scrollToBottom } from '@utils';
|
||||
|
||||
export function scrollMessagerie() {
|
||||
function scrollMessagerie() {
|
||||
const ul = document.querySelector('.messagerie ul');
|
||||
|
||||
if (ul) {
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import $ from 'jquery';
|
||||
import 'select2';
|
||||
import { isNumeric } from '@utils';
|
||||
|
||||
const { api_geo_url, api_adresse_url } = gon.autocomplete || {};
|
||||
|
||||
const language = {
|
||||
errorLoading: function () {
|
||||
|
@ -50,94 +47,6 @@ const baseOptions = {
|
|||
width: '100%'
|
||||
};
|
||||
|
||||
const baseAjaxOptions = {
|
||||
delay: 250,
|
||||
timeout: 10 * 1000, // 10 sec
|
||||
cache: true,
|
||||
data({ term: nom }) {
|
||||
return {
|
||||
nom,
|
||||
fields: 'nom,code'
|
||||
};
|
||||
},
|
||||
processResults(data) {
|
||||
return {
|
||||
results: data.map(({ nom }) => ({ id: nom, text: nom }))
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const regionsOptions = {
|
||||
...baseOptions,
|
||||
minimumInputLength: 2,
|
||||
ajax: { url: `${api_geo_url}/regions`, ...baseAjaxOptions }
|
||||
};
|
||||
|
||||
const communesOptions = {
|
||||
...baseOptions,
|
||||
minimumInputLength: 2,
|
||||
ajax: { url: `${api_geo_url}/communes`, ...baseAjaxOptions }
|
||||
};
|
||||
|
||||
const etranger99 = { id: '99 - Étranger', text: '99 - Étranger' };
|
||||
const departementsOptions = {
|
||||
...baseOptions,
|
||||
minimumInputLength: 1,
|
||||
ajax: {
|
||||
...baseAjaxOptions,
|
||||
url: `${api_geo_url}/departements`,
|
||||
data({ term }) {
|
||||
const data = { fields: 'nom,code' };
|
||||
|
||||
if (isNumeric(term)) {
|
||||
data.code = term.trim().padStart(2, '0');
|
||||
} else {
|
||||
data.nom = term;
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
processResults(data) {
|
||||
return {
|
||||
results: data
|
||||
.map(({ nom, code }) => ({
|
||||
id: `${code} - ${nom}`,
|
||||
text: `${code} - ${nom}`
|
||||
}))
|
||||
.concat([etranger99])
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const adresseOptions = {
|
||||
...baseOptions,
|
||||
minimumInputLength: 2,
|
||||
ajax: {
|
||||
...baseAjaxOptions,
|
||||
url: `${api_adresse_url}/search`,
|
||||
data({ term: q }) {
|
||||
return {
|
||||
q,
|
||||
limit: 5
|
||||
};
|
||||
},
|
||||
processResults(data) {
|
||||
let r = data.features.map(({ properties: { label }, geometry }) => ({
|
||||
id: label,
|
||||
text: label,
|
||||
geometry
|
||||
}));
|
||||
// Allow the user to select an arbitrary address missing from the results,
|
||||
// by adding the plain-text query to the list of results.
|
||||
r.unshift({ id: data.query, text: data.query });
|
||||
return {
|
||||
results: r
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const templateOption = ({ text }) =>
|
||||
$(
|
||||
`<span class="custom-select2-option"><span class="icon person"></span>${text}</span>`
|
||||
|
@ -145,10 +54,6 @@ const templateOption = ({ text }) =>
|
|||
|
||||
addEventListener('ds:page:update', () => {
|
||||
$('select.select2').select2(baseOptions);
|
||||
$('select.select2.departements').select2(departementsOptions);
|
||||
$('select.select2.regions').select2(regionsOptions);
|
||||
$('select.select2.communes').select2(communesOptions);
|
||||
$('select.select2.adresse').select2(adresseOptions);
|
||||
|
||||
$('.columns-form select.select2-limited').select2({
|
||||
width: '300px',
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import '../shared/polyfills';
|
||||
import Rails from '@rails/ujs';
|
||||
import * as ActiveStorage from '@rails/activestorage';
|
||||
import 'trix';
|
||||
import '@rails/actiontext';
|
||||
import 'whatwg-fetch'; // window.fetch polyfill
|
||||
import ReactRailsUJS from 'react_ujs';
|
||||
|
||||
|
@ -15,6 +13,7 @@ import '../shared/remote-input';
|
|||
import '../shared/franceconnect';
|
||||
import '../shared/toggle-target';
|
||||
|
||||
import '../new_design/chartkick';
|
||||
import '../new_design/dropdown';
|
||||
import '../new_design/form-validation';
|
||||
import '../new_design/procedure-context';
|
||||
|
@ -29,14 +28,15 @@ import '../new_design/champs/carte';
|
|||
import '../new_design/champs/linked-drop-down-list';
|
||||
import '../new_design/champs/repetition';
|
||||
|
||||
import { toggleCondidentielExplanation } from '../new_design/avis';
|
||||
import { scrollMessagerie } from '../new_design/messagerie';
|
||||
import {
|
||||
toggleCondidentielExplanation,
|
||||
replaceSemicolonByComma
|
||||
} from '../new_design/avis';
|
||||
import {
|
||||
showMotivation,
|
||||
motivationCancel,
|
||||
showImportJustificatif
|
||||
} from '../new_design/state-button';
|
||||
import { replaceSemicolonByComma } from '../new_design/avis';
|
||||
import {
|
||||
acceptEmailSuggestion,
|
||||
discardEmailSuggestionBox
|
||||
|
@ -46,7 +46,6 @@ import {
|
|||
const DS = {
|
||||
fire: (eventName, data) => Rails.fire(document, eventName, data),
|
||||
toggleCondidentielExplanation,
|
||||
scrollMessagerie,
|
||||
showMotivation,
|
||||
motivationCancel,
|
||||
showImportJustificatif,
|
||||
|
|
|
@ -1,26 +1,5 @@
|
|||
import Rails from '@rails/ujs';
|
||||
import jQuery from 'jquery';
|
||||
|
||||
// `smart_listing` gem is overriding `$.rails.href` method. When using newer
|
||||
// jQuery-less version of rails-ujs it breaks.
|
||||
// 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) {
|
||||
return element.href || href(element);
|
||||
};
|
||||
Rails.handleRemote = function (e) {
|
||||
if (this instanceof HTMLElement) {
|
||||
handleRemote.call(this, e);
|
||||
} else {
|
||||
let element = e.find('[data-remote]')[0];
|
||||
let event = new CustomEvent('click');
|
||||
Object.defineProperty(event, 'target', { value: element });
|
||||
return handleRemote.call(element, event);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// rails-ujs installs CSRFProtection for its own ajax implementation. We might need
|
||||
// CSRFProtection for jQuery initiated requests. This code is from jquery-ujs.
|
||||
jQuery.ajaxPrefilter((options, originalOptions, xhr) => {
|
||||
|
|
|
@ -49,7 +49,7 @@ class GeoArea < ApplicationRecord
|
|||
def to_feature
|
||||
{
|
||||
type: 'Feature',
|
||||
geometry: geometry,
|
||||
geometry: safe_geometry,
|
||||
properties: properties.symbolize_keys.merge(
|
||||
source: source,
|
||||
area: area,
|
||||
|
@ -61,6 +61,10 @@ class GeoArea < ApplicationRecord
|
|||
}
|
||||
end
|
||||
|
||||
def safe_geometry
|
||||
RGeo::GeoJSON.encode(rgeo_geometry)
|
||||
end
|
||||
|
||||
def rgeo_geometry
|
||||
RGeo::GeoJSON.decode(geometry.to_json, geo_factory: RGeo::Geographic.simple_mercator_factory)
|
||||
rescue RGeo::Error::InvalidGeometry
|
||||
|
|
|
@ -13,7 +13,7 @@ class ChampSerializer < ActiveModel::Serializer
|
|||
def value
|
||||
case object
|
||||
when GeoArea
|
||||
object.geometry
|
||||
object.safe_geometry
|
||||
else
|
||||
object.for_api
|
||||
end
|
||||
|
|
|
@ -20,6 +20,10 @@ class GeoAreaSerializer < ActiveModel::Serializer
|
|||
attribute :surface, if: :include_parcelle_agricole?
|
||||
attribute :bio, if: :include_parcelle_agricole?
|
||||
|
||||
def geometry
|
||||
object.safe_geometry
|
||||
end
|
||||
|
||||
def include_cadastre?
|
||||
object.source == GeoArea.sources.fetch(:cadastre)
|
||||
end
|
||||
|
|
|
@ -8,4 +8,3 @@
|
|||
%ul.tabs
|
||||
= dynamic_tab_item('Demande', instructeur_avis_path(avis.procedure, avis))
|
||||
= dynamic_tab_item('Avis', instruction_instructeur_avis_path(avis.procedure, avis), notification: avis.answer.blank?)
|
||||
= dynamic_tab_item('Messagerie', messagerie_instructeur_avis_path(avis.procedure, avis))
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
- content_for(:title, "Messagerie · Dossier nº #{@dossier.id} (#{@dossier.owner_name})")
|
||||
|
||||
= render partial: 'header', locals: { avis: @avis, dossier: @dossier }
|
||||
|
||||
= render partial: "shared/dossiers/messagerie", locals: { dossier: @dossier, connected_user: current_instructeur, messagerie_seen_at: nil, new_commentaire: @commentaire, form_url: commentaire_instructeur_avis_path(@avis) }
|
|
@ -15,6 +15,11 @@
|
|||
|
||||
- packs = ['application', 'track', administrateur_signed_in? ? 'track-admin' : nil].compact
|
||||
= javascript_packs_with_chunks_tag *packs, defer: true
|
||||
|
||||
= preload_link_tag(asset_url("Muli-Regular.woff"))
|
||||
= preload_link_tag(asset_url("Muli-Bold.woff"))
|
||||
= preload_link_tag(asset_url("Muli-Italic.woff"))
|
||||
|
||||
= stylesheet_link_tag 'new_design/new_application', media: 'all'
|
||||
= stylesheet_link_tag 'new_design/print', media: 'print'
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
-# Load Trix lazily, by using our React lazy-loader.
|
||||
-# (Trix itself doesn't use React though)
|
||||
= react_component('Trix')
|
||||
|
||||
= f.label :subject do
|
||||
Objet de l'email
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
= form.select :value, [champ.value].compact,
|
||||
{ include_blank: true },
|
||||
required: champ.mandatory?,
|
||||
class: 'select2 adresse'
|
||||
- hidden_field_id = SecureRandom.uuid
|
||||
= form.hidden_field :value, { data: { uuid: hidden_field_id } }
|
||||
= react_component("ComboAdresseSearch", mandatory: champ.mandatory?, hiddenFieldId: hidden_field_id)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
= form.select :value, [champ.value].compact,
|
||||
{ include_blank: true },
|
||||
required: champ.mandatory?,
|
||||
class: 'select2 communes'
|
||||
- hidden_field_id = SecureRandom.uuid
|
||||
= form.hidden_field :value, { data: { uuid: hidden_field_id } }
|
||||
= react_component("ComboCommunesSearch", mandatory: champ.mandatory?, hiddenFieldId: hidden_field_id)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
= form.select :value, [champ.value].compact,
|
||||
{ include_blank: true },
|
||||
required: champ.mandatory?,
|
||||
class: 'select2 departements'
|
||||
- hidden_field_id = SecureRandom.uuid
|
||||
= form.hidden_field :value, { data: { uuid: hidden_field_id } }
|
||||
= react_component("ComboDepartementsSearch", mandatory: champ.mandatory?, hiddenFieldId: hidden_field_id)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
= form.select :value, [champ.value].compact,
|
||||
{ include_blank: true },
|
||||
required: champ.mandatory?,
|
||||
class: 'select2 regions'
|
||||
- hidden_field_id = SecureRandom.uuid
|
||||
= form.hidden_field :value, { data: { uuid: hidden_field_id } }
|
||||
= react_component("ComboRegionsSearch", mandatory: champ.mandatory?, hiddenFieldId: hidden_field_id)
|
||||
|
|
|
@ -300,7 +300,6 @@ Rails.application.routes.draw do
|
|||
get '', action: 'procedure', on: :collection, as: :procedure
|
||||
member do
|
||||
get 'instruction'
|
||||
get 'messagerie'
|
||||
post 'commentaire' => 'avis#create_commentaire'
|
||||
post 'avis' => 'avis#create_avis'
|
||||
patch 'revoquer'
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"intersection-observer": "^0.10.0",
|
||||
"jquery": "^3.5.1",
|
||||
"mapbox-gl": "^1.11.1",
|
||||
"match-sorter": "^4.2.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
|
@ -30,8 +31,10 @@
|
|||
"react-loadable": "^5.5.0",
|
||||
"react-mapbox-gl": "^4.8.6",
|
||||
"react-mapbox-gl-draw": "^2.0.4",
|
||||
"react-query": "^2.23.1",
|
||||
"react-scroll-to-component": "^1.0.2",
|
||||
"react-sortable-hoc": "^1.11.0",
|
||||
"react-use": "^15.3.4",
|
||||
"react_ujs": "^2.6.1",
|
||||
"select2": "^4.0.13",
|
||||
"trix": "^1.2.3",
|
||||
|
|
|
@ -65,14 +65,6 @@ describe Instructeurs::AvisController, type: :controller do
|
|||
it { expect(assigns(:dossier)).to eq(dossier) }
|
||||
end
|
||||
|
||||
describe '#messagerie' do
|
||||
before { get :messagerie, params: { id: avis_without_answer.id, procedure_id: procedure.id } }
|
||||
|
||||
it { expect(response).to have_http_status(:success) }
|
||||
it { expect(assigns(:avis)).to eq(avis_without_answer) }
|
||||
it { expect(assigns(:dossier)).to eq(dossier) }
|
||||
end
|
||||
|
||||
describe '#bilans_bdf' do
|
||||
before { get :bilans_bdf, params: { id: avis_without_answer.id, procedure_id: procedure.id } }
|
||||
|
||||
|
@ -118,40 +110,6 @@ describe Instructeurs::AvisController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#create_commentaire' do
|
||||
let(:file) { nil }
|
||||
let(:scan_result) { true }
|
||||
let(:now) { Time.zone.parse("14/07/1789") }
|
||||
|
||||
subject { post :create_commentaire, params: { id: avis_without_answer.id, procedure_id: procedure.id, commentaire: { body: 'commentaire body', piece_jointe: file } } }
|
||||
|
||||
before do
|
||||
allow(ClamavService).to receive(:safe_file?).and_return(scan_result)
|
||||
Timecop.freeze(now)
|
||||
end
|
||||
|
||||
after { Timecop.return }
|
||||
|
||||
it do
|
||||
subject
|
||||
|
||||
expect(response).to redirect_to(messagerie_instructeur_avis_path(avis_without_answer.procedure, avis_without_answer))
|
||||
expect(dossier.commentaires.map(&:body)).to match(['commentaire body'])
|
||||
expect(dossier.reload.last_commentaire_updated_at).to eq(now)
|
||||
end
|
||||
|
||||
context "with a file" do
|
||||
let(:file) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
||||
|
||||
it do
|
||||
subject
|
||||
expect(Commentaire.last.piece_jointe.filename).to eq("piece_justificative_0.pdf")
|
||||
end
|
||||
|
||||
it { expect { subject }.to change(Commentaire, :count).by(1) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#expert_cannot_invite_another_expert' do
|
||||
let!(:previous_avis) { Avis.create(dossier: dossier, claimant: claimant, instructeur: instructeur, confidentiel: previous_avis_confidentiel) }
|
||||
let(:previous_avis_confidentiel) { false }
|
||||
|
|
|
@ -57,6 +57,71 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :polygon_with_extra_coordinate do
|
||||
geometry do
|
||||
{
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[2.428439855575562, 46.538476837725796, 0],
|
||||
[2.4284291267395024, 46.53842148758162, 0],
|
||||
[2.4282521009445195, 46.53841410755813, 0],
|
||||
[2.42824137210846, 46.53847314771794, 0],
|
||||
[2.428284287452698, 46.53847314771794, 0],
|
||||
[2.428364753723145, 46.538487907747864, 0],
|
||||
[2.4284291267395024, 46.538491597754714, 0],
|
||||
[2.428439855575562, 46.538476837725796, 0]
|
||||
]
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
trait :invalid_multi_polygon do
|
||||
geometry do
|
||||
{
|
||||
"type": "MultiPolygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
[5.894422531127931, 48.22810341752755],
|
||||
[5.893049240112306, 48.22427237832278],
|
||||
[5.892534255981446, 48.22593062452037],
|
||||
[5.892791748046875, 48.2260449843468],
|
||||
[5.894422531127931, 48.229933066408215],
|
||||
[5.894422531127931, 48.22810341752755]
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
[5.8950233459472665, 48.229933066408215],
|
||||
[5.893478393554688, 48.228961073585126],
|
||||
[5.892791748046875, 48.228903896961775],
|
||||
[5.892705917358398, 48.230390468407535],
|
||||
[5.8950233459472665, 48.229933066408215]
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
[5.893220901489259, 48.229246955743626],
|
||||
[5.893392562866212, 48.22884672027457],
|
||||
[5.892705917358398, 48.22878954352343],
|
||||
[5.892019271850587, 48.22856083588024],
|
||||
[5.892019271850587, 48.2277031731152],
|
||||
[5.890989303588868, 48.22787470681807],
|
||||
[5.889959335327149, 48.22787470681807],
|
||||
[5.890560150146485, 48.22838930447709],
|
||||
[5.890645980834962, 48.22878954352343],
|
||||
[5.890989303588868, 48.229018250144584],
|
||||
[5.892362594604493, 48.22930413198368],
|
||||
[5.893220901489259, 48.229246955743626]
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
trait :line_string do
|
||||
geometry do
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ feature 'The user' do
|
|||
let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) }
|
||||
let(:user_dossier) { user.dossiers.first }
|
||||
|
||||
scenario 'fill a dossier', js: true, vcr: { cassette_name: 'api_geo_departements_regions_et_communes' } do
|
||||
scenario 'fill a dossier', js: true do
|
||||
log_in(user, procedure)
|
||||
|
||||
fill_individual
|
||||
|
@ -30,13 +30,10 @@ feature 'The user' do
|
|||
select('AUSTRALIE', from: 'pays')
|
||||
|
||||
select_champ_geo('regions', 'Ma', 'Martinique')
|
||||
select('Martinique', from: 'regions')
|
||||
|
||||
select_champ_geo('departements', 'Ai', '02 - Aisne')
|
||||
select('02 - Aisne', from: 'departements')
|
||||
|
||||
select_champ_geo('communes', 'Am', 'Ambléon')
|
||||
select('Ambléon', from: 'communes')
|
||||
select_champ_geo('communes', 'Ambl', 'Ambléon (01300)')
|
||||
|
||||
check('engagement')
|
||||
fill_in('dossier_link', with: '123')
|
||||
|
@ -64,7 +61,7 @@ feature 'The user' do
|
|||
expect(champ_value_for('pays')).to eq('AUSTRALIE')
|
||||
expect(champ_value_for('regions')).to eq('Martinique')
|
||||
expect(champ_value_for('departements')).to eq('02 - Aisne')
|
||||
expect(champ_value_for('communes')).to eq('Ambléon')
|
||||
expect(champ_value_for('communes')).to eq('Ambléon (01300)')
|
||||
expect(champ_value_for('engagement')).to eq('on')
|
||||
expect(champ_value_for('dossier_link')).to eq('123')
|
||||
expect(champ_value_for('piece_justificative')).to be_nil # antivirus hasn't approved the file yet
|
||||
|
@ -87,9 +84,9 @@ feature 'The user' do
|
|||
expect(page).to have_selected_value('simple_choice_drop_down_list_long', selected: 'bravo')
|
||||
expect(page).to have_selected_value('multiple_choice_drop_down_list_long', selected: ['alpha', 'charly'])
|
||||
expect(page).to have_selected_value('pays', selected: 'AUSTRALIE')
|
||||
expect(page).to have_selected_value('regions', selected: 'Martinique')
|
||||
expect(page).to have_selected_value('departements', selected: '02 - Aisne')
|
||||
expect(page).to have_selected_value('communes', selected: 'Ambléon')
|
||||
expect(page).to have_hidden_field('regions', with: 'Martinique')
|
||||
expect(page).to have_hidden_field('departements', with: '02 - Aisne')
|
||||
expect(page).to have_hidden_field('communes', with: 'Ambléon (01300)')
|
||||
expect(page).to have_checked_field('engagement')
|
||||
expect(page).to have_field('dossier_link', with: '123')
|
||||
expect(page).to have_text('file.pdf')
|
||||
|
@ -321,6 +318,10 @@ feature 'The user' do
|
|||
e.sibling('.datetime').first('select')[:id][0..-4]
|
||||
end
|
||||
|
||||
def have_hidden_field(libelle, with:)
|
||||
have_css("##{form_id_for(libelle)}[value=\"#{with}\"]")
|
||||
end
|
||||
|
||||
def champ_value_for(libelle)
|
||||
champs = user_dossier.champs
|
||||
champs.find { |c| c.libelle == libelle }.value
|
||||
|
@ -351,10 +352,12 @@ feature 'The user' do
|
|||
end
|
||||
|
||||
def select_champ_geo(champ, fill_with, value)
|
||||
find(".editable-champ-#{champ} .select2-container").click
|
||||
id = find('.select2-container--open [role=listbox]')[:id]
|
||||
find("[aria-controls=#{id}]").fill_in with: fill_with
|
||||
expect(page).to have_content(value)
|
||||
find('li', text: value).click
|
||||
input = find("input[aria-label=#{champ}")
|
||||
input.click
|
||||
input.fill_in with: fill_with
|
||||
selector = "li[data-option-value=\"#{value}\"]"
|
||||
find(selector).click
|
||||
expect(page).to have_css(selector)
|
||||
expect(page).to have_hidden_field(champ, with: value)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,53 +24,38 @@ RSpec.describe GeoArea, type: :model do
|
|||
end
|
||||
|
||||
describe '#rgeo_geometry' do
|
||||
let(:geo_area) { build(:geo_area, geometry: geometry) }
|
||||
|
||||
context 'invalid' do
|
||||
let(:geometry) do
|
||||
let(:geo_area) { build(:geo_area, :polygon) }
|
||||
let(:polygon) do
|
||||
{
|
||||
"type" => "MultiPolygon",
|
||||
"type" => "Polygon",
|
||||
"coordinates" => [
|
||||
[
|
||||
[
|
||||
[5.894422531127931, 48.22810341752755],
|
||||
[5.893049240112306, 48.22427237832278],
|
||||
[5.892534255981446, 48.22593062452037],
|
||||
[5.892791748046875, 48.2260449843468],
|
||||
[5.894422531127931, 48.229933066408215],
|
||||
[5.894422531127931, 48.22810341752755]
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
[5.8950233459472665, 48.229933066408215],
|
||||
[5.893478393554688, 48.228961073585126],
|
||||
[5.892791748046875, 48.228903896961775],
|
||||
[5.892705917358398, 48.230390468407535],
|
||||
[5.8950233459472665, 48.229933066408215]
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
[5.893220901489259, 48.229246955743626],
|
||||
[5.893392562866212, 48.22884672027457],
|
||||
[5.892705917358398, 48.22878954352343],
|
||||
[5.892019271850587, 48.22856083588024],
|
||||
[5.892019271850587, 48.2277031731152],
|
||||
[5.890989303588868, 48.22787470681807],
|
||||
[5.889959335327149, 48.22787470681807],
|
||||
[5.890560150146485, 48.22838930447709],
|
||||
[5.890645980834962, 48.22878954352343],
|
||||
[5.890989303588868, 48.229018250144584],
|
||||
[5.892362594604493, 48.22930413198368],
|
||||
[5.893220901489259, 48.229246955743626]
|
||||
]
|
||||
[2.428439855575562, 46.538476837725796],
|
||||
[2.4284291267395024, 46.53842148758162],
|
||||
[2.4282521009445195, 46.53841410755813],
|
||||
[2.42824137210846, 46.53847314771794],
|
||||
[2.428284287452698, 46.53847314771794],
|
||||
[2.428364753723145, 46.538487907747864],
|
||||
[2.4284291267395024, 46.538491597754714],
|
||||
[2.428439855575562, 46.538476837725796]
|
||||
]
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
it { expect(geo_area.geometry).to eq(polygon) }
|
||||
|
||||
context 'invalid' do
|
||||
let(:geo_area) { build(:geo_area, :invalid_multi_polygon) }
|
||||
|
||||
it { expect(geo_area.rgeo_geometry).to be_nil }
|
||||
end
|
||||
|
||||
context 'polygon_with_extra_coordinate' do
|
||||
let(:geo_area) { build(:geo_area, :polygon_with_extra_coordinate) }
|
||||
|
||||
it { expect(geo_area.geometry).not_to eq(polygon) }
|
||||
it { expect(geo_area.safe_geometry).to eq(polygon) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
206
yarn.lock
206
yarn.lock
|
@ -898,6 +898,13 @@
|
|||
core-js-pure "^3.0.0"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.5.5":
|
||||
version "7.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
||||
integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.2.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
version "7.9.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
|
||||
|
@ -1904,6 +1911,11 @@
|
|||
"@types/istanbul-lib-coverage" "*"
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/js-cookie@2.2.6":
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
|
||||
integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
|
@ -2146,6 +2158,11 @@
|
|||
"@webassemblyjs/wast-parser" "1.9.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xobotyi/scrollbar-width@1.9.5":
|
||||
version "1.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d"
|
||||
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
|
@ -2913,6 +2930,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
bowser@^1.7.3:
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a"
|
||||
integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==
|
||||
|
||||
boxen@^4.1.0, boxen@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64"
|
||||
|
@ -4032,6 +4054,13 @@ copy-template-dir@^1.4.0:
|
|||
readdirp "^2.0.0"
|
||||
run-parallel "^1.1.4"
|
||||
|
||||
copy-to-clipboard@^3.2.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae"
|
||||
integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
|
||||
dependencies:
|
||||
toggle-selection "^1.0.6"
|
||||
|
||||
core-js-compat@^3.6.2:
|
||||
version "3.6.5"
|
||||
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c"
|
||||
|
@ -4267,6 +4296,14 @@ css-has-pseudo@^0.10.0:
|
|||
postcss "^7.0.6"
|
||||
postcss-selector-parser "^5.0.0-rc.4"
|
||||
|
||||
css-in-js-utils@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99"
|
||||
integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
css-loader@^3.4.2:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.3.tgz#95ac16468e1adcd95c844729e0bb167639eb0bcf"
|
||||
|
@ -4316,7 +4353,7 @@ css-tree@1.0.0-alpha.37:
|
|||
mdn-data "2.0.4"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-tree@1.0.0-alpha.39:
|
||||
css-tree@1.0.0-alpha.39, css-tree@^1.0.0-alpha.28:
|
||||
version "1.0.0-alpha.39"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb"
|
||||
integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==
|
||||
|
@ -4424,6 +4461,11 @@ csso@^4.0.2:
|
|||
dependencies:
|
||||
css-tree "1.0.0-alpha.39"
|
||||
|
||||
csstype@^2.5.5:
|
||||
version "2.6.13"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
|
||||
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
|
||||
|
||||
currently-unhandled@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
|
||||
|
@ -5124,7 +5166,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
|
|||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
error-stack-parser@^2.0.2, error-stack-parser@^2.0.3:
|
||||
error-stack-parser@^2.0.2, error-stack-parser@^2.0.3, error-stack-parser@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8"
|
||||
integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==
|
||||
|
@ -5648,7 +5690,7 @@ fancy-log@^1.3.3:
|
|||
parse-node-version "^1.0.0"
|
||||
time-stamp "^1.0.0"
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
@ -5702,11 +5744,21 @@ fast-safe-stringify@^2.0.4, fast-safe-stringify@^2.0.7:
|
|||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fast-shallow-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b"
|
||||
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
|
||||
|
||||
fast-stringify@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fast-stringify/-/fast-stringify-1.1.2.tgz#f109b792d54343aec271b47882598d279402401d"
|
||||
integrity sha512-SfslXjiH8km0WnRiuPfpUKwlZjW5I878qsOm+2x8x3TgqmElOOLh1rgJFb+PolNdNRK3r8urEefqx0wt7vx1dA==
|
||||
|
||||
fastest-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-1.0.1.tgz#9122d406d4c9d98bea644a6b6853d5874b87b028"
|
||||
integrity sha1-kSLUBtTJ2YvqZEpraFPVh0uHsCg=
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
|
||||
|
@ -6987,6 +7039,11 @@ hyperlinker@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/hyperlinker/-/hyperlinker-1.0.0.tgz#23dc9e38a206b208ee49bc2d6c8ef47027df0c0e"
|
||||
integrity sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==
|
||||
|
||||
hyphenate-style-name@^1.0.2:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.15, iconv-lite@^0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
|
@ -7138,6 +7195,14 @@ ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
|
||||
inline-style-prefixer@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-4.0.2.tgz#d390957d26f281255fe101da863158ac6eb60911"
|
||||
integrity sha512-N8nVhwfYga9MiV9jWlwfdj1UDIaZlBFu4cJSJkIr7tZX7sHpHhGR5su1qdpW+7KPL8ISTvCIkcaFi/JdBknvPg==
|
||||
dependencies:
|
||||
bowser "^1.7.3"
|
||||
css-in-js-utils "^2.0.0"
|
||||
|
||||
inquirer-autocomplete-prompt@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/inquirer-autocomplete-prompt/-/inquirer-autocomplete-prompt-1.1.0.tgz#e7745b49122e56b483659c91328a2c3fca33ffd6"
|
||||
|
@ -7732,6 +7797,11 @@ js-base64@^2.1.8:
|
|||
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
|
||||
integrity sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==
|
||||
|
||||
js-cookie@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
|
||||
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
|
||||
|
||||
js-string-escape@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
|
||||
|
@ -8466,6 +8536,14 @@ marked@^0.3.6:
|
|||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790"
|
||||
integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==
|
||||
|
||||
match-sorter@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-4.2.1.tgz#575b4b3737185ba9518b67612b66877ea0b37358"
|
||||
integrity sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.5"
|
||||
remove-accents "0.4.2"
|
||||
|
||||
maxstache-stream@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/maxstache-stream/-/maxstache-stream-1.0.4.tgz#9c7f5cab7e5fdd2d90da86143b4e9631ea328040"
|
||||
|
@ -8884,6 +8962,20 @@ nan@^2.12.1, nan@^2.13.2:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
||||
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
|
||||
|
||||
nano-css@^5.2.1:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.0.tgz#9d3cd29788d48b6a07f52aa4aec7cf4da427b6b5"
|
||||
integrity sha512-uM/9NGK9/E9/sTpbIZ/bQ9xOLOIHZwrrb/CRlbDHBU/GFS7Gshl24v/WJhwsVViWkpOXUmiZ66XO7fSB4Wd92Q==
|
||||
dependencies:
|
||||
css-tree "^1.0.0-alpha.28"
|
||||
csstype "^2.5.5"
|
||||
fastest-stable-stringify "^1.0.1"
|
||||
inline-style-prefixer "^4.0.0"
|
||||
rtl-css-js "^1.9.0"
|
||||
sourcemap-codec "^1.4.1"
|
||||
stacktrace-js "^2.0.0"
|
||||
stylis "3.5.0"
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
|
@ -11103,6 +11195,13 @@ react-mapbox-gl@^4.8.6:
|
|||
deep-equal "1.0.1"
|
||||
supercluster "^7.0.0"
|
||||
|
||||
react-query@^2.23.1:
|
||||
version "2.23.1"
|
||||
resolved "https://registry.yarnpkg.com/react-query/-/react-query-2.23.1.tgz#7d676f56d3c6e96b4de4d0b178baf6bb6a0ec272"
|
||||
integrity sha512-qIma0Kvr//LWgWFah7RcntvD4FurXXdQaQeIfqhCWKdhihhe3Xs5BHsljAP68jo719/+xhWxL3I96SvrU4gGHA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
|
||||
react-scroll-to-component@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-scroll-to-component/-/react-scroll-to-component-1.0.2.tgz#f260dc936c62a53e772786d7832fe0884e195354"
|
||||
|
@ -11119,6 +11218,31 @@ react-sortable-hoc@^1.11.0:
|
|||
invariant "^2.2.4"
|
||||
prop-types "^15.5.7"
|
||||
|
||||
react-universal-interface@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"
|
||||
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
|
||||
|
||||
react-use@^15.3.4:
|
||||
version "15.3.4"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-15.3.4.tgz#f853d310bd71f75b38900a8caa3db93f6dc6e872"
|
||||
integrity sha512-cHq1dELW6122oi1+xX7lwNyE/ugZs5L902BuO8eFJCfn2api1KeuPVG1M/GJouVARoUf54S2dYFMKo5nQXdTag==
|
||||
dependencies:
|
||||
"@types/js-cookie" "2.2.6"
|
||||
"@xobotyi/scrollbar-width" "1.9.5"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
fast-deep-equal "^3.1.3"
|
||||
fast-shallow-equal "^1.0.0"
|
||||
js-cookie "^2.2.1"
|
||||
nano-css "^5.2.1"
|
||||
react-universal-interface "^0.6.2"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
screenfull "^5.0.0"
|
||||
set-harmonic-interval "^1.0.1"
|
||||
throttle-debounce "^2.1.0"
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
react@^16.13.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||
|
@ -11332,6 +11456,11 @@ regjsparser@^0.6.4:
|
|||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
remove-accents@0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
|
||||
integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=
|
||||
|
||||
remove-bom-buffer@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53"
|
||||
|
@ -11432,6 +11561,11 @@ requires-port@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
|
@ -11567,6 +11701,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
|||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rtl-css-js@^1.9.0:
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.14.0.tgz#daa4f192a92509e292a0519f4b255e6e3c076b7d"
|
||||
integrity sha512-Dl5xDTeN3e7scU1cWX8c9b6/Nqz3u/HgR4gePc1kWXYiQWVQbKCEyK6+Hxve9LbcJ5EieHy1J9nJCN3grTtGwg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
run-async@^2.2.0, run-async@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
|
||||
|
@ -11696,6 +11837,11 @@ schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.6.6:
|
|||
ajv "^6.12.0"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
screenfull@^5.0.0:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.0.2.tgz#b9acdcf1ec676a948674df5cd0ff66b902b0bed7"
|
||||
integrity sha512-cCF2b+L/mnEiORLN5xSAz6H3t18i2oHh9BA8+CQlAh5DRw2+NFAGQJOSYbcGw8B2k04g/lVvFcfZ83b3ysH5UQ==
|
||||
|
||||
scroll-to@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/scroll-to/-/scroll-to-0.0.2.tgz#936d398a9133660a2492145c2c0081dfcb0728f3"
|
||||
|
@ -11825,6 +11971,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
|
||||
set-harmonic-interval@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249"
|
||||
integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==
|
||||
|
||||
set-value@^2.0.0, set-value@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
||||
|
@ -12053,6 +12204,11 @@ source-map-url@^0.4.0:
|
|||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
||||
|
||||
source-map@0.5.6:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
integrity sha1-dc449SvwczxafwwRjYEzSiu19BI=
|
||||
|
||||
source-map@^0.4.2:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
|
||||
|
@ -12070,6 +12226,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
|
|||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
sourcemap-codec@^1.4.1:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
||||
spark-md5@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.1.tgz#83a0e255734f2ab4e5c466e5a2cfc9ba2aa2124d"
|
||||
|
@ -12178,7 +12339,7 @@ stable@^0.1.8:
|
|||
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
|
||||
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
|
||||
|
||||
stack-generator@^2.0.3:
|
||||
stack-generator@^2.0.3, stack-generator@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36"
|
||||
integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==
|
||||
|
@ -12195,6 +12356,23 @@ stackframe@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
|
||||
integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==
|
||||
|
||||
stacktrace-gps@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a"
|
||||
integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==
|
||||
dependencies:
|
||||
source-map "0.5.6"
|
||||
stackframe "^1.1.1"
|
||||
|
||||
stacktrace-js@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
|
||||
integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
|
||||
dependencies:
|
||||
error-stack-parser "^2.0.6"
|
||||
stack-generator "^2.0.5"
|
||||
stacktrace-gps "^3.0.4"
|
||||
|
||||
static-extend@^0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
|
||||
|
@ -12490,6 +12668,11 @@ stylehacks@^4.0.0:
|
|||
postcss "^7.0.0"
|
||||
postcss-selector-parser "^3.0.0"
|
||||
|
||||
stylis@3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1"
|
||||
integrity sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw==
|
||||
|
||||
supercluster@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.0.0.tgz#75d474fafb0a055db552ed7bd7bbda583f6ab321"
|
||||
|
@ -12698,6 +12881,11 @@ text-table@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
throttle-debounce@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
|
||||
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
|
||||
|
||||
through2-filter@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254"
|
||||
|
@ -12862,6 +13050,11 @@ to-time@^1.0.2:
|
|||
dependencies:
|
||||
bignumber.js "^2.4.0"
|
||||
|
||||
toggle-selection@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
|
||||
integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
|
||||
|
||||
toidentifier@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
|
@ -12929,6 +13122,11 @@ tryer@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
||||
|
||||
ts-easing@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
|
||||
integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==
|
||||
|
||||
ts-pnp@^1.1.6:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
|
||||
|
|
Loading…
Reference in a new issue