Skip to content
Snippets Groups Projects
Commit bcbc4607 authored by Sébastien DA ROCHA's avatar Sébastien DA ROCHA :bicyclist:
Browse files

Merge branch 'redmine-issue/13469' into 'develop'

parents 6bf57c75 8e5ffa9b
No related branches found
No related tags found
No related merge requests found
Showing
with 114 additions and 111 deletions
sonar.sources = src
sonar.exclusions = build/**, node_modules/**
#sonar.tests = api/tests/
......@@ -22,12 +22,12 @@
:key="'message-' + index"
:class="['ui', message.level ? message.level : 'info', 'message']"
>
<i
<em
class="close icon"
@click="DISCARD_MESSAGE(message)"
/>
<div class="header">
<i class="info circle icon" />
<em class="info circle icon" />
Informations
</div>
<ul class="list">
......
......@@ -298,7 +298,7 @@ const mapUtil = {
return featureType.color;
},
addVectorTileLayer: function (url, project_slug, featureTypes, form_filters) {
addVectorTileLayer: function (url, projectSlug, featureTypes, formFilters) {
layerMVT = L.vectorGrid.protobuf(url, {
noWrap:true,
vectorTileLayerStyles: {
......@@ -326,23 +326,22 @@ const mapUtil = {
fill: true,
color: colorValue,
};
// Filtre sur le feature type
if (form_filters && form_filters.type.selected) {
if (featureType.title !== form_filters.type.selected) {
if (formFilters && formFilters.type.selected) {
if (featureType.title !== formFilters.type.selected) {
return hiddenStyle;
}
}
// Filtre sur le statut
if (form_filters && form_filters.status.selected.value) {
if (properties.status !== form_filters.status.selected.value) {
if (formFilters && formFilters.status.selected.value) {
if (properties.status !== formFilters.status.selected.value) {
return hiddenStyle;
}
}
// Filtre sur le titre
if (form_filters && form_filters.title) {
if (!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())) {
if (formFilters && formFilters.title) {
if (!properties.title.toLowerCase().includes(formFilters.title.toLowerCase())) {
return hiddenStyle;
}
}
......@@ -358,7 +357,7 @@ const mapUtil = {
}
});
layerMVT.on('click', (e) => { // The .on method attaches an event handler
const popupContent = this._createContentPopup(e.layer, featureTypes, project_slug);
const popupContent = this._createContentPopup(e.layer, featureTypes, projectSlug);
L.popup()
.setContent(popupContent)
.setLatLng(e.latlng)
......@@ -368,7 +367,7 @@ const mapUtil = {
window.layerMVT = layerMVT;
},
addFeatures: function (features, filter, addToMap = true, featureTypes, project_slug) {
addFeatures: function (features, filter, addToMap = true, featureTypes, projectSlug) {
const featureGroup = new L.FeatureGroup();
features.forEach((feature) => {
const featureProperties = feature.properties ? feature.properties : feature;
......@@ -389,7 +388,7 @@ const mapUtil = {
filters.length && filters.every(val => val !== false)
) {
const geomJSON = flip(feature.geometry || feature.geom);
const popupContent = this._createContentPopup(feature, featureTypes, project_slug);
const popupContent = this._createContentPopup(feature, featureTypes, projectSlug);
// Look for a custom field
let customField;
......@@ -425,10 +424,10 @@ const mapUtil = {
featureType.colors_style.value.icons[customFieldOption] !== 'circle'
) {
const iconHTML = `
<i
<em
class="fas fa-${featureType.colors_style.value.icons[customFieldOption]} fa-lg"
style="color: ${color}"
></i>
></em>
`;
const customMapIcon = L.divIcon({
html: iconHTML,
......@@ -455,10 +454,10 @@ const mapUtil = {
} else {
if (featureType.icon && featureType.icon !== 'circle') {
const iconHTML = `
<i
<em
class="fas fa-${featureType.icon} fa-lg"
style="color: ${color}"
></i>
></em>
`;
const customMapIcon = L.divIcon({
html: iconHTML,
......@@ -512,39 +511,39 @@ const mapUtil = {
map.on(eventName, callback);
},
_createContentPopup: function (feature, featureTypes, project_slug) {
const formatDate = (current_datetime) => {
let formatted_date = current_datetime.getFullYear() + '-' + ('0' + (current_datetime.getMonth() + 1)).slice(-2) + '-' + ('0' + current_datetime.getDate()).slice(-2) + ' ' +
('0' + current_datetime.getHours()).slice(-2) + ':' + ('0' + current_datetime.getMinutes()).slice(-2);
return formatted_date;
_createContentPopup: function (feature, featureTypes, projectSlug) {
const formatDate = (currentDatetime) => {
let 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;
};
let feature_type = feature.properties ? feature.properties.feature_type : feature.feature_type;
let feature_url = feature.feature_url;
let featureType = feature.properties ? feature.properties.feature_type : feature.feature_type;
let featureUrl = feature.feature_url;
let status = feature.status;
let feature_type_url = feature.feature_type_url;
let date_maj = feature.updated_on;
let featureTypeUrl = feature.feature_type_url;
let dateMaj = feature.updated_on;
if (feature.properties) {
status = feature.properties.status;
date_maj = feature.properties.updated_on ? formatDate(new Date(feature.properties.updated_on)) : '<i>indisponible</i>';
feature_type_url = feature.properties.feature_type_url;
feature_url = feature.properties.feature_url;
dateMaj = feature.properties.updated_on ? formatDate(new Date(feature.properties.updated_on)) : '<em>indisponible</em>';
featureTypeUrl = feature.properties.feature_type_url;
featureUrl = feature.properties.feature_url;
}
if (featureTypes && feature.properties) { // => VectorTile
feature_type = feature.properties.feature_type_id ?
featureType = feature.properties.feature_type_id ?
featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.properties.feature_type_id) :
featureTypes.find((f_type) => f_type.slug === feature.properties.feature_type); //* geojson
featureTypes.find((fType) => fType.slug === feature.properties.feature_type); //* geojson
status = statusList.find((x) => x.value === feature.properties.status.value).name;
if (feature_type) feature_type_url = '/geocontrib/projet/' + project_slug + '/type-signalement/' + feature_type.slug + '/';
feature_url = feature_type_url + 'signalement/' + feature.properties.feature_id + '/';
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;
}
//* adapt link url for shared-project restricted navigation
if (window.location.pathname.includes('projet-partage')) {
feature_url = feature_url.replace('projet', 'projet-partage');
feature_type_url = feature_type_url.replace('projet', 'projet-partage');
featureUrl = featureUrl.replace('projet', 'projet-partage');
featureTypeUrl = featureTypeUrl.replace('projet', 'projet-partage');
}
let author = '';
const creator = feature.properties ? feature.properties.creator : feature.creator;
......@@ -557,28 +556,28 @@ const mapUtil = {
}
let title = feature.properties ? feature.properties.title : feature.title;
if (feature_url) {
title = `<a href="${feature_url}">${title}</a>`;
if (featureUrl) {
title = `<a href="${featureUrl}">${title}</a>`;
} else {
title = `<span>${title|| '<i>indisponible</i>'}</span>`;
title = `<span>${title|| '<em>indisponible</em>'}</span>`;
}
if (feature_type_url) {
`<a href="${feature_type_url}"> ${feature_type.title || '<i>indisponible</i>'} </a>`;
if (featureTypeUrl) {
`<a href="${featureTypeUrl}"> ${featureType.title || '<em>indisponible</em>'} </a>`;
}
return `
<h4>
<${feature_url ? 'a href="' + feature_url + '"' : 'span'}>${title || '<i>indisponible</i>'}</${feature_url ? 'a' : 'span'}>
<${featureUrl ? `a href="${featureUrl}"` : 'span'}>${title || '<em>indisponible</em>'}</${featureUrl ? 'a' : 'span'}>
</h4>
<div>
Statut : ${status || '<i>indisponible</i>'}
Statut : ${status || '<em>indisponible</em>'}
</div>
<div>
Type : <${feature_type_url ? 'a href="'+ feature_type_url + '"' : 'span'}> ${feature_type.title || '<i>indisponible</i>'} </${feature_type_url ? 'a' : 'span'}>
Type : <${featureTypeUrl ? `a href="${featureTypeUrl}"` : 'span'}> ${featureType.title || '<em>indisponible</em>'} </${featureTypeUrl ? 'a' : 'span'}>
</div>
<div>
Dernière mise à jour : ${date_maj || '<i>indisponible</i>'}
Dernière mise à jour : ${dateMaj || '<em>indisponible</em>'}
</div>
${author}
`;
......
......@@ -195,7 +195,6 @@ body {
opacity: 0.9;
}
/* */
/* ---------------------------------- */
/* LEAFLET DRAW TOOLBAR */
......
......@@ -57,7 +57,7 @@
<span v-if="item.object_type === 'feature'">
Signalement supprimé({{ item.data.feature_title }})
</span>
<i v-else>Événement inconnu</i>
<em v-else>Événement inconnu</em>
</span>
<span
v-if="item.object_type !== 'project'"
......@@ -69,17 +69,17 @@
}})
</span>
<div class="description">
<i>[ {{ item.created_on }}
<em>[ {{ item.created_on }}
<span v-if="user.is_authenticated">
, par {{ item.display_user }}
</span>
]</i>
]</em>
</div>
</div>
</div>
<i
<em
v-if="!events || events.length === 0"
>Aucune notification pour le moment.</i>
>Aucune notification pour le moment.</em>
</div>
</div>
</div>
......@@ -110,17 +110,17 @@
><del>{{ item.data.feature_title }}</del>&nbsp;(supprimé)</span>
</div>
<div class="description">
<i>[ {{ item.created_on }}
<em>[ {{ item.created_on }}
<span v-if="user.is_authenticated">
, par {{ item.display_user }}
</span>
]</i>
]</em>
</div>
</div>
</div>
<i
<em
v-if="!features || features.length === 0"
>Aucun signalement pour le moment.</i>
>Aucun signalement pour le moment.</em>
</div>
</div>
</div>
......@@ -146,17 +146,17 @@
>"{{ item.related_comment.comment }}"</a>
</div>
<div class="description">
<i>[ {{ item.created_on }}
<em>[ {{ item.created_on }}
<span v-if="user.is_authenticated">
, par {{ item.display_user }}
</span>
]</i>
]</em>
</div>
</div>
</div>
<i
<em
v-if="!comments || comments.length === 0"
>Aucun commentaire pour le moment.</i>
>Aucun commentaire pour le moment.</em>
</div>
</div>
</div>
......@@ -170,7 +170,7 @@ import { mapState } from 'vuex';
import miscAPI from '@/services/misc-api';
export default {
name: 'UserActivity',
data() {
......@@ -214,4 +214,4 @@ export default {
}
};
</script>
\ No newline at end of file
</script>
......@@ -56,7 +56,7 @@
import { mapState } from 'vuex';
export default {
name: 'UserProfile',
computed: {
......@@ -66,7 +66,7 @@ export default {
userFullname() {
if (this.user.first_name || this.user.last_name)
return this.user.first_name + ' ' + this.user.last_name;
return `${this.user.first_name} ${this.user.last_name}`;
return null;
},
}
......@@ -76,4 +76,4 @@ export default {
<style lang="less" scoped>
</style>
\ No newline at end of file
</style>
......@@ -66,18 +66,18 @@
class="right floated"
:data-tooltip="`Projet créé le ${project.created_on}`"
>
<i class="calendar icon" />&nbsp;{{ project.created_on }}
<em class="calendar icon" />&nbsp;{{ project.created_on }}
</span>
<span data-tooltip="Membres">
{{ project.nb_contributors }}&nbsp;<i class="user icon" />
{{ project.nb_contributors }}&nbsp;<em class="user icon" />
</span>
<span data-tooltip="Signalements publiés">
{{ project.nb_published_features }}&nbsp;<i
{{ project.nb_published_features }}&nbsp;<em
class="map marker icon"
/>
</span>
<span data-tooltip="Commentaires">
{{ project.nb_published_features_comments }}&nbsp;<i
{{ project.nb_published_features_comments }}&nbsp;<em
class="comment icon"
/>
</span>
......@@ -104,7 +104,7 @@ import { mapState, mapMutations, mapActions } from 'vuex';
import Pagination from '@/components/Pagination.vue';
export default {
name: 'UserProjectList',
components: {
......@@ -166,7 +166,9 @@ export default {
]),
refreshId() {
return '?ver=' + Math.random();
const crypto = window.crypto || window.msCrypto;
var array = new Uint32Array(1);
return '?ver=' + crypto.getRandomValues(array); // Compliant for security-sensitive use cases
},
getData(page) {
......@@ -183,4 +185,4 @@ export default {
}
};
</script>
\ No newline at end of file
</script>
......@@ -22,7 +22,7 @@
<script>
export default {
name: 'AppFooter',
computed: {
......
......@@ -25,7 +25,7 @@
<span>
<span v-if="project"> Projet : {{ project.title }} </span>
</span>
<i class="dropdown icon" />
<em class="dropdown icon" />
<div
:class="[
'menu dropdown-list',
......@@ -41,7 +41,7 @@
}"
class="item"
>
<i class="home icon" />Accueil
<em class="home icon" />Accueil
</router-link>
<router-link
v-if="project"
......@@ -51,7 +51,7 @@
}"
class="item"
>
<i class="list icon" />Liste & Carte
<em class="list icon" />Liste & Carte
</router-link>
<router-link
v-if="
......@@ -64,7 +64,7 @@
}"
class="item"
>
<i class="map icon" />Fonds cartographiques
<em class="map icon" />Fonds cartographiques
</router-link>
<router-link
v-if="
......@@ -77,7 +77,7 @@
}"
class="item"
>
<i class="users icon" />Membres
<em class="users icon" />Membres
</router-link>
<div class="mobile">
<router-link
......@@ -111,7 +111,7 @@
v-if="user"
class="item"
@click="logout"
><i class="ui logout icon" />
><em class="ui logout icon" />
</a>
<router-link
v-else-if="!user && !SSO_LOGIN_URL"
......@@ -166,7 +166,7 @@
v-if="user"
class="item log-item"
@click="logout"
><i class="ui logout icon" />
><em class="ui logout icon" />
</a>
<router-link
v-else-if="!user && !SSO_LOGIN_URL"
......@@ -192,7 +192,7 @@
import { mapState } from 'vuex';
export default {
name: 'AppHeader',
data() {
......@@ -234,7 +234,7 @@ export default {
},
userFullname() {
if (this.user.first_name || this.user.last_name)
return this.user.first_name + ' ' + this.user.last_name;
return `${this.user.first_name} ${this.user.last_name}`;
return null;
},
isAdmin() {
......@@ -300,4 +300,4 @@ export default {
height: 100% !important;
}
</style>
\ No newline at end of file
</style>
......@@ -32,7 +32,7 @@
{{ selected }}
</div>
</div>
<i
<em
:class="['dropdown icon', { clear: clearable && selected }]"
@click="clear"
/>
......@@ -186,4 +186,4 @@ export default {
.italic {
font-style: italic;
}
</style>
\ No newline at end of file
</style>
......@@ -36,9 +36,9 @@
</div>
</div>
</div>
<i v-if="attachments.length === 0">
<em v-if="attachments.length === 0">
Aucune pièce jointe associée au signalement.
</i>
</em>
</div>
</template>
......
......@@ -51,7 +51,7 @@
event.related_comment.attachment.url
"
target="_blank"
><i class="paperclip fitted icon" />
><em class="paperclip fitted icon" />
{{ event.related_comment.attachment.title }}</a>
</div>
</div>
......@@ -107,7 +107,7 @@
class="ui icon button"
for="attachment_file"
>
<i class="paperclip icon" />
<em class="paperclip icon" />
<span class="label">{{
comment_form.attachment_file.value
? comment_form.attachment_file.value
......@@ -146,7 +146,7 @@
class="ui compact green icon button"
@click="postComment"
>
<i class="plus icon" /> Poster le commentaire
<em class="plus icon" /> Poster le commentaire
</button>
</form>
</div>
......@@ -160,7 +160,7 @@ import { mapState, mapGetters } from 'vuex';
import featureAPI from '@/services/feature-api';
export default {
name: 'FeatureComments',
props: {
......@@ -262,7 +262,7 @@ export default {
this.comment_form.attachment_file.fileName = title; //* name of the file
const fileExtension = title.substring(title.lastIndexOf('.') + 1);
if ((title.length - fileExtension.length) > 11) {
title = title.slice(0, 10) + '[...].' + fileExtension;
title = `${title.slice(0, 10)}[...].${fileExtension}`;
}
this.comment_form.attachment_file.title = title; //* title for display
this.comment_form.attachment_file.errors = null;
......
......@@ -16,7 +16,7 @@
data-tooltip="Ajouter un signalement"
data-position="bottom left"
>
<i class="plus fitted icon" />
<em class="plus fitted icon" />
</router-link>
<router-link
v-if="
......@@ -33,7 +33,7 @@
}"
class="ui button button-hover-orange"
>
<i class="inverted grey pencil alternate icon" />
<em class="inverted grey pencil alternate icon" />
</router-link>
<a
v-if="((permissions && permissions.can_update_feature) || isFeatureCreator) && isOnline"
......@@ -41,7 +41,7 @@
class="ui button button-hover-red"
@click="isCanceling = true"
>
<i class="inverted grey trash alternate icon" />
<em class="inverted grey trash alternate icon" />
</a>
</div>
<div class="ui hidden divider" />
......@@ -58,7 +58,7 @@
import { mapState, mapGetters } from 'vuex';
export default {
name: 'FeatureHeader',
computed: {
......
......@@ -12,7 +12,7 @@
</td>
<td>
<b>
<i
<em
v-if="field.field_type === 'boolean'"
:class="[
'icon',
......@@ -33,7 +33,7 @@
<tr>
<td>Statut</td>
<td>
<i
<em
v-if="currentFeature.status"
:class="['icon', statusIcon]"
/>
......@@ -79,7 +79,7 @@
import { mapState } from 'vuex';
export default {
name: 'FeatureTable',
filters: {
......
......@@ -135,4 +135,4 @@ export default {
},
},
};
</script>
\ No newline at end of file
</script>
......@@ -8,7 +8,7 @@
type="button"
@click="removeAttachmentFormset(form.dataKey)"
>
<i class="ui times icon" />
<em class="ui times icon" />
</button>
</h4>
<!-- {{ form.errors }} -->
......@@ -42,7 +42,7 @@
class="ui icon button"
:for="'attachment_file' + attachmentForm.dataKey"
>
<i class="file icon" />
<em class="file icon" />
<span
v-if="form.attachment_file.value"
class="label"
......@@ -262,4 +262,4 @@ export default {
},
},
};
</script>
\ No newline at end of file
</script>
<template>
<div class="ui mini modal">
<i class="close icon" />
<em class="close icon" />
<div class="content">
<h3>Importer une image géoréférencée</h3>
<form
......@@ -21,7 +21,7 @@
class="ui icon button"
for="image_file"
>
<i class="file icon" />
<em class="file icon" />
<span class="label">Sélectionner une image ...</span>
</label>
<input
......@@ -44,7 +44,7 @@
class="ui positive right labeled icon button"
>
Importer
<i class="checkmark icon" />
<em class="checkmark icon" />
</button>
</form>
</div>
......@@ -55,4 +55,4 @@
export default {
name: 'FeatureEditModal'
};
</script>
\ No newline at end of file
</script>
......@@ -7,7 +7,7 @@
type="button"
@click="remove_linked_formset"
>
<i class="ui times icon" />
<em class="ui times icon" />
</button>
</h4>
<ul
......@@ -164,4 +164,4 @@ export default {
},
},
};
</script>
\ No newline at end of file
</script>
......@@ -4,9 +4,9 @@
:data-tooltip="`Passer en mode ${massMode === 'modify' ? 'suppression':'édition'}`"
@click="switchMode"
>
<div><i :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div>
<div><em :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div>
<span class="grey">|&nbsp;</span>
<div><i :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div>
<div><em :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div>
</div>
</template>
......@@ -45,4 +45,4 @@ export default {
color: #bbbbbb;
}
</style>
\ No newline at end of file
</style>
......@@ -7,7 +7,7 @@
type="button"
@click="removeCustomForm()"
>
<i class="ui times icon" />
<em class="ui times icon" />
</button>
</h4>
<div class="visible-fields">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment