diff --git a/sonar-project.properties b/sonar-project.properties index 7de185ab2d26b5e69b0a6f152315845410c7566e..08cb6f9b7a2b974004a44cf490837489660af109 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,3 +1,3 @@ sonar.sources = src -sonar.exclusions = build/**, node_modules/** +sonar.exclusions = build/**, node_modules/**, src/assets/resources/** #sonar.tests = api/tests/ diff --git a/src/App.vue b/src/App.vue index a303e546e081dbf70878c0c85c6c0f1c27574fff..7104f1d89452abe8f86971a0821bf69fe6ea9f26 100644 --- a/src/App.vue +++ b/src/App.vue @@ -22,12 +22,15 @@ :key="'message-' + index" :class="['ui', message.level ? message.level : 'info', 'message']" > - <em + <i class="close icon" @click="DISCARD_MESSAGE(message)" /> <div class="header"> - <em class="info circle icon" /> + <i + class="info circle icon" + aria-hidden="true" + /> Informations </div> <ul class="list"> @@ -106,8 +109,9 @@ export default { ...mapMutations(['DISCARD_MESSAGE']), clickOutsideMenu(e) { - if (e.target.closest && !e.target.closest('#menu-dropdown')) + if (e.target.closest && !e.target.closest('#menu-dropdown')) { this.menuIsOpen = false; + } }, }, }; diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js index ad632c88defc4456eeaed18c12c9b4c3d210789b..d731abea211fbffb94bded1dbc2bfbda934e202f 100644 --- a/src/assets/js/map-util.js +++ b/src/assets/js/map-util.js @@ -7,7 +7,7 @@ import 'leaflet.vectorgrid'; let map; let dictLayersToLeaflet = {}; var layerMVT; -let statusList = [ +const statusList = [ { name: 'Brouillon', value: 'draft', @@ -55,7 +55,7 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ params: params, } ).then(response => { - let data = response.data; + const data = response.data; var err = typeof data === 'object' ? null : data; if (data.features || err) { showResults(err, evt.latlng, data); @@ -116,7 +116,7 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ } else { // Otherwise show the content in a popup - let contentLines = []; + const contentLines = []; let contentTitle; if (data.features.length > 0) { Object.entries(data.features[0].properties).forEach(entry => { @@ -211,7 +211,7 @@ const mapUtil = { if (layers) { //* if admin has defined basemaps for this project layers.forEach((layer) => { if (layer) { - let options = layer.options; + const options = layer.options; if (options) { options.noWrap = true; options.opacity = layer.opacity; @@ -424,10 +424,10 @@ const mapUtil = { featureType.colors_style.value.icons[customFieldOption] !== 'circle' ) { const iconHTML = ` - <em + <i class="fas fa-${featureType.colors_style.value.icons[customFieldOption]} fa-lg" style="color: ${color}" - ></em> + ></i> `; const customMapIcon = L.divIcon({ html: iconHTML, @@ -454,10 +454,10 @@ const mapUtil = { } else { if (featureType.icon && featureType.icon !== 'circle') { const iconHTML = ` - <em + <i class="fas fa-${featureType.icon} fa-lg" style="color: ${color}" - ></em> + ></i> `; const customMapIcon = L.divIcon({ html: iconHTML, @@ -513,7 +513,7 @@ const mapUtil = { _createContentPopup: function (feature, featureTypes, projectSlug) { const formatDate = (currentDatetime) => { - let formattedDate = currentDatetime.getFullYear() + '-' + ('0' + (currentDatetime.getMonth() + 1)).slice(-2) + '-' + ('0' + currentDatetime.getDate()).slice(-2) + ' ' + + const formattedDate = currentDatetime.getFullYear() + '-' + ('0' + (currentDatetime.getMonth() + 1)).slice(-2) + '-' + ('0' + currentDatetime.getDate()).slice(-2) + ' ' + ('0' + currentDatetime.getHours()).slice(-2) + ':' + ('0' + currentDatetime.getMinutes()).slice(-2); return formattedDate; }; @@ -534,7 +534,9 @@ const mapUtil = { featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.properties.feature_type_id) : featureTypes.find((fType) => fType.slug === feature.properties.feature_type); //* geojson status = statusList.find((x) => x.value === feature.properties.status.value).name; - if (featureType) featureTypeUrl = `/geocontrib/projet/${projectSlug}/type-signalement/${featureType.slug}/`; + if (featureType) { + featureTypeUrl = `/geocontrib/projet/${projectSlug}/type-signalement/${featureType.slug}/`; + } featureUrl = `${featureTypeUrl}signalement/${feature.properties.feature_id}/`; } else { status = feature.properties ? feature.properties.status.label : feature.status.label; @@ -562,10 +564,6 @@ const mapUtil = { title = `<span>${title|| '<em>indisponible</em>'}</span>`; } - if (featureTypeUrl) { - `<a href="${featureTypeUrl}"> ${featureType.title || '<em>indisponible</em>'} </a>`; - } - return ` <h4> <${featureUrl ? `a href="${featureUrl}"` : 'span'}>${title || '<em>indisponible</em>'}</${featureUrl ? 'a' : 'span'}> diff --git a/src/assets/js/utils.js b/src/assets/js/utils.js index 31e94db49ccb7413f2f3b5dc063a98b438d2ac94..284cbdf1d18adb5a327589c0e13ac9a9429dd510 100644 --- a/src/assets/js/utils.js +++ b/src/assets/js/utils.js @@ -2,26 +2,27 @@ export function fileConvertSize(aSize){ aSize = Math.abs(parseInt(aSize, 10)); const def = [[1, 'octets', 0], [1024, 'ko', 0], [1024*1024, 'Mo', 1], [1024*1024*1024, 'Go', 2], [1024*1024*1024*1024, 'To', 2]]; for (let i=0; i<def.length; i++) { - if (aSize<def[i][0]) return (aSize/def[i-1][0]).toFixed(def[i-1][2]) + ' ' + def[i-1][1]; + if (aSize<def[i][0]) { + return (aSize/def[i-1][0]).toFixed(def[i-1][2]) + ' ' + def[i-1][1]; + } } } export function fileConvertSizeToMo(aSize){ - console.log(aSize); aSize = Math.abs(parseInt(aSize, 10)); const def = [1024*1024, 'Mo', 1]; return (aSize/def[0]).toFixed(def[2]); } export function csvToJson(csv) { - let result = []; + const result = []; const allLines = csv.split('\n'); const headers = allLines[0].split(','); const [, ...lines] = allLines; for (const line of lines) { - let obj = {}; + const obj = {}; const currentLine = line.split(','); for (let i = 0; i < headers.length; i++) { diff --git a/src/components/Account/UserProfile.vue b/src/components/Account/UserProfile.vue index a082d517de45ca433a70a12f8f4f77ba4f8e8b76..1b8c6aa24f6c1de1b74a8a26eb2b0b1b2369c74d 100644 --- a/src/components/Account/UserProfile.vue +++ b/src/components/Account/UserProfile.vue @@ -65,8 +65,9 @@ export default { ]), userFullname() { - if (this.user.first_name || this.user.last_name) + if (this.user.first_name || this.user.last_name) { return `${this.user.first_name} ${this.user.last_name}`; + } return null; }, } diff --git a/src/components/Account/UserProjectsList.vue b/src/components/Account/UserProjectsList.vue index e95b914fd79aa6abe3e6bb1a03ceb328336cc6d1..2abee6850e74a47d4b928e4420a5eb686b8016d9 100644 --- a/src/components/Account/UserProjectsList.vue +++ b/src/components/Account/UserProjectsList.vue @@ -66,18 +66,18 @@ class="right floated" :data-tooltip="`Projet créé le ${project.created_on}`" > - <em class="calendar icon" /> {{ project.created_on }} + <i class="calendar icon" /> {{ project.created_on }} </span> <span data-tooltip="Membres"> - {{ project.nb_contributors }} <em class="user icon" /> + {{ project.nb_contributors }} <i class="user icon" /> </span> <span data-tooltip="Signalements publiés"> - {{ project.nb_published_features }} <em + {{ project.nb_published_features }} <i class="map marker icon" /> </span> <span data-tooltip="Commentaires"> - {{ project.nb_published_features_comments }} <em + {{ project.nb_published_features_comments }} <i class="comment icon" /> </span> diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue index 6ff9f77d38bb8f356be23bce793d8ac85a7ab7ee..a07dcda35a68f3b2859850d91855d64a2133f3e5 100644 --- a/src/components/AppHeader.vue +++ b/src/components/AppHeader.vue @@ -25,7 +25,10 @@ <span> <span v-if="project"> Projet : {{ project.title }} </span> </span> - <em class="dropdown icon" /> + <i + class="dropdown icon" + aria-hidden="true" + /> <div :class="[ 'menu dropdown-list', @@ -41,7 +44,10 @@ }" class="item" > - <em class="home icon" />Accueil + <i + class="home icon" + aria-hidden="true" + />Accueil </router-link> <router-link v-if="project" @@ -51,7 +57,10 @@ }" class="item" > - <em class="list icon" />Liste & Carte + <i + class="list icon" + aria-hidden="true" + />Liste & Carte </router-link> <router-link v-if=" @@ -64,7 +73,10 @@ }" class="item" > - <em class="map icon" />Fonds cartographiques + <i + class="map icon" + aria-hidden="true" + />Fonds cartographiques </router-link> <router-link v-if=" @@ -77,7 +89,10 @@ }" class="item" > - <em class="users icon" />Membres + <i + class="users icon" + aria-hidden="true" + />Membres </router-link> <div class="mobile"> <router-link @@ -111,7 +126,10 @@ v-if="user" class="item" @click="logout" - ><em class="ui logout icon" /> + ><i + class="ui logout icon" + aria-hidden="true" + /> </a> <router-link v-else-if="!user && !SSO_LOGIN_URL" @@ -166,7 +184,10 @@ v-if="user" class="item log-item" @click="logout" - ><em class="ui logout icon" /> + ><i + class="ui logout icon" + aria-hidden="true" + /> </a> <router-link v-else-if="!user && !SSO_LOGIN_URL" @@ -233,8 +254,9 @@ export default { return this.configuration.VUE_APP_LOGO_PATH; }, userFullname() { - if (this.user.first_name || this.user.last_name) + if (this.user.first_name || this.user.last_name) { return `${this.user.first_name} ${this.user.last_name}`; + } return null; }, isAdmin() { diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue index b7cc3d7a3a87b8f749a064c3d016f8715c4d4077..9c02886cb1dcc25050cfc17bee1c2e6fb93d3f57 100644 --- a/src/components/Dropdown.vue +++ b/src/components/Dropdown.vue @@ -32,7 +32,7 @@ {{ selected }} </div> </div> - <em + <i :class="['dropdown icon', { clear: clearable && selected }]" @click="clear" /> @@ -115,7 +115,9 @@ export default { }, created() { - this.identifier = Math.floor(Math.random() * 10000); + const crypto = window.crypto || window.msCrypto; + var array = new Uint32Array(1); + this.identifier = Math.floor(crypto.getRandomValues(array) * 10000); window.addEventListener('mousedown', this.clickOutsideDropdown); }, @@ -166,7 +168,9 @@ export default { if (this.clearable) { this.input = ''; this.$emit('update:selection', ''); - if (this.isOpen) this.toggleDropdown(false); + if (this.isOpen) { + this.toggleDropdown(false); + } } }, diff --git a/src/components/Feature/Detail/FeatureComments.vue b/src/components/Feature/Detail/FeatureComments.vue index 52910059d5d03bb21bea8e7672a5ec78cbfa5722..e2158b98cb87818d337e9ca36841f68fa95a48f3 100644 --- a/src/components/Feature/Detail/FeatureComments.vue +++ b/src/components/Feature/Detail/FeatureComments.vue @@ -45,13 +45,18 @@ <div v-if="event.related_comment.attachment" > - <br><a + <br> + <a :href=" DJANGO_BASE_URL + event.related_comment.attachment.url " target="_blank" - ><em class="paperclip fitted icon" /> + > + <i + class="paperclip fitted icon" + aria-hidden="true" + /> {{ event.related_comment.attachment.title }}</a> </div> </div> @@ -107,7 +112,7 @@ class="ui icon button" for="attachment_file" > - <em class="paperclip icon" /> + <i class="paperclip icon" /> <span class="label">{{ comment_form.attachment_file.value ? comment_form.attachment_file.value @@ -146,7 +151,10 @@ class="ui compact green icon button" @click="postComment" > - <em class="plus icon" /> Poster le commentaire + <i + class="plus icon" + aria-hidden="true" + /> Poster le commentaire </button> </form> </div> @@ -285,8 +293,8 @@ export default { }, validateImgFile(files, handleFile) { - let url = window.URL || window.webkitURL; - let image = new Image(); + const url = window.URL || window.webkitURL; + const image = new Image(); image.onload = function () { handleFile(true); URL.revokeObjectURL(image.src); diff --git a/src/components/Feature/Detail/FeatureHeader.vue b/src/components/Feature/Detail/FeatureHeader.vue index bdf8616eb701f57f1025d4ca848bb9fdd981c0f5..d0850cb749761cd9462f53e69a904c8a43046ea4 100644 --- a/src/components/Feature/Detail/FeatureHeader.vue +++ b/src/components/Feature/Detail/FeatureHeader.vue @@ -16,7 +16,10 @@ data-tooltip="Ajouter un signalement" data-position="bottom left" > - <em class="plus fitted icon" /> + <i + class="plus fitted icon" + aria-hidden="true" + /> </router-link> <router-link v-if=" @@ -33,7 +36,10 @@ }" class="ui button button-hover-orange" > - <em class="inverted grey pencil alternate icon" /> + <i + class="inverted grey pencil alternate icon" + aria-hidden="true" + /> </router-link> <a v-if="((permissions && permissions.can_update_feature) || isFeatureCreator) && isOnline" @@ -41,7 +47,10 @@ class="ui button button-hover-red" @click="isCanceling = true" > - <em class="inverted grey trash alternate icon" /> + <i + class="inverted grey trash alternate icon" + aria-hidden="true" + /> </a> </div> <div class="ui hidden divider" /> diff --git a/src/components/Feature/Detail/FeatureTable.vue b/src/components/Feature/Detail/FeatureTable.vue index 171ceb5a03a0554089310c8533b69035126943ce..5e60af316be3b421dd06a84ea368be6fd700cd46 100644 --- a/src/components/Feature/Detail/FeatureTable.vue +++ b/src/components/Feature/Detail/FeatureTable.vue @@ -12,7 +12,7 @@ </td> <td> <b> - <em + <i v-if="field.field_type === 'boolean'" :class="[ 'icon', @@ -33,7 +33,7 @@ <tr> <td>Statut</td> <td> - <em + <i v-if="currentFeature.status" :class="['icon', statusIcon]" /> diff --git a/src/components/Feature/Edit/FeatureExtraForm.vue b/src/components/Feature/Edit/FeatureExtraForm.vue index 38734ee77de0e254bacd56d903c6c64dcc1bc55c..c85678611cea50ba0e3e8fd2600a21e2a942b3f4 100644 --- a/src/components/Feature/Edit/FeatureExtraForm.vue +++ b/src/components/Feature/Edit/FeatureExtraForm.vue @@ -116,7 +116,7 @@ export default { }, set(newValue) { //* set the value selected in the dropdown - let newExtraForm = this.field; + const newExtraForm = this.field; newExtraForm['value'] = newValue; this.$store.commit('feature/UPDATE_EXTRA_FORM', newExtraForm); }, @@ -125,7 +125,7 @@ export default { methods: { updateStore_extra_form(evt) { - let newExtraForm = this.field; + const newExtraForm = this.field; if (this.field.field_type === 'boolean') { newExtraForm['value'] = evt.target.checked; //* if checkbox use "checked" } else { diff --git a/src/components/Feature/FeatureAttachmentForm.vue b/src/components/Feature/FeatureAttachmentForm.vue index 78e714c6b4912757f10e6fe36759c5b21f3dfcc7..808e8606d33cd3e44665e275c0217c34bf8e1bc6 100644 --- a/src/components/Feature/FeatureAttachmentForm.vue +++ b/src/components/Feature/FeatureAttachmentForm.vue @@ -8,7 +8,7 @@ type="button" @click="removeAttachmentFormset(form.dataKey)" > - <em class="ui times icon" /> + <i class="ui times icon" /> </button> </h4> <!-- {{ form.errors }} --> @@ -42,7 +42,10 @@ class="ui icon button" :for="'attachment_file' + attachmentForm.dataKey" > - <em class="file icon" /> + <i + class="file icon" + aria-hidden="true" + /> <span v-if="form.attachment_file.value" class="label" @@ -163,7 +166,7 @@ export default { methods: { initForm(attachmentForm) { - for (let el in attachmentForm) { + for (const el in attachmentForm) { if (el && this.form[el]) { if (el === 'attachment_file' && attachmentForm[el]) { this.form[el].value = attachmentForm[el].split('/').pop(); //* keep only the file name, not the path @@ -179,8 +182,9 @@ export default { 'feature/REMOVE_ATTACHMENT_FORM', this.attachmentForm.dataKey ); - if (this.form.id.value) + if (this.form.id.value) { this.$store.commit('feature/ADD_ATTACHMENT_TO_DELETE', this.form.id.value); + } }, updateStore() { @@ -196,8 +200,8 @@ export default { }, validateImgFile(files, handleFile) { - let url = window.URL || window.webkitURL; - let image = new Image(); + const url = window.URL || window.webkitURL; + const image = new Image(); image.onload = function () { handleFile(true); URL.revokeObjectURL(image.src); diff --git a/src/components/Feature/FeatureEditModal.vue b/src/components/Feature/FeatureEditModal.vue index e005c820817de50dfa05a01dbe40181ae77ee133..3ed47f5d719634a7f84923114cfd04f63f894222 100644 --- a/src/components/Feature/FeatureEditModal.vue +++ b/src/components/Feature/FeatureEditModal.vue @@ -1,7 +1,7 @@ <template> <div class="ui mini modal"> - <em class="close icon" /> + <i class="close icon" /> <div class="content"> <h3>Importer une image géoréférencée</h3> <form @@ -21,7 +21,10 @@ class="ui icon button" for="image_file" > - <em class="file icon" /> + <i + class="file icon" + aria-hidden="true" + /> <span class="label">Sélectionner une image ...</span> </label> <input @@ -44,7 +47,10 @@ class="ui positive right labeled icon button" > Importer - <em class="checkmark icon" /> + <i + class="checkmark icon" + aria-hidden="true" + /> </button> </form> </div> diff --git a/src/components/Feature/FeatureLinkedForm.vue b/src/components/Feature/FeatureLinkedForm.vue index bbd2b1ab1bbcd82020ca31bb859a562b2694f1c0..6d2256b22fe530951e5dde52d984a0e4febdf479 100644 --- a/src/components/Feature/FeatureLinkedForm.vue +++ b/src/components/Feature/FeatureLinkedForm.vue @@ -7,7 +7,10 @@ type="button" @click="remove_linked_formset" > - <em class="ui times icon" /> + <i + class="ui times icon" + aria-hidden="true" + /> </button> </h4> <ul diff --git a/src/components/Feature/FeatureListMassToggle.vue b/src/components/Feature/FeatureListMassToggle.vue index ef0bd866e2729328b35c18f836a2202c7e4d705b..8483baa507f964c9db68496497aeb3921f23e043 100644 --- a/src/components/Feature/FeatureListMassToggle.vue +++ b/src/components/Feature/FeatureListMassToggle.vue @@ -4,9 +4,9 @@ :data-tooltip="`Passer en mode ${massMode === 'modify' ? 'suppression':'édition'}`" @click="switchMode" > - <div><em :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div> + <div><i :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div> <span class="grey">| </span> - <div><em :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div> + <div><i :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div> </div> </template> diff --git a/src/components/FeatureType/FeatureTypeCustomForm.vue b/src/components/FeatureType/FeatureTypeCustomForm.vue index 05a34dbf2ab751a0db1d581f3db591983d8619d4..02dfcf5ed31ad7d580addbef24762e7a99701599 100644 --- a/src/components/FeatureType/FeatureTypeCustomForm.vue +++ b/src/components/FeatureType/FeatureTypeCustomForm.vue @@ -7,7 +7,7 @@ type="button" @click="removeCustomForm()" > - <em class="ui times icon" /> + <i class="ui times icon" /> </button> </h4> <div class="visible-fields"> @@ -302,7 +302,7 @@ export default { }, fillCustomFormData(customFormData) { - for (let el in customFormData) { + for (const el in customFormData) { if (el && this.form[el] && customFormData[el]) { //* check if is an object, because data from api is a string, while import from django is an object this.form[el].value = customFormData[el].value @@ -341,7 +341,7 @@ export default { }, hasRegularCharacters(input) { - for (let char of input) { + for (const char of input) { if (!/[a-zA-Z0-9-_]/.test(char)) { return false; } diff --git a/src/components/FeatureType/SymbologySelector.vue b/src/components/FeatureType/SymbologySelector.vue index 5db2a4dbf6303969484d555d7fe29ed2d94dd246..064ad7aea7066e902ebeebe51084e7747f4a71b6 100644 --- a/src/components/FeatureType/SymbologySelector.vue +++ b/src/components/FeatureType/SymbologySelector.vue @@ -45,7 +45,7 @@ class="icon-container" @click="selectIcon(icon)" > - <em + <i :class="`fa-${icon}`" class="icon alt fas" /> @@ -121,7 +121,9 @@ export default { created() { this.form.color.value = this.initColor; - if (this.initIcon) this.form.icon = this.initIcon; + if (this.initIcon) { + this.form.icon = this.initIcon; + } this.$emit('set', { name: this.title, value: this.form diff --git a/src/components/ImportTask.vue b/src/components/ImportTask.vue index 5d239b8582c3789ae4fdd9067fa45b9a87294dce..d0b82745658dc09951e9d46ef6333484feaeaeeb 100644 --- a/src/components/ImportTask.vue +++ b/src/components/ImportTask.vue @@ -3,8 +3,16 @@ <table class="ui collapsing celled table"> <thead> <tr> - <th>Fichiers importés</th> - <th>Status</th> + <th + scope="col" + > + Fichiers importés + </th> + <th + scope="col" + > + Status + </th> </tr> </thead> <tbody> @@ -29,19 +37,19 @@ :data-tooltip="importFile.infos" class="ui icon margin-left" > - <em + <i v-if="importFile.status === 'processing'" class="orange hourglass half icon" /> - <em + <i v-else-if="importFile.status === 'finished'" class="green check circle outline icon" /> - <em + <i v-else-if="importFile.status === 'failed'" class="red x icon" /> - <em + <i v-else class="red ban icon" /> @@ -50,7 +58,7 @@ v-if="importFile.status === 'pending'" data-tooltip="Statut en attente. Clickez pour rafraichir." > - <em + <i :class="['orange icon', ready && !reloading ? 'sync' : 'hourglass half rotate']" @click="fetchImports()" /> @@ -69,8 +77,8 @@ import { mapState } from 'vuex'; export default { filters: { setDate: function (value) { - let date = new Date(value); - let d = date.toLocaleDateString('fr', { + const date = new Date(value); + const d = date.toLocaleDateString('fr', { year: 'numeric', month: 'long', day: 'numeric', diff --git a/src/components/Pagination.vue b/src/components/Pagination.vue index 30ef334a6c89e0f488fb0d760966fa47eeedc12e..7764f116a41c61b8f25df5a22e20d3354ca97fe9 100644 --- a/src/components/Pagination.vue +++ b/src/components/Pagination.vue @@ -11,7 +11,10 @@ :href="currentLocation" @click="page -= 1" > - <em class="ui icon big angle left" /> + <i + class="ui icon big angle left" + aria-hidden="true" + /> </a> </li> <div @@ -61,7 +64,10 @@ :href="currentLocation" @click="page += 1" > - <em class="ui icon big angle right" /> + <i + class="ui icon big angle right" + aria-hidden="true" + /> </a> </li> </ul> diff --git a/src/components/Project/Basemaps/BasemapListItem.vue b/src/components/Project/Basemaps/BasemapListItem.vue index 7107d3cf9d1084b24ec17b0c1537982939a2e280..73a0aee131cfb94e525775d79d8d642d8088740d 100644 --- a/src/components/Project/Basemaps/BasemapListItem.vue +++ b/src/components/Project/Basemaps/BasemapListItem.vue @@ -37,7 +37,10 @@ class="ui compact small icon left floated button green" @click="addLayer" > - <em class="ui plus icon" /> + <i + class="ui plus icon" + aria-hidden="true" + /> <span>Ajouter une couche</span> </a> </div> @@ -58,7 +61,10 @@ button button-hover-green " > - <em class="ui trash alternate icon" /> + <i + class="ui trash alternate icon" + aria-hidden="true" + /> <span>Supprimer ce fond cartographique</span> </a> </div> @@ -67,6 +73,8 @@ </template> <script> +import { mapState } from 'vuex'; + import Sortable from 'sortablejs'; import ProjectMappingContextLayer from '@/components/Project/Basemaps/ProjectMappingContextLayer.vue'; @@ -84,7 +92,18 @@ export default { } }, + data() { + return { + sortableElement: null + }; + }, + computed: { + ...mapState('map', [ + 'UPDATE_BASEMAP', + 'DELETE_BASEMAP', + 'REPLACE_BASEMAP_LAYERS' + ]), maxLayersCount: function () { return this.basemap.layers.reduce((acc, curr) => { if (curr.dataKey > acc) { @@ -109,7 +128,7 @@ export default { methods: { deleteBasemap() { - this.$store.commit('map/DELETE_BASEMAP', this.basemap.id); + this.DELETE_BASEMAP(this.basemap.id); }, addLayer(layer) { @@ -121,7 +140,7 @@ export default { title: 'Open street map', ...layer, }; - this.$store.commit('map/UPDATE_BASEMAP', { + this.UPDATE_BASEMAP({ layers: [...this.basemap.layers, newLayer], id: this.basemap.id, title: this.basemap.title, @@ -134,14 +153,11 @@ export default { if(evt.target.value === '') { //* delete or add error message while typing errors = 'Veuillez compléter ce champ.'; } - this.$store.commit('map/UPDATE_BASEMAP', { + this.UPDATE_BASEMAP({ id: this.basemap.id, title: evt.target.value, errors, }); - - - }, removeLayer(dataKey) { @@ -150,7 +166,7 @@ export default { fillLayersWithDatakey(layers) { let dataKey = 0; - this.$store.commit('map/REPLACE_BASEMAP_LAYERS', { + this.REPLACE_BASEMAP_LAYERS({ basemapId: this.basemap.id, layers: layers.map((el) => { dataKey += 1; @@ -168,9 +184,9 @@ export default { //* increment value 'order' in this.basemap.layers looping over layers from template ^ let order = 0; - let movedLayers = []; - for (let id of currentLayersNamesInOrder) { - let matchingLayer = this.basemap.layers.find( + const movedLayers = []; + for (const id of currentLayersNamesInOrder) { + const matchingLayer = this.basemap.layers.find( (el) => el.dataKey === Number(id) ); if (matchingLayer) { @@ -189,7 +205,7 @@ export default { }, initSortable() { - new Sortable(document.getElementById(`list-${this.basemap.id}`), { + this.sortableElement = new Sortable(document.getElementById(`list-${this.basemap.id}`), { animation: 150, handle: '.layer-handle-sort', // The element that is active to drag ghostClass: 'blue-background-class', diff --git a/src/components/Project/Basemaps/ProjectMappingContextLayer.vue b/src/components/Project/Basemaps/ProjectMappingContextLayer.vue index a914f3ef391bc5927112ec0cd22b9db8e6b96318..c1a37355c902c3e3a4b95459c444152b498b0177 100644 --- a/src/components/Project/Basemaps/ProjectMappingContextLayer.vue +++ b/src/components/Project/Basemaps/ProjectMappingContextLayer.vue @@ -12,7 +12,7 @@ for="form.layer.id_for_label" class="layer-handle-sort" > - <em class="th icon" />couche + <i class="th icon" />couche </label> <Dropdown :options="availableLayerOptions" @@ -57,7 +57,10 @@ @click="removeLayer" > <div class="ui compact small icon floated button button-hover-red"> - <em class="ui grey trash alternate icon" /> + <i + class="ui grey trash alternate icon" + aria-hidden="true" + /> <span>Supprimer cette couche</span> </div> </div> diff --git a/src/components/Project/Detail/ProjectFeatureTypes.vue b/src/components/Project/Detail/ProjectFeatureTypes.vue index 7b5bf2d858849069b2d8770a9c86ed93e626b682..a86e846975acaff6e58498b86430a0dcdb435bb5 100644 --- a/src/components/Project/Detail/ProjectFeatureTypes.vue +++ b/src/components/Project/Detail/ProjectFeatureTypes.vue @@ -73,7 +73,10 @@ data-position="top right" data-variation="mini" > - <em class="ui plus icon" /> + <i + class="ui plus icon" + aria-hidden="true" + /> </router-link> <router-link v-if=" @@ -99,13 +102,19 @@ data-position="top right" data-variation="mini" > - <em class="inverted grey copy alternate icon" /> + <i + class="inverted grey copy alternate icon" + aria-hidden="true" + /> </router-link> <div v-if="isImporting(type)" class="import-message" > - <em class="info circle icon" /> + <i + class="info circle icon" + aria-hidden="true" + /> Import en cours </div> <div @@ -127,7 +136,7 @@ data-variation="mini" @click="toggleDeleteFeatureType(type)" > - <em class="inverted grey trash alternate icon" /> + <i class="inverted grey trash alternate icon" /> </a> <router-link v-if=" @@ -153,7 +162,7 @@ data-position="top center" data-variation="mini" > - <em class="inverted grey paint brush alternate icon" /> + <i class="inverted grey paint brush alternate icon" /> </router-link> <router-link v-if=" @@ -180,7 +189,10 @@ data-position="top center" data-variation="mini" > - <em class="inverted grey pencil alternate icon" /> + <i + class="inverted grey pencil alternate icon" + aria-hidden="true" + /> </router-link> </div> </div> @@ -204,7 +216,7 @@ }" class="ui compact basic button" > - <em class="ui plus icon" />Créer un nouveau type de signalement + <i class="ui plus icon" />Créer un nouveau type de signalement </router-link> </div> <div class="nouveau-type-signalement"> @@ -222,7 +234,10 @@ button-align-left " > - <em class="ui plus icon" /> + <i + class="ui plus icon" + aria-hidden="true" + /> <label class="ui" for="json_file" @@ -258,7 +273,7 @@ button-align-left " > - <em class="ui plus icon" /> + <i class="ui plus icon" /> <label class="ui" for="csv_file" @@ -296,7 +311,10 @@ }" class="ui compact basic button button-align-left" > - <em class="ui plus icon" /> + <i + class="ui plus icon" + aria-hidden="true" + /> Créer un nouveau type de signalement à partir du catalogue {{ CATALOG_NAME|| 'IDGO' }} </router-link> </div> @@ -310,7 +328,10 @@ class="ui fluid teal icon button" @click="toNewGeojsonFeatureType" > - <em class="upload icon" /> Lancer l'import avec le fichier + <i + class="upload icon" + aria-hidden="true" + /> Lancer l'import avec le fichier {{ geojsonFileToImport.name }} </button> </div> @@ -324,7 +345,7 @@ class="ui fluid teal icon button" @click="toNewCsvFeatureType" > - <em class="upload icon" /> Lancer l'import avec le fichier + <i class="upload icon" /> Lancer l'import avec le fichier {{ csvFileToImport.name }} </button> </div> @@ -332,7 +353,7 @@ v-if="csvError" class="ui negative message" > - <em + <i class="close icon" @click="csvError = null" /> @@ -529,7 +550,9 @@ export default { onGeoJSONFileChange(e) { this.importing = true; var files = e.target.files || e.dataTransfer.files; - if (!files.length) return; + if (!files.length) { + return; + } this.geojsonFileToImport = files[0]; // TODO : VALIDATION IF FILE IS JSON if (parseFloat(fileConvertSizeToMo(this.geojsonFileToImport.size)) > 10) { @@ -556,7 +579,9 @@ export default { onCSVFileChange(e) { this.featureTypeImporting = true; var files = e.target.files || e.dataTransfer.files; - if (!files.length) return; + if (!files.length) { + return; + } this.csvFileToImport = files[0]; if (parseFloat(fileConvertSizeToMo(this.csvFileToImport.size)) > 10) { this.isFileSizeModalOpen = true; diff --git a/src/components/Project/Detail/ProjectHeader.vue b/src/components/Project/Detail/ProjectHeader.vue index b442c78d4a4aec71ef835aa61320e92f0499641c..f88484e91693904d8a5671d4925bcd092ce1792e 100644 --- a/src/components/Project/Detail/ProjectHeader.vue +++ b/src/components/Project/Detail/ProjectHeader.vue @@ -15,19 +15,28 @@ class="ui basic teal label" data-tooltip="Membres" > - <em class="user icon" />{{ project.nb_contributors }} + <i + class="user icon" + aria-hidden="true" + />{{ project.nb_contributors }} </div> <div class="ui basic teal label" data-tooltip="Signalements publiés" > - <em class="map marker icon" />{{ project.nb_published_features }} + <i + class="map marker icon" + aria-hidden="true" + />{{ project.nb_published_features }} </div> <div class="ui basic teal label" data-tooltip="Commentaires" > - <em class="comment icon" />{{ + <i + class="comment icon" + aria-hidden="true" + />{{ project.nb_published_features_comments }} </div> @@ -59,7 +68,10 @@ data-variation="mini" @click="OPEN_PROJECT_MODAL('subscribe')" > - <em class="inverted grey envelope icon" /> + <i + class="inverted grey envelope icon" + aria-hidden="true" + /> </a> <router-link v-if=" @@ -73,7 +85,10 @@ data-position="top center" data-variation="mini" > - <em class="inverted grey pencil alternate icon" /> + <i + class="inverted grey pencil alternate icon" + aria-hidden="true" + /> </router-link> <a v-if="isProjectAdmin && isOffline() !== true" @@ -84,7 +99,10 @@ data-variation="mini" @click="OPEN_PROJECT_MODAL('deleteProject')" > - <em class="inverted grey trash icon" /> + <i + class="inverted grey trash icon" + aria-hidden="true" + /> </a> </div> @@ -93,7 +111,10 @@ class="ui teal left labeled icon button share-button" @click="copyLink" > - <em class="left icon share square" /> + <i + class="left icon share square" + aria-hidden="true" + /> Copier le lien de partage </button> @@ -103,8 +124,9 @@ Le lien a été copié dans le presse-papier </span> - <em + <i class="close icon" + aria-hidden="true" @click="confirmMsg = ''" /> </div> @@ -118,7 +140,7 @@ class="ui fluid labeled teal icon button" @click="sendOfflineFeatures" > - <em class="upload icon" /> + <i class="upload icon" /> Envoyer au serveur </button> </div> @@ -221,7 +243,9 @@ export default { method: feature.type.toUpperCase(), }) .then((response) => { - if (!response) this.arraysOfflineErrors.push(feature); + if (!response) { + this.arraysOfflineErrors.push(feature); + } }) .catch((error) => { console.error(error); diff --git a/src/components/Project/Detail/ProjectModal.vue b/src/components/Project/Detail/ProjectModal.vue index c11c641d4c9e4813848be7838a4adb44c3935e7f..69de49375be36830ef51101cb7ff5962a42b4935 100644 --- a/src/components/Project/Detail/ProjectModal.vue +++ b/src/components/Project/Detail/ProjectModal.vue @@ -10,12 +10,12 @@ { 'transition visible active': projectModalType }, ]" > - <em + <i class="close icon" @click="CLOSE_PROJECT_MODAL" /> <div class="ui icon header"> - <em :class="[projectModalType === 'subscribe' ? 'envelope' : 'trash', 'icon']" /> + <i :class="[projectModalType === 'subscribe' ? 'envelope' : 'trash', 'icon']" /> {{ projectModalType === 'subscribe' ? 'Notifications' : 'Suppression' }} du {{ diff --git a/src/components/Project/Detail/ProjectParameters.vue b/src/components/Project/Detail/ProjectParameters.vue index 03cd229bb54f01e7fb6330d9236acb8b5c90c18a..a1c57bc7ffe904f80104ae97328b6b9bafdebf6a 100644 --- a/src/components/Project/Detail/ProjectParameters.vue +++ b/src/components/Project/Detail/ProjectParameters.vue @@ -7,7 +7,7 @@ <div class="card"> <div class="center aligned content"> <h4 class="ui center aligned icon header"> - <em class="disabled grey archive icon" /> + <i class="disabled grey archive icon" /> <div class="content"> Délai avant archivage automatique </div> @@ -20,7 +20,7 @@ <div class="card"> <div class="content"> <h4 class="ui center aligned icon header"> - <em class="disabled grey trash alternate icon" /> + <i class="disabled grey trash alternate icon" /> <div class="content"> Délai avant suppression automatique </div> @@ -33,7 +33,7 @@ <div class="card"> <div class="content"> <h4 class="ui center aligned icon header"> - <em class="disabled grey eye icon" /> + <i class="disabled grey eye icon" /> <div class="content"> Visibilité des signalements publiés </div> @@ -46,7 +46,7 @@ <div class="card"> <div class="content"> <h4 class="ui center aligned icon header"> - <em class="disabled grey eye icon" /> + <i class="disabled grey eye icon" /> <div class="content"> Visibilité des signalements archivés </div> @@ -59,7 +59,7 @@ <div class="card"> <div class="content"> <h4 class="ui center aligned icon header"> - <em class="disabled grey cogs icon" /> + <i class="disabled grey cogs icon" /> <div class="content"> Modération </div> diff --git a/src/components/Project/FeaturesListAndMap/FeatureListTable.vue b/src/components/Project/FeaturesListAndMap/FeatureListTable.vue index e90fd6edad417e3de69f3431feac053b303a3cdc..b6929e3190503d0b38d853c82ed3c14b5f503193 100644 --- a/src/components/Project/FeaturesListAndMap/FeatureListTable.vue +++ b/src/components/Project/FeaturesListAndMap/FeatureListTable.vue @@ -13,17 +13,23 @@ > <thead> <tr> - <th class="dt-center"> + <th + scope="col" + class="dt-center" + > <FeatureListMassToggle /> </th> - <th class="dt-center"> + <th + scope="col" + class="dt-center" + > <div class="pointer" @click="changeSort('status')" > Statut - <em + <i :class="{ down: isSortedAsc('status'), up: isSortedDesc('status'), @@ -32,13 +38,16 @@ /> </div> </th> - <th class="dt-center"> + <th + scope="col" + class="dt-center" + > <div class="pointer" @click="changeSort('feature_type')" > Type - <em + <i :class="{ down: isSortedAsc('feature_type'), up: isSortedDesc('feature_type'), @@ -47,13 +56,16 @@ /> </div> </th> - <th class="dt-center"> + <th + scope="col" + class="dt-center" + > <div class="pointer" @click="changeSort('title')" > Nom - <em + <i :class="{ down: isSortedAsc('title'), up: isSortedDesc('title'), @@ -62,13 +74,16 @@ /> </div> </th> - <th class="dt-center"> + <th + scope="col" + class="dt-center" + > <div class="pointer" @click="changeSort('updated_on')" > Dernière modification - <em + <i :class="{ down: isSortedAsc('updated_on'), up: isSortedDesc('updated_on'), @@ -79,6 +94,7 @@ </th> <th v-if="user" + scope="col" class="dt-center" > <div @@ -86,7 +102,7 @@ @click="changeSort('display_creator')" > Auteur - <em + <i :class="{ down: isSortedAsc('display_creator'), up: isSortedDesc('display_creator'), @@ -97,6 +113,7 @@ </th> <th v-if="user" + scope="col" class="dt-center" > <div @@ -104,7 +121,7 @@ @click="changeSort('display_last_editor')" > Dernier éditeur - <em + <i :class="{ down: isSortedAsc('display_last_editor'), up: isSortedDesc('display_last_editor'), @@ -142,25 +159,25 @@ v-if="feature.status === 'archived'" data-tooltip="Archivé" > - <em class="grey archive icon" /> + <i class="grey archive icon" /> </div> <div v-else-if="feature.status === 'pending'" data-tooltip="En attente de publication" > - <em class="teal hourglass outline icon" /> + <i class="teal hourglass outline icon" /> </div> <div v-else-if="feature.status === 'published'" data-tooltip="Publié" > - <em class="olive check icon" /> + <i class="olive check icon" /> </div> <div v-else-if="feature.status === 'draft'" data-tooltip="Brouillon" > - <em class="orange pencil alternate icon" /> + <i class="orange pencil alternate icon" /> </div> </td> <td class="dt-center"> @@ -373,7 +390,9 @@ export default { displayedPageNumbers() { //* s'il y a moins de 5 pages, renvoyer toutes les pages - if (this.lastPageNumber < 5) return this.pageNumbers; + if (this.lastPageNumber < 5) { + return this.pageNumbers; + } //* si la page courante est inférieur à 5, la liste commence à l'index 0 et on retourne 5 pages let firstPageInList = 0; let pagesQuantity = 5; @@ -408,7 +427,9 @@ export default { }, canDeleteFeature(feature) { - if (this.userStatus === 'Administrateur projet') return true; //* can delete all + if (this.userStatus === 'Administrateur projet') { + return true; //* can delete all + } //* others can delete only their own features return feature.display_creator === this.user.username; }, diff --git a/src/components/Projects/ProjectsListItem.vue b/src/components/Projects/ProjectsListItem.vue index a9560dc654bb90a9fe7f174d4d9d765ac41398e2..178ad9edf5199a417812c0ab9d635775797537b6 100644 --- a/src/components/Projects/ProjectsListItem.vue +++ b/src/components/Projects/ProjectsListItem.vue @@ -41,18 +41,18 @@ </div> <div class="meta"> <span class="right floated"> - <em class="calendar icon" /> {{ project.created_on }} + <i class="calendar icon" /> {{ project.created_on }} </span> <span data-tooltip="Membres"> - {{ project.nb_contributors }} <em class="user icon" /> + {{ project.nb_contributors }} <i class="user icon" /> </span> <span data-tooltip="Signalements publiés"> - {{ project.nb_published_features }} <em + {{ project.nb_published_features }} <i class="map marker icon" /> </span> <span data-tooltip="Commentaires"> - {{ project.nb_published_features_comments }} <em + {{ project.nb_published_features_comments }} <i class="comment icon" /> </span> diff --git a/src/components/Projects/ProjectsMenu.vue b/src/components/Projects/ProjectsMenu.vue index 619e7aac2c317166257274f8e4425e356593055b..c70a951675ec7f17cfc499f8f376ee55947360de 100644 --- a/src/components/Projects/ProjectsMenu.vue +++ b/src/components/Projects/ProjectsMenu.vue @@ -5,7 +5,7 @@ class="title collapsible-filters" > FILTRES - <em + <i class="ui icon caret right down" /> </div> diff --git a/src/components/Projects/SearchProjects.vue b/src/components/Projects/SearchProjects.vue index 703197cb85dc4333b7bdc413db0b295777915845..46532d2afc47752b6d959f51d4d579ee865b3bea 100644 --- a/src/components/Projects/SearchProjects.vue +++ b/src/components/Projects/SearchProjects.vue @@ -37,7 +37,9 @@ export default { this.$emit('loading', false); }) .catch((err) => { - if (err.message) this.$emit('loading', false); + if (err.message) { + this.$emit('loading', false); + } }); }, 100) }, @@ -52,7 +54,6 @@ export default { <style lang="less" scoped> #search-projects { - display: block; height: 100%; min-height: 40px; display: flex; diff --git a/src/components/SearchFeature.vue b/src/components/SearchFeature.vue index 6a5b191a2208ee63600b9e089cf6287e1e86c662..bd68b45419af7a285968bf95aa13cf019d216dae 100644 --- a/src/components/SearchFeature.vue +++ b/src/components/SearchFeature.vue @@ -27,7 +27,10 @@ class="multiselect__clear" @click.prevent.stop="selection = null" > - <em class="close icon" /> + <i + class="close icon" + aria-hidden="true" + /> </div> </template> <span slot="noResult"> diff --git a/src/components/SidebarLayers.vue b/src/components/SidebarLayers.vue index 2707712780b9229e8389c5f5894cd0b2a91b5c9c..e8bd5fcbbe60d1fa7293075ae3c87fdf20e119e2 100644 --- a/src/components/SidebarLayers.vue +++ b/src/components/SidebarLayers.vue @@ -48,7 +48,7 @@ <!-- <span data-tooltip="Il est possible pour chaque fond cartographique de modifier l'ordre des couches" data-position="bottom left"> - <em class="question circle outline icon"></em> + <i class="question circle outline icon"></em> </span> --> </h4> </div> @@ -90,7 +90,7 @@ :data-id="layer.id" > <p class="layer-handle-sort"> - <em class="th icon" />{{ layer.title }} + <i class="th icon" />{{ layer.title }} </p> <label>Opacité <span>(%)</span></label> <div class="range-container"> @@ -145,7 +145,7 @@ export default { mounted() { this.baseMaps = this.$store.state.map.basemaps; - let project = this.$route.params.slug; + const project = this.$route.params.slug; const mapOptions = JSON.parse(localStorage.getItem('geocontrib-map-options')) || {}; if (mapOptions && mapOptions[project]) { @@ -201,7 +201,7 @@ export default { let mapOptions = localStorage.getItem('geocontrib-map-options') || {}; mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {}; - let project = this.$route.params.slug; + const project = this.$route.params.slug; mapOptions[project] = { ...mapOptions[project], 'current-basemap-index': basemap.id, @@ -226,7 +226,7 @@ export default { }, isQueryable(baseMap) { - let queryableLayer = baseMap.layers.filter((l) => l.queryable === true); + const queryableLayer = baseMap.layers.filter((l) => l.queryable === true); return queryableLayer.length > 0; }, @@ -260,7 +260,7 @@ export default { setLocalstorageMapOptions(basemaps) { let mapOptions = localStorage.getItem('geocontrib-map-options') || {}; mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {}; - let project = this.$route.params.slug; + const project = this.$route.params.slug; mapOptions[project] = { ...mapOptions[project], basemaps: basemaps, @@ -273,7 +273,7 @@ export default { initSortable() { this.baseMaps.forEach((basemap) => { - let element=document.getElementById(`list-${basemap.id}`); + const element=document.getElementById(`list-${basemap.id}`); if(element) { new Sortable(element, { animation: 150, @@ -308,12 +308,12 @@ export default { ); // For each basemap, compare the length and id values of the layers outer_block: { - for (let basemapServer of basemapFromServer) { - let idLayersServer = basemapServer.layers.map((b) => b.id).sort(); + for (const basemapServer of basemapFromServer) { + const idLayersServer = basemapServer.layers.map((b) => b.id).sort(); if (basemapFromLocalstorage.length) { - for (let basemapLocalstorage of basemapFromLocalstorage) { + for (const basemapLocalstorage of basemapFromLocalstorage) { if (basemapServer.id === basemapLocalstorage.id) { - let idLayersLocalstorage = basemapLocalstorage.layers + const idLayersLocalstorage = basemapLocalstorage.layers .map((b) => b.id) .sort(); isSameLayers = @@ -348,7 +348,7 @@ export default { }, getQueryableLayers(baseMap) { - let queryableLayer = baseMap.layers.filter((l) => l.queryable === true); + const queryableLayer = baseMap.layers.filter((l) => l.queryable === true); return queryableLayer.map((x) => { return { name: x.title, diff --git a/src/main.js b/src/main.js index 7b10631836a7243508261d4761a8d41b1806f09e..6a6d3d1a2ade040eb0b0b1aeb1dd62a6e5f86d69 100644 --- a/src/main.js +++ b/src/main.js @@ -27,7 +27,9 @@ var refreshing=false; if(navigator.serviceWorker){ navigator.serviceWorker.addEventListener('controllerchange', () => { // We'll also need to add 'refreshing' to our data originally set to false. - if (refreshing) return; + if (refreshing) { + return; + } refreshing = true; // Here the actual reload of the page occurs window.location.reload(); @@ -36,7 +38,7 @@ if(navigator.serviceWorker){ -let onConfigLoaded = function(config){ +const onConfigLoaded = function(config){ store.commit('SET_CONFIG', config); setInterval(() => { //* check if navigator is online store.commit('SET_IS_ONLINE', navigator.onLine); @@ -44,7 +46,7 @@ let onConfigLoaded = function(config){ // set title and favico document.title= config.VUE_APP_APPLICATION_NAME+' '+config.VUE_APP_APPLICATION_ABSTRACT; - let link = document.createElement('link'); + const link = document.createElement('link'); link.id = 'dynamic-favicon'; link.rel = 'shortcut icon'; link.href = config.VUE_APP_APPLICATION_FAVICO; @@ -73,8 +75,8 @@ axios.get('./config/config.json') .catch((error)=>{ console.error(error); console.log('try to get From Localstorage'); - let conf=localStorage.getItem('geontrib_conf'); - if(conf){ + const conf=localStorage.getItem('geontrib_conf'); + if (conf) { onConfigLoaded(JSON.parse(conf)); } }) diff --git a/src/registerServiceWorker.js b/src/registerServiceWorker.js index 8b95be07184a3e621b6072a250c1171bc711d80b..d9165a280ec265551fe559549fbfdab19a934813 100644 --- a/src/registerServiceWorker.js +++ b/src/registerServiceWorker.js @@ -29,7 +29,9 @@ if (process.env.NODE_ENV === 'production') { alert('Une nouvelle version de l\'application est disponible, l\'application va se recharger'); console.log('New content is available; please refresh.'); // - if (!registration || !registration.waiting) return; + if (!registration || !registration.waiting) { + return; + } // Send message to SW to skip the waiting and activate the new SW registration.waiting.postMessage({ type: 'SKIP_WAITING' }); //window.location.reload(true); diff --git a/src/services/feature-api.js b/src/services/feature-api.js index 690df05e61decf02e2d0749458d73350a13f5d84..5e8fe8fbc797d1fed73568bad0594d54588fe5e1 100644 --- a/src/services/feature-api.js +++ b/src/services/feature-api.js @@ -112,7 +112,7 @@ const featureAPI = { }, async updateFeature({ feature_id, feature_type__slug, project__slug, newStatus }) { - let url = `${baseUrl}features/${feature_id}/?feature_type__slug=${feature_type__slug}&project__slug=${project__slug}`; + const url = `${baseUrl}features/${feature_id}/?feature_type__slug=${feature_type__slug}&project__slug=${project__slug}`; const response = await axios({ url, @@ -141,7 +141,7 @@ const featureAPI = { }, async postCommentAttachment({ featureId, file, fileName, commentId, title }) { - let formdata = new FormData(); + const formdata = new FormData(); formdata.append('file', file, fileName); formdata.append('title', title); diff --git a/src/services/project-api.js b/src/services/project-api.js index 8866ad935e563ed5f947be4f3b178760d825d937..d3be3ec50ae784ac874c63aaf60e312231f302ab 100644 --- a/src/services/project-api.js +++ b/src/services/project-api.js @@ -47,7 +47,9 @@ const projectAPI = { async getProjects({ baseUrl, filters, page, projectSlug, myaccount }) { let url = `${baseUrl}projects/`; - if (projectSlug) url += `${projectSlug}/`; + if (projectSlug) { + url += `${projectSlug}/`; + } url += `?page=${page}`; if (myaccount) { url += '&myaccount=true'; diff --git a/src/store/index.js b/src/store/index.js index 6593814e3485e110b43e8df549a1e9e556db26ce..04a89cb4c93f0e69f9bc7b58998b2e9f87d9ec5f 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -77,7 +77,9 @@ export default new Vuex.Store({ }, DISPLAY_MESSAGE(state, message) { state.messages = [message, ...state.messages]; - if (document.getElementById('content')) document.getElementById('content').scrollIntoView({ block: 'start', inline: 'nearest' }); + if (document.getElementById('content')) { + document.getElementById('content').scrollIntoView({ block: 'start', inline: 'nearest' }); + } setTimeout(() => { state.messages = []; }, 3000); diff --git a/src/store/modules/feature-type.store.js b/src/store/modules/feature-type.store.js index b107250076255f9598b86f38c55c7a7b6cd03c53..6d15c719a6a458e9d55df5f60a9e87d9ef218f31 100644 --- a/src/store/modules/feature-type.store.js +++ b/src/store/modules/feature-type.store.js @@ -8,8 +8,8 @@ const getColorsStyles = (customForms) => customForms }); const pending2draftFeatures = (features) => { - let result = []; - for (let el of features) { + const result = []; + for (const el of features) { if (el.properties.status === 'pending') { el.properties.status = 'draft'; } @@ -172,11 +172,14 @@ const feature_type = { async SEND_FEATURES_FROM_GEOJSON({ state, dispatch, rootState }, payload) { let { feature_type_slug, geojson } = payload; //* check if geojson then build a file - if(!geojson && !state.fileToImport && state.fileToImport.size === 0 ) return; - let formData = new FormData(); - let fileToImport; + if(!geojson && !state.fileToImport && state.fileToImport.size === 0 ) { + return; + } + const formData = new FormData(); let { name, type } = geojson || state.fileToImport; - if (!name && state.fileToImport) name = state.fileToImport.name; + if (!name && state.fileToImport) { + name = state.fileToImport.name; + } if (rootState.projects.project.moderation) { if (state.fileToImport && state.fileToImport.size > 0) { //* if data in a binary file, read it as text @@ -188,11 +191,11 @@ const feature_type = { type: 'FeatureCollection', features: unmoderatedFeatures }; } - fileToImport = new File([JSON.stringify(geojson)], name, { type }); + const fileToImport = new File([JSON.stringify(geojson)], name, { type }); formData.append('json_file', geojson ? fileToImport : state.fileToImport); formData.append('feature_type_slug', feature_type_slug); - let url = + const url = this.state.configuration.VUE_APP_DJANGO_API_BASE + 'import-tasks/'; return axios @@ -215,10 +218,12 @@ const feature_type = { }, async SEND_FEATURES_FROM_CSV({ state, dispatch }, payload) { - let { feature_type_slug, csv } = payload; - if(!csv && !state.fileToImport && state.fileToImport.size === 0 ) return; + const { feature_type_slug, csv } = payload; + if (!csv && !state.fileToImport && state.fileToImport.size === 0 ) { + return; + } - let formData = new FormData(); + const formData = new FormData(); formData.append('csv_file', state.fileToImport); formData.append('feature_type_slug', feature_type_slug); diff --git a/src/store/modules/feature.store.js b/src/store/modules/feature.store.js index 9c8beff21476bdf8f6ef78f2f002775d75f54a9c..4c7ac5663f952b7d53902c60d367b3a7a38cb624 100644 --- a/src/store/modules/feature.store.js +++ b/src/store/modules/feature.store.js @@ -67,7 +67,9 @@ const feature = { }, UPDATE_ATTACHMENT_FORM(state, payload) { const index = state.attachmentFormset.findIndex((el) => el.dataKey === payload.dataKey); - if (index !== -1) state.attachmentFormset[index] = payload; + if (index !== -1) { + state.attachmentFormset[index] = payload; + } }, REMOVE_ATTACHMENT_FORM(state, payload) { state.attachmentFormset = state.attachmentFormset.filter(form => form.dataKey !== payload); @@ -80,7 +82,9 @@ const feature = { }, UPDATE_LINKED_FORM(state, payload) { const index = state.linkedFormset.findIndex((el) => el.dataKey === payload.dataKey); - if (index !== -1) state.linkedFormset[index] = payload; + if (index !== -1) { + state.linkedFormset[index] = payload; + } }, REMOVE_LINKED_FORM(state, payload) { state.linkedFormset = state.linkedFormset.filter(form => form.dataKey !== payload); @@ -109,8 +113,10 @@ const feature = { state.massMode = payload; }, }, + getters: { }, + actions: { async GET_PROJECT_FEATURES({ commit, rootState }, { project_slug, @@ -143,7 +149,9 @@ const feature = { if (limit) { url = url.concat('', `${url.includes('?') ? '&' : '?'}limit=${limit}`); } - if (geojson) url = url.concat('', '&output=geojson'); + if (geojson) { + url = url.concat('', '&output=geojson'); + } try { const response = await axios.get(url, { cancelToken: cancelToken.token }); @@ -169,7 +177,7 @@ const feature = { const cancelToken = axios.CancelToken.source(); commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true }); //commit('SET_CURRENT_FEATURE', null); //? Est-ce que c'est nécessaire ? -> fait sauter l'affichage au clic sur un signalement lié (feature_detail) - let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/?id=${feature_id}`; + const url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/?id=${feature_id}`; return axios .get(url, { cancelToken: cancelToken.token }) .then((response) => { @@ -215,7 +223,7 @@ const feature = { } function createGeojson() { //* prepare feature data to send - let extraFormObject = {}; //* prepare an object to be flatten in properties of geojson + const extraFormObject = {}; //* prepare an object to be flatten in properties of geojson for (const field of state.extra_form) { extraFormObject[field.name] = field.value; } @@ -264,11 +272,11 @@ const feature = { commit('DISCARD_LOADER', null, { root: true }); if (error.message === 'Network Error' || !rootState.isOnline) { let arraysOffline = []; - let localStorageArray = localStorage.getItem('geocontrib_offline'); + const localStorageArray = localStorage.getItem('geocontrib_offline'); if (localStorageArray) { arraysOffline = JSON.parse(localStorageArray); } - let updateMsg = { + const updateMsg = { project: rootState.projects.project.slug, type: routeName === 'editer-signalement' ? 'put' : 'post', featureId: state.form.feature_id, @@ -295,7 +303,7 @@ const feature = { const DJANGO_API_BASE = rootState.configuration.VUE_APP_DJANGO_API_BASE; function addFile(attachment, attchmtId) { - let formdata = new FormData(); + const formdata = new FormData(); formdata.append('file', attachment.fileToImport, attachment.fileToImport.name); return axios .put(`${DJANGO_API_BASE}features/${featureId}/attachments/${attchmtId}/upload-file/`, formdata) @@ -309,7 +317,7 @@ const feature = { } function putOrPostAttachement(attachment) { - let formdata = new FormData(); + const formdata = new FormData(); formdata.append('title', attachment.title); formdata.append('info', attachment.info); @@ -335,7 +343,7 @@ const feature = { } function deleteAttachement(attachmentsId, featureId) { - let payload = { + const payload = { attachmentsId: attachmentsId, featureId: featureId }; @@ -354,7 +362,7 @@ const feature = { DELETE_ATTACHMENTS({ commit }, payload) { - let url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/${payload.featureId}/attachments/${payload.attachmentsId}/`; + const url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/${payload.featureId}/attachments/${payload.attachmentsId}/`; return axios .delete(url) .then((response) => { @@ -386,7 +394,9 @@ const feature = { const { feature_id, noFeatureType } = payload; let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${feature_id}/?` + `project__slug=${rootState.projects.project.slug}`; - if (!noFeatureType) url +=`&feature_type__slug=${rootState.feature_type.current_feature_type_slug}`; + if (!noFeatureType) { + url +=`&feature_type__slug=${rootState.feature_type.current_feature_type_slug}`; + } return axios .delete(url) .then((response) => response) diff --git a/src/store/modules/map.store.js b/src/store/modules/map.store.js index c73787140532046ad921d000c8f122a3cbcffb00..7e31a4c4ec48d9ae084a3180cbff33c98b9c6a5e 100644 --- a/src/store/modules/map.store.js +++ b/src/store/modules/map.store.js @@ -105,8 +105,8 @@ const map = { }, INITIATE_MAP({ commit }, el) { //todo: since this function is not anymore called in different components, it would better to move it in project_details.vue - let mapDefaultViewCenter = [46, 2]; // defaultMapView.center; - let mapDefaultViewZoom = 5; // defaultMapView.zoom; + const mapDefaultViewCenter = [46, 2]; // defaultMapView.center; + const mapDefaultViewZoom = 5; // defaultMapView.zoom; mapUtil.createMap(el, { mapDefaultViewCenter, mapDefaultViewZoom, @@ -167,7 +167,7 @@ const map = { }, DELETE_BASEMAP({ commit }, basemapId) { - let url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/` + basemapId; + const url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/` + basemapId; return axios .delete(url) .then((response) => { diff --git a/src/store/modules/projects.store.js b/src/store/modules/projects.store.js index 68adf8ddc44f56fa4f074ac47897c7706997c80e..3107a843e5ec424af0cc7740f8aedaba385345fb 100644 --- a/src/store/modules/projects.store.js +++ b/src/store/modules/projects.store.js @@ -116,11 +116,13 @@ const projects = { }, async GET_PROJECT_INFO({ rootState, dispatch }, slug) { - let promises = [ + const promises = [ dispatch('GET_PROJECT_LAST_MESSAGES', slug).then(response => response), dispatch('feature-type/GET_PROJECT_FEATURE_TYPES', slug, { root: true }).then(response => response), ]; - if (rootState.user) promises.push(dispatch('map/GET_BASEMAPS', slug, { root: true }).then(response => response)); + if (rootState.user) { + promises.push(dispatch('map/GET_BASEMAPS', slug, { root: true }).then(response => response)); + } const promiseResult = await Promise.all(promises); return promiseResult; diff --git a/src/views/Catalog.vue b/src/views/Catalog.vue index 3033f489161fd156263febf53c462f61e9cf6ef1..947e826a0bee4f107dbac58f4855e01273eb4a21 100644 --- a/src/views/Catalog.vue +++ b/src/views/Catalog.vue @@ -89,7 +89,7 @@ class="ui fluid teal icon button" @click="launchImport" > - <em class="upload icon" /> Lancer l'import avec le fichier + <i class="upload icon" /> Lancer l'import avec le fichier <span v-if="selectedResource"> {{ selectedResource.resource }} </span> @@ -128,7 +128,7 @@ export default { }, nbPages() { - let N = Math.ceil(this.resources.length / this.pagination.pagesize); + const N = Math.ceil(this.resources.length / this.pagination.pagesize); const arr = [...Array(N).keys()].map(function (x) { ++x; return x; @@ -147,7 +147,9 @@ export default { this.$store.commit('DISPLAY_LOADER', 'Interrogation du catologue datasud.'); this.$store.dispatch('projects/GET_PROJECT', this.$route.params.slug); miscAPI.getIdgoCatalog(this.user.username).then((data) => { - if (data && data.layers) this.resources = data.layers; + if (data && data.layers) { + this.resources = data.layers; + } this.$store.commit('DISCARD_LOADER'); }); }, @@ -197,7 +199,9 @@ export default { launchImport() { const queryParams = `typename=${this.selectedResource.layer}&organization_slug=${this.selectedResource.organization_slug}`; miscAPI.getExternalGeojson(queryParams).then((data) => { - if (data) this.redirect(data); + if (data) { + this.redirect(data); + } }); }, }, diff --git a/src/views/Feature/FeatureDetail.vue b/src/views/Feature/FeatureDetail.vue index 54ef274846b0bdc3ecd6d7c217c7a2047f7808ec..76e2928f09325035de1297082d2ae8b442d96408 100644 --- a/src/views/Feature/FeatureDetail.vue +++ b/src/views/Feature/FeatureDetail.vue @@ -48,12 +48,12 @@ { 'active visible': isCanceling }, ]" > - <em + <i class="close icon" @click="isCanceling = false" /> <div class="ui icon header"> - <em class="trash alternate icon" /> + <i class="trash alternate icon" /> Supprimer le signalement </div> <div class="actions"> @@ -152,7 +152,8 @@ export default { this.DISCARD_LOADER(); this.initMap(); }); - } if (!this.currentFeature || this.currentFeature.feature_id !== this.$route.params.slug_signal) { + } + if (!this.currentFeature || this.currentFeature.feature_id !== this.$route.params.slug_signal) { this.GET_PROJECT_FEATURE({ project_slug: this.$route.params.slug, feature_id: this.$route.params.slug_signal diff --git a/src/views/Feature/FeatureEdit.vue b/src/views/Feature/FeatureEdit.vue index 1f95ceb22f8d4be968597038dda2a24e99df099d..fc9839d8c0328883373458002a0f96744bcad2dc 100644 --- a/src/views/Feature/FeatureEdit.vue +++ b/src/views/Feature/FeatureEdit.vue @@ -82,7 +82,7 @@ class="ui compact button" @click="toggleGeoRefModal" > - <em class="file image icon" />Importer une image géoréférencée + <i class="file image icon" />Importer une image géoréférencée </button> Vous pouvez utiliser une image géoréférencée pour localiser le signalement. @@ -96,7 +96,7 @@ class="ui mini modal transition visible active" style="display: block !important" > - <em + <i class="close icon" @click="toggleGeoRefModal" /> @@ -117,7 +117,7 @@ class="ui icon button" for="image_file" > - <em class="file icon" /> + <i class="file icon" /> <span class="label">{{ geoRefFileLabel }}</span> </label> <input @@ -149,7 +149,7 @@ ]" @click="georeferencement" > - <em class="plus icon" /> + <i class="plus icon" /> Importer </button> </form> @@ -163,7 +163,7 @@ class="ui compact button" @click="create_point_geoposition" > - <em class="ui map marker alternate icon" />Positionner le + <i class="ui map marker alternate icon" />Positionner le signalement à partir de votre géolocalisation </button> </p> @@ -249,7 +249,7 @@ class="ui compact basic button" @click="add_attachement_formset" > - <em class="ui plus icon" />Ajouter une pièce jointe + <i class="ui plus icon" />Ajouter une pièce jointe </button> </div> @@ -272,7 +272,7 @@ class="ui compact basic button" @click="add_linked_formset" > - <em class="ui plus icon" />Ajouter une liaison + <i class="ui plus icon" />Ajouter une liaison </button> </div> <div class="ui divider" /> @@ -281,7 +281,7 @@ class="ui teal icon button" @click="postForm" > - <em class="white save icon" /> Enregistrer les changements + <i class="white save icon" /> Enregistrer les changements </button> </form> </div> @@ -459,7 +459,7 @@ export default { }, mounted() { - let promises = [ + const promises = [ this.$store.dispatch('projects/GET_PROJECT', this.$route.params.slug), this.$store.dispatch('projects/GET_PROJECT_INFO', this.$route.params.slug), ]; @@ -497,7 +497,7 @@ export default { methods: { initForm() { if (this.currentRouteName === 'editer-signalement') { - for (let key in this.feature) { + for (const key in this.feature) { if (key && this.form[key]) { if (key === 'status') { const value = this.feature[key]; @@ -558,7 +558,7 @@ export default { georeferencement() { const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}exif-geom-reader/`; - let formData = new FormData(); + const formData = new FormData(); formData.append('image_file', this.file); axios .post(url, formData, { @@ -568,9 +568,9 @@ export default { }) .then((response) => { if (response.data.geom.indexOf('POINT') >= 0) { - let regexp = /POINT\s\((.*)\s(.*)\)/; - let arr = regexp.exec(response.data.geom); - let json = { + const regexp = /POINT\s\((.*)\s(.*)\)/; + const arr = regexp.exec(response.data.geom); + const json = { type: 'Feature', geometry: { type: 'Point', @@ -607,7 +607,7 @@ export default { const field = feature.feature_data.find((el) => el.label === label); return field ? field.value : null; } - let extraForm = this.feature_type.customfield_set.map((field) => { + const extraForm = this.feature_type.customfield_set.map((field) => { return { ...field, //* add value field to extra forms from feature_type and existing values if feature is defined @@ -914,7 +914,7 @@ export default { 'draw:edited', function (e) { var layers = e.layers; - let self = this; + const self = this; layers.eachLayer(function (layer) { self.updateGeomField(layer.toGeoJSON()); }); @@ -936,7 +936,9 @@ export default { }, updateMap(geomFeatureJSON) { - if (this.drawnItems) this.drawnItems.clearLayers(); + if (this.drawnItems) { + this.drawnItems.clearLayers(); + } var geomType = this.feature_type.geom_type; if (geomFeatureJSON) { var geomJSON = flip(geomFeatureJSON.geometry); @@ -974,7 +976,7 @@ export default { }); const currentFeatureId = this.$route.params.slug_signal; setTimeout(() => { - let project_id = this.$route.params.slug.split('-')[0]; + const project_id = this.$route.params.slug.split('-')[0]; const mvtUrl = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; mapUtil.addVectorTileLayer( @@ -992,10 +994,6 @@ export default { const allFeaturesExceptCurrent = features.filter( (feat) => feat.id !== currentFeatureId ); - console.log(allFeaturesExceptCurrent); - console.log(allFeaturesExceptCurrent[0].geometry); - console.log(allFeaturesExceptCurrent[0].geometry.coordinates); - console.log(allFeaturesExceptCurrent[0].geometry.coordinates[0]); mapUtil.addFeatures( allFeaturesExceptCurrent, {}, @@ -1035,18 +1033,22 @@ export default { changeMobileBtnOrder() { //* move large toolbar for polygon creation, cutting map in the middle function changeDisplay() { - let buttons = document.querySelector('.leaflet-draw-actions.leaflet-draw-actions-top.leaflet-draw-actions-bottom'); + const buttons = document.querySelector('.leaflet-draw-actions.leaflet-draw-actions-top.leaflet-draw-actions-bottom'); if (buttons && buttons.style) { buttons.style.display = 'flex'; buttons.style['flex-direction'] = 'column'; } } if (window.screen.availWidth < 767) { //* change button order all the time to keep homogeinity on mobile - let wrapper = document.querySelector('.leaflet-top.leaflet-right'); - if (wrapper) wrapper.appendChild(wrapper.children[0]); + const wrapper = document.querySelector('.leaflet-top.leaflet-right'); + if (wrapper) { + wrapper.appendChild(wrapper.children[0]); + } if (this.feature_type.geom_type === 'polygon') { //* if it's a polygon, change tools direction to vertical let polygonBtn = document.querySelector('.leaflet-draw-draw-polygon'); //* since elements are generated - if (polygonBtn) polygonBtn.addEventListener('click', changeDisplay); //* it should be done at each click + if (polygonBtn) { + polygonBtn.addEventListener('click', changeDisplay); //* it should be done at each click + } } } }, diff --git a/src/views/Feature/FeatureOffline.vue b/src/views/Feature/FeatureOffline.vue index a568e976b6fe06e2edc44e5dc743fe0ccc08b7b5..8bbe1718e7dff467c10f594dcf6921b1ee310d07 100644 --- a/src/views/Feature/FeatureOffline.vue +++ b/src/views/Feature/FeatureOffline.vue @@ -16,7 +16,7 @@ }" class="ui positive left labeled icon button margin-1" > - <em class="arrow left icon" />Retour au projet + <i class="arrow left icon" />Retour au projet </router-link> </div> </template> diff --git a/src/views/FeatureType/FeatureTypeDetail.vue b/src/views/FeatureType/FeatureTypeDetail.vue index 8c07e4a391456eae7570aa12ab3d15fd28974dd1..75e0ca8a3bc6e9d61c6a1d8a04c517ad178a6a1e 100644 --- a/src/views/FeatureType/FeatureTypeDetail.vue +++ b/src/views/FeatureType/FeatureTypeDetail.vue @@ -72,7 +72,7 @@ :class="['title', { active: showImport && isOnline, nohover: !isOnline }]" @click="toggleShowImport" > - <em class="dropdown icon" /> + <i class="dropdown icon" /> Importer des signalements </div> <div :class="['content', { active: showImport && isOnline }]"> @@ -85,7 +85,7 @@ class="ui icon button ellipsis" for="json_file" > - <em class="file icon" /> + <i class="file icon" /> <span class="label">{{ geojsonFileToImport.name }}</span> </label> <input @@ -103,7 +103,7 @@ class="ui icon button ellipsis" for="csv_file" > - <em class="file icon" /> + <i class="file icon" /> <span class="label">{{ csvFileToImport.name }}</span> </label> <input @@ -142,7 +142,7 @@ class="ui icon button ellipsis" for="json_file" > - <em class="file icon" /> + <i class="file icon" /> <span class="label">{{ fileToImport.name }}</span> </label> <input @@ -191,7 +191,7 @@ class="ui fluid teal icon button" @click="importGeoJson" > - <em class="upload icon" /> Lancer l'import + <i class="upload icon" /> Lancer l'import </button> <ImportTask v-if="importFeatureTypeData && importFeatureTypeData.length" @@ -206,7 +206,7 @@ :class="['title', { active: !showImport }]" @click="toggleShowImport" > - <em class="dropdown icon" /> + <i class="dropdown icon" /> Exporter les signalements </div> <div :class="['content', { active: !showImport }]"> @@ -222,7 +222,7 @@ class="ui fluid teal icon button" @click="geojsonFileToImport.size !== 0 ? importGeoJson() : importCSV()" > - <em class="download icon" /> Exporter + <i class="download icon" /> Exporter </button> </div> </div> @@ -232,7 +232,7 @@ :class="['title', { active: !showImport && isOnline, nohover: !isOnline }]" @click="toggleShowImport" > - <em class="dropdown icon" /> + <i class="dropdown icon" /> Exporter les signalements </div> <div :class="['content', { active: !showImport && isOnline}]"> @@ -243,7 +243,7 @@ <!-- <div class="ui selection dropdown fluid"> <input type="hidden" name="format"> - <em class="dropdown icon"></em> + <i class="dropdown icon"></em> <div class="default text">Format</div> <div class="menu"> <div class="item" data-value="1">GeoJSON</div> @@ -269,7 +269,7 @@ class="ui fluid teal icon button" @click="exportFeatures" > - <em class="download icon" /> Exporter + <i class="download icon" /> Exporter </button> </div> </div> @@ -318,25 +318,25 @@ v-if="feature.status === 'archived'" data-tooltip="Archivé" > - <em class="grey archive icon" /> + <i class="grey archive icon" /> </span> <span v-else-if="feature.status === 'pending'" data-tooltip="En attente de publication" > - <em class="teal hourglass outline icon" /> + <i class="teal hourglass outline icon" /> </span> <span v-else-if="feature.status === 'published'" data-tooltip="Publié" > - <em class="olive check icon" /> + <i class="olive check icon" /> </span> <span v-else-if="feature.status === 'draft'" data-tooltip="Brouillon" > - <em class="orange pencil alternate icon" /> + <i class="orange pencil alternate icon" /> </span> <router-link :to="{ @@ -371,7 +371,7 @@ :to="{ name: 'liste-signalements', params: { slug } }" class="ui right labeled icon button margin-25" > - <em class="right arrow icon" /> + <i class="right arrow icon" /> Voir tous les signalements </router-link> <router-link @@ -474,33 +474,38 @@ export default { }, structure: function () { if (Object.keys(this.feature_types).length) { - let st = this.feature_types.find( + const st = this.feature_types.find( (el) => el.slug === this.$route.params.feature_type_slug ); - if (st) return st; + if (st) { + return st; + } } return {}; }, feature_type_features: function () { - if (this.features.length) + if (this.features.length) { return this.features.filter( (el) => el.feature_type.slug === this.$route.params.feature_type_slug ); + } return {}; }, lastFeatures: function () { - if (this.feature_type_features.length) + if (this.feature_type_features.length) { return this.feature_type_features.slice(0, 5); + } return []; }, orderedCustomFields() { - if (Object.keys(this.structure).length) + if (Object.keys(this.structure).length) { return [...this.structure.customfield_set].sort( (a, b) => a.position - b.position ); + } return {}; }, }, @@ -689,7 +694,7 @@ export default { return; } - let reader = new FileReader(); + const reader = new FileReader(); reader.addEventListener('load', (e) => { // bypass json check for files larger then 10 Mo let jsonValidity; @@ -714,15 +719,13 @@ export default { onCsvFileChange(e) { this.loadingImportFile = true; const files = e.target.files || e.dataTransfer.files; - console.log(files); if (!files.length) { this.loadingImportFile = false; return; } - let reader = new FileReader(); + const reader = new FileReader(); reader.addEventListener('load', (e) => { - console.log(e); // bypass csv check for files larger then 10 Mo let csvValidity; if (parseFloat(fileConvertSizeToMo(files[0].size)) <= 10) { @@ -745,7 +748,7 @@ export default { importGeoJson() { this.waitMessage = true; - let payload = { + const payload = { slug: this.slug, feature_type_slug: this.$route.params.feature_type_slug, }; @@ -765,7 +768,7 @@ export default { importCSV() { this.waitMessage = true; - let payload = { + const payload = { slug: this.slug, feature_type_slug: this.$route.params.feature_type_slug, }; diff --git a/src/views/FeatureType/FeatureTypeEdit.vue b/src/views/FeatureType/FeatureTypeEdit.vue index 9b013bd1a68bf46b44f5946d583fecaf33ffd721..66209641c87bb86747b7c347c8b9bdcf3e98c4de 100644 --- a/src/views/FeatureType/FeatureTypeEdit.vue +++ b/src/views/FeatureType/FeatureTypeEdit.vue @@ -11,7 +11,7 @@ v-if="error" class="ui negative message" > - <p><em class="cross icon" /> {{ error }}</p> + <p><i class="cross icon" /> {{ error }}</p> </div> </div> <div class="fourteen wide column"> @@ -213,7 +213,7 @@ " @click="setCSVCoordsFields" > - <em class="white save icon" /> + <i class="white save icon" /> Continuer </button> </div> --> @@ -237,7 +237,7 @@ class="ui compact basic button" @click="addCustomForm" > - <em class="ui plus icon" />Ajouter un champ personnalisé + <i class="ui plus icon" />Ajouter un champ personnalisé </button> <div class="ui divider" /> @@ -246,7 +246,7 @@ type="button" @click="sendFeatureType" > - <em class="white save icon" /> + <i class="white save icon" /> {{ action === "create" ? "Créer" : "Sauvegarder" }} le type de signalement </button> @@ -256,7 +256,7 @@ type="button" @click="postFeatureTypeThenFeatures" > - <em class="white save icon" /> + <i class="white save icon" /> Créer et importer le(s) signalement(s) du geojson </button> </div> @@ -553,7 +553,9 @@ export default { fillFormData(formData) { for (const el in formData) { // * find feature_type and fill form values - if (this.form[el]) this.form[el].value = formData[el]; + if (this.form[el]) { + this.form[el].value = formData[el]; + } } //! add custom fields using ONLY this function, incrementing dataKey for Vue to correctly update components formData.customfield_set.forEach((el) => this.addCustomForm(el)); @@ -577,7 +579,7 @@ export default { } //* if modified or deleted } else { - let modifiedColorStyle = {}; + const modifiedColorStyle = {}; for (const [index, key] of newOptions.entries()) { //* if no key then item will disappear (deleted) if (key) { @@ -601,12 +603,13 @@ export default { checkCustomForms() { let is_valid = true; - if (this.$refs.customForms) + if (this.$refs.customForms) { for (const customForm of this.$refs.customForms) { if (customForm.checkCustomForm() === false) { is_valid = false; } } + } return is_valid; //* fallback if all customForms returned true }, diff --git a/src/views/FeatureType/FeatureTypeSymbology.vue b/src/views/FeatureType/FeatureTypeSymbology.vue index 4ed4de46de41d5540db3b6838b2c9c6ae3ddfa8b..39d0eb96f97bd192f366ad604a8b560ff7b9f21b 100644 --- a/src/views/FeatureType/FeatureTypeSymbology.vue +++ b/src/views/FeatureType/FeatureTypeSymbology.vue @@ -14,13 +14,13 @@ v-if="error" class="ui negative message" > - <p><em class="close icon" /> {{ error }}</p> + <p><i class="close icon" /> {{ error }}</p> </div> <div v-if="success" class="ui positive message" > - <em + <i class="close icon" @click="success = null" /> @@ -103,7 +103,7 @@ :disabled="!canSaveSymbology" @click="sendFeatureSymbology" > - <em class="white save icon" /> + <i class="white save icon" /> Sauvegarder la symbologie du type de signalement </button> </form> diff --git a/src/views/FlatPages/LegalMentions.vue b/src/views/FlatPages/LegalMentions.vue index 46a5ff9bccf2f6e18d4fcb81c189be7da932c87c..4ef2a792c3dbe2ed672108df7d47a23b7610bb76 100644 --- a/src/views/FlatPages/LegalMentions.vue +++ b/src/views/FlatPages/LegalMentions.vue @@ -63,11 +63,11 @@ export default { methods: { createMenu() { // parse the ToC content (looking for h2 elements) - let list = document.querySelectorAll('h2'); - let tocArr = []; + const list = document.querySelectorAll('h2'); + const tocArr = []; for (let i = 0; i < list.length; i++) { - let e = list[i]; + const e = list[i]; let id = e.id; // add id in html if not present diff --git a/src/views/Login.vue b/src/views/Login.vue index 904ea9b70c2dbaed70e253fc9f170408bab1efe2..41b036981c4a3a265bcb2ae92af58260f2dd7ef2 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -41,7 +41,7 @@ <div class="ui stacked secondary segment"> <div class="six field required"> <div class="ui left icon input"> - <em class="user icon" /> + <i class="user icon" /> <input v-model="username_value" type="text" @@ -52,7 +52,7 @@ </div> <div class="six field required"> <div class="ui left icon input"> - <em class="lock icon" /> + <i class="lock icon" /> <input v-model="password_value" type="password" diff --git a/src/views/Project/FeaturesListAndMap.vue b/src/views/Project/FeaturesListAndMap.vue index 08c9d8d64262825e23a3db039ce83306f8a16c61..e1d8e775459d4bd99bfcae2438e9d246bf59efe4 100644 --- a/src/views/Project/FeaturesListAndMap.vue +++ b/src/views/Project/FeaturesListAndMap.vue @@ -21,14 +21,14 @@ data-tooltip="Carte" data-position="bottom left" @click="showMap = true" - ><em class="map fitted icon" /></a> + ><i class="map fitted icon" /></a> <a :class="['item no-margin', { active: !showMap }]" data-tab="list" data-tooltip="Liste" data-position="bottom left" @click="showMap = false" - ><em class="list fitted icon" /></a> + ><i class="list fitted icon" /></a> <div class="item"> <h4> {{ featuresCount }} signalement{{ featuresCount > 1 ? "s" : "" }} @@ -50,7 +50,7 @@ data-position="bottom right" @click="toggleAddFeature" > - <em class="plus fitted icon" /> + <i class="plus fitted icon" /> <div v-if="showAddFeature" class="menu left transition visible" @@ -82,7 +82,7 @@ data-position="bottom right" @click="toggleModifyStatus" > - <em class="pencil fitted icon" /> + <i class="pencil fitted icon" /> <div v-if="showModifyStatus" class="menu left transition visible" @@ -111,7 +111,7 @@ data-position="bottom right" @click="toggleDeleteModal" > - <em class="grey trash fitted icon" /> + <i class="grey trash fitted icon" /> </div> </div> </div> @@ -146,7 +146,7 @@ <div class="field wide four column"> <label>Nom</label> <div class="ui icon input"> - <em class="search icon" /> + <i class="search icon" /> <div class="ui action input"> <input v-model="form.title" @@ -159,7 +159,7 @@ class="ui teal icon button" @click="resetPaginationNfetchFeatures" > - <em class="search icon" /> + <i class="search icon" /> </button> </div> </div> @@ -218,12 +218,12 @@ { 'active visible': isDeleteModalOpen }, ]" > - <em + <i class="close icon" @click="isDeleteModalOpen = false" /> <div class="ui icon header"> - <em class="trash alternate icon" /> + <i class="trash alternate icon" /> Êtes-vous sûr de vouloir effacer <span v-if="checkedFeatures.length === 1"> un signalement ? </span> <span v-else> ces {{ checkedFeatures.length }} signalements ? </span> @@ -455,7 +455,7 @@ export default { async modifyStatus(newStatus) { if (this.checkedFeatures.length > 0) { const feature_id = this.checkedFeatures[0]; - let feature = this.clickedFeatures.find((el) => el.feature_id === feature_id); + const feature = this.clickedFeatures.find((el) => el.feature_id === feature_id); if (feature) { featureAPI.updateFeature({ feature_id, @@ -464,7 +464,7 @@ export default { newStatus }).then((response) => { if (response && response.data && response.status === 200) { - let newCheckedFeatures = [...this.checkedFeatures]; + const newCheckedFeatures = [...this.checkedFeatures]; newCheckedFeatures.splice(this.checkedFeatures.indexOf(response.data.id), 1); this.UPDATE_CHECKED_FEATURES(newCheckedFeatures); this.modifyStatus(newStatus); @@ -588,12 +588,18 @@ export default { buildQueryString() { let urlParams = ''; - let typeFilter = this.getFeatureTypeSlug(this.form.type.selected); - let statusFilter = this.form.status.selected.value; + const typeFilter = this.getFeatureTypeSlug(this.form.type.selected); + const statusFilter = this.form.status.selected.value; - if (typeFilter) urlParams += `&feature_type_slug=${typeFilter}`; - if (statusFilter) urlParams += `&status__value=${statusFilter}`; - if (this.form.title) urlParams += `&title=${this.form.title}`; + if (typeFilter) { + urlParams += `&feature_type_slug=${typeFilter}`; + } + if (statusFilter) { + urlParams += `&status__value=${statusFilter}`; + } + if (this.form.title) { + urlParams += `&title=${this.form.title}`; + } if (this.sort.column) { urlParams += `&ordering=${ this.sort.ascending ? '-' : '' diff --git a/src/views/Project/ProjectBasemaps.vue b/src/views/Project/ProjectBasemaps.vue index f0ef8a8416f5886be01fd0bd1ba646219db8929b..a2cc746e0c6d28c31645a6ffdd4272aa1c69105b 100644 --- a/src/views/Project/ProjectBasemaps.vue +++ b/src/views/Project/ProjectBasemaps.vue @@ -15,7 +15,7 @@ style="text-align: left" > <div class="header"> - <em class="info circle icon" /> Informations + <i class="info circle icon" /> Informations </div> {{ message.comment }} </div> @@ -39,7 +39,7 @@ data-variation="mini" @click="addBasemap" > - <em class="ui plus icon" /> + <i class="ui plus icon" /> <span> Créer un fond cartographique</span> </a> </div> @@ -60,7 +60,7 @@ class="ui teal icon floated button" @click="saveChanges" > - <em class="white save icon" /> Enregistrer les changements + <i class="white save icon" /> Enregistrer les changements </button> </div> </form> diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue index d858d924ff5fc8ee7f936aa5caf5a3c693442745..1d69e610a1feb4312e3d362137e435838f9bc9cf 100644 --- a/src/views/Project/ProjectDetail.vue +++ b/src/views/Project/ProjectDetail.vue @@ -13,7 +13,7 @@ v-if="tempMessage" class="ui positive message" > - <p><em class="check icon" /> {{ tempMessage }}</p> + <p><i class="check icon" /> {{ tempMessage }}</p> </div> </div> <div @@ -26,7 +26,7 @@ style="text-align: left" > <div class="header"> - <em class="info circle icon" /> Informations + <i class="info circle icon" /> Informations </div> <ul class="list"> {{ @@ -91,7 +91,7 @@ </div> <span v-else-if="!projectInfoLoading"> - <em class="icon exclamation triangle" /> + <i class="icon exclamation triangle" /> <span>Vous ne disposez pas des droits nécessaires pour consulter ce projet.</span> </span> @@ -268,8 +268,10 @@ export default { this.DISCARD_LOADER(); this.projectInfoLoading = false; setTimeout(() => { - let map = mapUtil.getMap(); - if (map) map.remove(); + const map = mapUtil.getMap(); + if (map) { + map.remove(); + } this.initMap(); }, 1000); }) @@ -317,12 +319,13 @@ export default { .then((data) => { this.is_suscriber = data.is_suscriber; this.modalType = false; - if (this.is_suscriber) + if (this.is_suscriber) { this.infoMessage = 'Vous êtes maintenant abonné aux notifications de ce projet.'; - else + } else { this.infoMessage = 'Vous ne recevrez plus les notifications de ce projet.'; + } setTimeout(() => (this.infoMessage = ''), 3000); }); }, @@ -388,7 +391,7 @@ export default { if (this.project && this.permissions.can_view_project) { await this.INITIATE_MAP(this.$refs.map); this.checkForOfflineFeature(); - let project_id = this.$route.params.slug.split('-')[0]; + const project_id = this.$route.params.slug.split('-')[0]; const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; mapUtil.addVectorTileLayer( mvtUrl, diff --git a/src/views/Project/ProjectEdit.vue b/src/views/Project/ProjectEdit.vue index 7e1a43f3b258c543a716d61bc9839475b64e3c1b..5d7fcc13c2aa3c794c250000524d71140a757381 100644 --- a/src/views/Project/ProjectEdit.vue +++ b/src/views/Project/ProjectEdit.vue @@ -64,7 +64,7 @@ class="ui icon button" for="thumbnail" > - <em class="file icon" /> + <i class="file icon" /> <span class="label">{{ form.thumbnail_name ? form.thumbnail_name : fileToImport.name }}</span> @@ -239,7 +239,7 @@ class="ui teal icon button" @click="postForm" > - <em class="white save icon" /> Enregistrer les changements + <i class="white save icon" /> Enregistrer les changements </button> </form> </div> @@ -308,15 +308,16 @@ export default { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, levelPermissions(){ - let levels = new Array(); - if(this.levelsPermissions){ + const levels = new Array(); + if(this.levelsPermissions) { this.levelsPermissions.forEach((item) => { - if (item.user_type_id !== 'super_contributor') + if (item.user_type_id !== 'super_contributor') { levels.push({ name: this.translateRoleToFrench(item.user_type_id), value: item.user_type_id, }); - if (!this.form.moderation && item.user_type_id == 'moderator'){ + } + if (!this.form.moderation && item.user_type_id == 'moderator') { levels.pop(); } }); @@ -324,12 +325,14 @@ export default { return levels; }, levelPermissionsPub(){ - let levels = new Array(); - if(this.levelsPermissions){ + const levels = new Array(); + if (this.levelsPermissions) { this.levelsPermissions.forEach((item) => { - if (item.user_type_id !== 'super_contributor' - && item.user_type_id !== 'admin' - && item.user_type_id !== 'moderator'){ + if ( + item.user_type_id !== 'super_contributor' && + item.user_type_id !== 'admin' && + item.user_type_id !== 'moderator' + ) { levels.push({ name: this.translateRoleToFrench(item.user_type_id), value: item.user_type_id, @@ -357,7 +360,9 @@ export default { if (!this.project) { this.$store.dispatch('projects/GET_PROJECT', this.$route.params.slug) .then((projet) => { - if (projet) this.fillProjectForm(); + if (projet) { + this.fillProjectForm(); + } }); } else { this.fillProjectForm(); @@ -395,7 +400,7 @@ export default { }, truncate(n, len) { - let ext = n.substring(n.lastIndexOf('.') + 1, n.length).toLowerCase(); + const ext = n.substring(n.lastIndexOf('.') + 1, n.length).toLowerCase(); let filename = n.replace('.' + ext, ''); if (filename.length <= len) { return n; @@ -405,8 +410,8 @@ export default { }, validateImgFile(files, handleFile) { - let url = window.URL || window.webkitURL; - let image = new Image(); + const url = window.URL || window.webkitURL; + const image = new Image(); image.onload = function () { handleFile(true); URL.revokeObjectURL(image.src); @@ -426,7 +431,7 @@ export default { function handleFile(isValid) { if (isValid) { _this.fileToImport = files[0]; //* store the file to post later - let reader = new FileReader(); //* read the file to display in the page + const reader = new FileReader(); //* read the file to display in the page reader.onload = function (e) { _this.thumbnailFileSrc = e.target.result; }; @@ -447,8 +452,12 @@ export default { checkEmpty() { //* forbid empty fields - if (!this.form.archive_feature) this.form.archive_feature = 0; - if (!this.form.delete_feature) this.form.delete_feature = 0; + if (!this.form.archive_feature) { + this.form.archive_feature = 0; + } + if (!this.form.delete_feature) { + this.form.delete_feature = 0; + } }, goBackNrefresh(slug) { @@ -468,7 +477,7 @@ export default { postProjectThumbnail(projectSlug) { //* send img to the backend when feature_type is created if (this.fileToImport) { - let formData = new FormData(); + const formData = new FormData(); formData.append('file', this.fileToImport); const url = this.$store.state.configuration.VUE_APP_DJANGO_API_BASE + @@ -489,7 +498,9 @@ export default { .catch((error) => { let err_msg = "Transférez une image valide. Le fichier que vous avez transféré n'est pas une image, ou il est corrompu."; - if (error.response.data[0]) err_msg = error.response.data[0]; + if (error.response.data[0]) { + err_msg = error.response.data[0]; + } this.errorThumbnail.push(err_msg); throw error; }); @@ -522,7 +533,9 @@ export default { }, async postForm() { - if (!this.checkForm()) return; + if (!this.checkForm()) { + return; + } const projectData = { title: this.form.title, description: this.form.description, @@ -595,7 +608,7 @@ export default { } //* transform string values to objects for dropdowns display (could be in a computed) if (this.levelPermissionsPub) { - let value = this.levelPermissionsPub.find( + const value = this.levelPermissionsPub.find( (el) => el.name === this.project.access_level_pub_feature ); if(value){ @@ -606,7 +619,7 @@ export default { } } if (this.levelPermissions) { - let value = this.levelPermissions.find( + const value = this.levelPermissions.find( (el) => el.name === this.project.access_level_arch_feature ); if(value){ diff --git a/src/views/Project/ProjectMembers.vue b/src/views/Project/ProjectMembers.vue index 41f117594bf94f9ac4de85f26f95f285e025c52d..27986572f40e25ccf67d773c93ad86f6efe38d98 100644 --- a/src/views/Project/ProjectMembers.vue +++ b/src/views/Project/ProjectMembers.vue @@ -49,7 +49,7 @@ :disabled="!newMember.user.name" @click="addMember" > - <em class="white add icon" /> + <i class="white add icon" /> <span class="padding-1">Ajouter</span> </button> </div> @@ -64,7 +64,7 @@ <tr> <th> Membre - <em + <i :class="{ down: isSortedAsc('member'), up: isSortedDesc('member'), @@ -75,7 +75,7 @@ </th> <th> Niveau d'autorisation - <em + <i :class="{ down: isSortedAsc('role'), up: isSortedDesc('role'), @@ -108,7 +108,7 @@ data-tooltip="Retirer ce membre" @click="removeMember(member)" > - <em class="times icon" /> + <i class="times icon" /> </button> </div> </td> @@ -123,7 +123,7 @@ class="ui teal icon button" @click="saveMembers" > - <em class="white save icon" /> Enregistrer les changements + <i class="white save icon" /> Enregistrer les changements </button> </div> </div> diff --git a/src/views/Projects/ProjectsList.vue b/src/views/Projects/ProjectsList.vue index 41da0d7e04c15fe414708c0111a342cf2126a7ec..e817ef18b74dd81cadf5f5f81a8f1578ae079e7c 100644 --- a/src/views/Projects/ProjectsList.vue +++ b/src/views/Projects/ProjectsList.vue @@ -13,7 +13,7 @@ :to="{ name: 'project_create', params: { action: 'create' } }" class="ui green basic button" > - <em class="plus icon" /> Créer un nouveau projet + <i class="plus icon" /> Créer un nouveau projet </router-link> <router-link v-if="user && user.can_create_project && isOnline" @@ -22,7 +22,7 @@ }" class="ui blue basic button" > - <em class="copy icon" /> Accéder à la liste des modèles de projets + <i class="copy icon" /> Accéder à la liste des modèles de projets </router-link> </div> diff --git a/src/views/Projects/ProjectsTypes.vue b/src/views/Projects/ProjectsTypes.vue index 30e644b9e71cad832e89f933abb31e720e49ba14..72457c2f8eda5aafa873e312f3335291d0771011 100644 --- a/src/views/Projects/ProjectsTypes.vue +++ b/src/views/Projects/ProjectsTypes.vue @@ -38,25 +38,25 @@ </div> <div class="meta"> <span data-tooltip="Délai avant archivage"> - {{ project.archive_feature }} <em class="box icon" /> + {{ project.archive_feature }} <i class="box icon" /> </span> <span data-tooltip="Délai avant suppression"> - {{ project.archive_feature }} <em + {{ project.archive_feature }} <i class="trash alternate icon" /> </span> <span data-tooltip="Date de création"> - {{ project.created_on }} <em class="calendar icon" /> + {{ project.created_on }} <i class="calendar icon" /> </span> </div> <div class="meta"> <span data-tooltip="Visibilité des signalement publiés"> - {{ project.access_level_pub_feature }} <em + {{ project.access_level_pub_feature }} <i class="eye icon" /> </span> <span data-tooltip="Visibilité des signalement archivés"> - {{ project.access_level_arch_feature }} <em + {{ project.access_level_arch_feature }} <i class="archive icon" /> </span> @@ -94,7 +94,9 @@ export default { mounted() { projectAPI.getProjectTypes(this.API_BASE_URL) .then((data) => { - if (data) this.project_types = data; + if (data) { + this.project_types = data; + } }); },