Skip to content
Snippets Groups Projects
Commit 590eca7c authored by m431m's avatar m431m :speech_balloon:
Browse files

Merge branch 'redmine-issues/17891' into '1.1'

REDMINE_ISSUE-17891

See merge request onegeo-suite/sites/onegeo-suite-site-login-vuejs!46
parents 9a1b9c0f b999fdfd
No related branches found
No related tags found
No related merge requests found
......@@ -43,6 +43,7 @@ VUE_APP_LOGO=@/assets/logo.png
VUE_APP_LOGIN_API_PATH=/login
VUE_APP_ORGANISATION_API_PATH=/organisation/
VUE_APP_USERGROUP_API_PATH=/usergroup/
VUE_APP_PERSONAL_DATA_API_PATH=/api/personal-data/
# AUTH
VUE_APP_LOGIN_API_USERNAME=admin
......
......@@ -12,7 +12,7 @@
},
"dependencies": {
"axios": "^1.5.0",
"bootstrap-vue": "^2.21.2",
"bootstrap-vue": "^2.22.0",
"core-js": "^3.6.5",
"corejs-typeahead": "^1.3.1",
"lodash": "^4.17.21",
......
import axios from 'axios';
import i18n from '@/i18n';
const DEV_AUTH = process.env.NODE_ENV === 'development' ? true : false;
const AUTH = {
username: process.env.VUE_APP_LOGIN_API_USERNAME,
password: process.env.VUE_APP_LOGIN_API_PASSWORD
};
if (!DEV_AUTH) {
axios.defaults.headers.common['X-CSRFToken'] = (name => {
var re = new RegExp(name + "=([^;]+)");
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
})('csrftoken');
}
const path = require('path');
const DOMAIN = process.env.VUE_APP_DOMAIN;
const PERSONAL_DATA_URL = process.env.VUE_APP_PERSONAL_DATA_API_PATH
const personalDataAPI = {
async postPersonalDataDemand() {
const url = new URL(path.join(`${i18n.locale}${PERSONAL_DATA_URL}`, 'demands/'), DOMAIN);
const response = await axios.post(
url,
null,
{ ...DEV_AUTH && { auth: AUTH } }
);
if (response.status === 200) {
return response.data;
}
return false;
},
async getPersonalDataDemands() {
const url = new URL(path.join(`${i18n.locale}${PERSONAL_DATA_URL}`, 'demands/'), DOMAIN);
const response = await axios.get(
url,
{ ...DEV_AUTH && { auth: AUTH } }
);
if (response.status === 200) {
return response.data;
}
return false;
},
// async downloadPersonalData(url) {
// const response = await axios.get(
// url,
// {
// responseType: 'blob',
// ...DEV_AUTH && { auth: AUTH }
// }
// );
// if (response.status === 200) {
// return response.data;
// }
// return false;
// }
}
export default personalDataAPI;
......@@ -172,6 +172,10 @@
"Your password cannot be entirely numerical."
]
}
},
"personalDataExport": {
"title": "Personal data export",
"newDemand": "New request for export of personal data"
}
},
"validationEmail": {
......
......@@ -173,6 +173,10 @@
"Votre mot de passe ne peut pas être entièrement numérique."
]
}
},
"personalDataExport": {
"title": "Export des données personnelles",
"newDemand": "Nouvelle demande d'export des données personnelles"
}
},
"validationEmail": {
......
<template>
<div id="export_data">
<b-overlay
:show="loading"
rounded="lg"
:style="'padding: 5px;'"
variant="white"
:spinner-small="true"
spinner-type="grow"
spinner-variant="primary"
>
<div
v-if="lastDemand && !isLastDemandFinished"
class="export_data-demande in-progress"
>
<div>
La demande d'export de vos données personnelles du
<i>{{ new Date(lastDemand.creation_date).toLocaleDateString() }}</i> à
<i>{{ new Date(lastDemand.creation_date).toLocaleTimeString([], { hour: '2-digit', minute:'2-digit' }) }}</i>
est en attente.
</div>
</div>
<div
v-else-if="lastDemand && isLastDemandFinished"
class="export_data-demande"
>
<div>
La demande d'export de vos données personnelles du
<i>{{ new Date(lastDemand.creation_date).toLocaleDateString() }}</i> à
<i>{{ new Date(lastDemand.creation_date).toLocaleTimeString([], { hour: '2-digit', minute:'2-digit' }) }}</i>
a aboutie.
</div>
<div style="display: flex; justify-content: center;">
<b-button
variant="success"
@click="downloadPersonalData"
>
Télécharger
</b-button>
</div>
</div>
<b-button
id="export_data-button"
variant="primary"
:disabled="!isLastDemandFinished"
@click="demandPersonalData"
>
{{ $t('profile.personalDataExport.newDemand') }}
</b-button>
</b-overlay>
</div>
</template>
<script>
import personalDataAPI from '@/api/personalDataAPI.js';
import { downloadFile } from '@/utils';
export default {
name: 'PersonalDataExport',
data() {
return {
loading: false,
lastDemand: null
};
},
computed: {
isLastDemandFinished() {
if (this.lastDemand && !this.lastDemand.stop_date) {
return false;
}
return true;
}
},
created() {
this.getDemands();
},
methods: {
async demandPersonalData() {
try {
this.loading = true;
const newDemand = await personalDataAPI.postPersonalDataDemand();
this.lastDemand = newDemand;
this.loading = false;
await this.getDemands();
} catch {
this.loading = false;
}
},
async getDemands() {
try {
this.loading = true;
const demands = await personalDataAPI.getPersonalDataDemands();
if (demands && demands.results && demands.results.length) {
this.lastDemand = demands.results[0];
}
this.loading = false;
} catch {
this.loading = false;
}
},
async downloadPersonalData() {
try {
if (this.lastDemand && this.lastDemand.download_href) {
this.loading = true;
const link = document.createElement('a');
link.href = this.lastDemand.download_href;
link.setAttribute('download', `personal_data-${this.lastDemand.id}`);
link.setAttribute('target', '_blank');
document.body.appendChild(link);
link.click();
link.remove();
this.loading = false;
}
} catch {
this.loading = false;
}
}
}
};
</script>
<style scoped lang="less">
#export_data {
width: 100%;
.export_data-demande {
margin: 0 2px 1.5rem;
padding: 0.5rem 0.75rem;
background-color: #effff4;
border-radius: 2px;
box-shadow: 0px 1px 4px rgba(14, 31, 53, 0.12), 0px 4px 8px rgba(14, 31, 53, 0.08);
color: #495057;
font-weight: 600;
text-align: center;
button {
margin: 0.5rem;
font-weight: 600;
}
}
.export_data-demande.in-progress {
background-color: #fdf6e4;
}
#export_data-button {
width: 100%;
font-size: 1rem;
border: 2px solid #9BD0FF;
border-radius: 8px;
font-weight: 600;
}
}
</style>
export function downloadFile(file) {
const fileName =
file.name && file.name.split('/').length && file.name.split('/').slice(-1)[0].split('.').length ?
file.name.split('/').slice(-1)[0].split('.')[0] :
'file';
const href = URL.createObjectURL(file.url);
const link = document.createElement('a');
link.href = href;
link.setAttribute('download', `${fileName}.${file.url.type === 'application/x-zip-compressed' ? 'zip' : 'pdf'}`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(href);
}
\ No newline at end of file
......@@ -18,6 +18,7 @@
<span class="sub-title">{{ $t('profile.subtitle') }}</span>
</h4>
<hr class="divider">
<ValidationObserver ref="form" v-slot="{ handleSubmit }">
<b-overlay
:show="loadingUserInformation"
......@@ -402,6 +403,10 @@
</div>
</b-overlay>
</ValidationObserver>
<h5>{{ $t('profile.personalDataExport.title') }}</h5>
<hr class="divider">
<PersonalDataExport />
</div>
</div>
<small class="footer">
......@@ -420,6 +425,8 @@ import i18n from '@/i18n';
import Swal from "sweetalert2";
import "sweetalert2/dist/sweetalert2.min.css";
import PersonalDataExport from '../components/PersonalDataExport.vue';
import {
ValidationObserver,
ValidationProvider,
......@@ -455,6 +462,7 @@ export default {
name: 'UserProfile',
components: {
PersonalDataExport,
ValidationObserver,
ValidationProvider,
},
......@@ -679,12 +687,18 @@ export default {
border-top: 2px solid #373b3d;
}
#export_data {
margin-top: 24px;
}
h5 {
color: #6b7479;
margin-bottom: 20px;
margin-top: 40px;
color: #373b3d;
}
form {
margin-top: 32px;
margin-top: 20px;
h5 {
margin-bottom: 20px;
......
......@@ -12,4 +12,11 @@ module.exports = {
},
},
},
configureWebpack: {
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
};
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