FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
ameliabooking
/
assets
/
views
/
backend
/
parts
Edit File: DialogImport.vue
<template> <div> <div class="am-dialog-scrollable"> <!-- Dialog Header --> <div class="am-dialog-header"> <el-row> <el-col :span="14"> <h2>{{ $root.labels.import_customer_data }}</h2> </el-col> <el-col :span="10" class="align-right"> <el-button @click="closeDialog" class="am-dialog-close" size="small" icon="el-icon-close"></el-button> </el-col> </el-row> </div> <!-- Form --> <el-form label-position="top" ref="mapForm" :model="mapForm"> <!-- Upload file --> <div v-if="currentStep === 1"> <el-form-item :label="$root.labels.upload_csv + ':'" style="margin-bottom: 16px"> <el-upload drag action="#" :on-success="uploadData" :on-remove="removeData" :before-upload="loadData" accept=".csv" ref="files" :thumbnail-mode="true" :class="{'upload-disabled' : files.length >= 1 || dataLoading}" > <i class="el-icon-upload"></i> <div class="el-upload__text" v-html="$root.labels.drag_drop"></div> </el-upload> </el-form-item> <div class="am-import-rules am-import-rule-list"> <img :src="$root.getUrl + 'public/img/info.svg'" style="float: left;"/> <b><span style="font-size: 16px;margin-left:8px">{{ $root.labels.import_rules }}</span></b> <div v-html="$root.labels.import_rules_desc"></div> <div v-html="$root.labels.import_rules_req"></div> </div> </div> <!-- /Upload file --> <!-- Map columns --> <div v-show="currentStep === 2" class="am-import-columns"> <p>{{ $root.labels.imported_customers }} {{ total }}</p> <p>{{ $root.labels.map_data }}</p> <p v-html="$root.labels.required_data"></p> <el-alert v-if="doubleField" type="error" show-icon title="" :description="$root.labels.more_than_one" :closable="false" style="margin-bottom: 10px" /> <el-alert v-if="missingValues.length" type="error" show-icon title="" :description="$root.labels.missing_value + ' ' + missingValues" :closable="false" style="margin-bottom: 10px" /> <el-row v-for="(column, index) in columns" :key="index" :gutter="25"> <el-col :lg="10" :md="10" :sm="10" :xs="10" class="am-import-columns-select"> <el-form-item :prop="mapColumns[index].value + ' ' + index" :rules="rules.field"> <el-select v-model="mapColumns[index]" @change="checkFields" > <el-option v-for="field in fields" :key="field.value" :label="field.label" :value="field" > </el-option> </el-select> </el-form-item> <p>{{ errorMessages[index] }}</p> </el-col> <el-col :lg="14" :md="14" :sm="14" :xs="14" class="am-import-columns-text"> <span v-for="(name, index) in column" :key="index"> <span v-if="name && index !== 0">, </span><span>{{ name }}</span> </span> </el-col> </el-row> </div> <!-- /Map columns --> <!-- Dialog Loader --> <div class="am-dialog-loader" v-if="dialogLoading"> <div class="am-dialog-loader-content"> <img :src="$root.getUrl + 'public/img/spinner.svg'" class=""/> <p v-html="$root.labels.importing_customers"></p> </div> </div> <div v-if="currentStep === 4"> <p>{{ conflicts.length }} {{ $root.labels.customer_conflicts }}</p> <br> <p><b>{{ $root.labels.values_overwritten }}</b></p> <div class="am-import-rule-list"> <ul v-for="value in valuesOverwrite"> <li>{{ value }}</li> </ul> </div> <p><b>{{ $root.labels.values_saved }}</b></p> <div class="am-import-rule-list"> <ul v-for="value in valuesSaved"> <li>{{ value }}</li> </ul> </div> </div> <div v-if="currentStep === 5"> <div v-if="addedUsers && addedUsers.length" class="am-import-outcome"> <div v-if="!failedToAdd.length"> <!-- Import Successful --> <p><b>{{ $root.labels.import_successful }}</b></p> <img :src="$root.getUrl+'public/img/check-circle-green-full.svg'" class=""/> <p>{{ $root.labels.total }} {{ addedUsers.length }} {{ $root.labels.out_of }} {{ total }} {{ $root.labels.import_successful_desc }}</p> </div> <div v-else> <!-- Import Partially Successful --> <p><b>{{ $root.labels.import_partially_successful }}</b></p> <img :src="$root.getUrl+'public/img/check-circle-green-partial.svg'" class=""/> <p>{{ $root.labels.total }} {{ addedUsers.length }} {{ $root.labels.out_of }} {{ total }} {{ $root.labels.import_successful_desc }}</p> <el-alert type="warning" show-icon title="" :description="failedToAdd.length + ' ' + $root.labels.customer_not_imported" :closable="false" /> <p>{{ $root.labels.prepared_csv }}</p> <el-button @click="exportCSV" > {{ $root.labels.download_csv }} </el-button> </div> </div> <div v-else class="am-import-outcome"> <div> <!-- Import Failed --> <p><b>{{ $root.labels.import_failed }}</b></p> <img :src="$root.getUrl+'public/img/warning.svg'" class=""/> <p>{{ $root.labels.none_of }} {{ $root.labels.import_successful_desc }}</p> <p>{{ $root.labels.check_csv }}</p> </div> </div> </div> </el-form> </div> <!-- Dialog Footer --> <div class="am-dialog-footer"> <div class="am-dialog-footer-actions"> <el-row> <el-col :sm="24" class="align-right"> <el-button v-if="currentStep !== 4" type="" @click="closeDialog" > <span v-if="currentStep === 5">{{ $root.labels.close }}</span> <span v-else>{{ $root.labels.cancel }}</span> </el-button> <el-button v-else type="primary" class="am-dialog-create" @click="skipImport" > {{ $root.labels.skip_import }} </el-button> <el-button v-show="showContinue" v-if="currentStep !== 4 && currentStep !== 5" type="primary" class="am-dialog-create" @click="nextStep()" :loading="dataLoading" > {{ $root.labels.continue }} </el-button> <el-button v-if="currentStep === 4" type="primary" class="am-dialog-create" @click="nextStep(true)" > {{ $root.labels.overwrite_records }} </el-button> </el-col> </el-row> </div> </div> </div> </template> <script> import imageMixin from '../../../js/common/mixins/imageMixin' import dateMixin from '../../../js/common/mixins/dateMixin' import moment from 'moment' export default { mixins: [imageMixin, dateMixin], props: { fields: { type: Array, default: () => [] }, requiredFields: { type: Array, default: () => [] }, valuesSaved: { type: Array, default: () => [] }, valuesOverwrite: { type: Array, default: () => [] }, action: { type: String, default: null } }, data () { let validateFormat = (rule, input, callback) => { let arr = rule.field.split(' ') let type = arr[0] let index = arr[1] switch (type) { case 'email': let regexEmail = /^\S+@\S+\.\S+$/ this.data.forEach(row => { if (row[index] && !regexEmail.test(row[index])) { callback(new Error()) } }) callback() break case 'phone': this.data.forEach(row => { if (row[index] && !row[index].startsWith('+')) { callback(new Error()) } }) callback() break case 'birthday': this.data.forEach(row => { if (row[index] && !moment(row[index], this.momentDateFormat, true).isValid()) { callback(new Error()) } }) callback() break case 'gender': this.data.forEach(row => { if (row[index] && row[index] !== 'male' && row[index] !== 'female') { callback(new Error()) } }) callback() break } } return { checkAllColumns: true, showContinue: false, doubleField: false, missingValues: [], dataLoading: false, total: 0, data: [], conflicts: [], failedToAdd: [], addedUsers: [], columns: [], currentStep: 1, files: [], dialogLoading: false, mapForm: {}, mapColumns: [], errorMessages: [], select: [], rules: { field: [ {validator: validateFormat, message: this.$root.labels.wrong_format, trigger: 'change'} ] }, mapRules: [] } }, updated () { this.inlineSVG() if (this.checkAllColumns && this.currentStep === 2) { this.$refs.mapForm.validate() } }, mounted () { this.inlineSVG() }, methods: { loadData () { this.showContinue = true this.dataLoading = true }, exportCSV () { let exportData = [] this.failedToAdd.forEach((user) => { exportData.push(this.data[user.index]) }) let csv = Papa.unparse(exportData, {header: false}) let csvData = new Blob([csv], {type: 'text/csv;charset=utf-8;'}) let csvURL = null if (navigator.msSaveBlob) { csvURL = navigator.msSaveBlob(csvData, 'download.csv') } else { csvURL = window.URL.createObjectURL(csvData) } let tempLink = document.createElement('a') tempLink.href = csvURL tempLink.setAttribute('download', 'data.csv') tempLink.click() }, removeData (file, fileList) { let index = this.files.indexOf(file) if (index !== -1) { this.files.splice(index, 1) } if (this.files.length === 0) { this.showContinue = false } }, uploadData (response, file, fileList) { this.files.push(file) this.dataLoading = false }, transform (results, parser) { if (results.data.some(Boolean)) { this.total++ this.data.push(results.data) results.data.forEach((col, index) => { if (this.columns[index]) { this.columns[index].push(col) } else { this.columns[index] = [col] } }) } }, skipImport () { this.conflicts = [] this.nextStep() }, importData () { this.files.forEach((file) => { let file2 = file.raw const reader = new FileReader() reader.onload = e => { let contents = e.target.result Papa.parse(contents, {step: this.transform, skipEmptyLines: true}) this.columns.forEach((col, index) => { if (this.fields[index]) { this.mapColumns[index] = this.fields[index] } else { this.mapColumns[index] = this.fields[this.fields.length - 1] } }) this.dataLoading = false } reader.readAsText(file2) }) }, checkFields () { this.checkAllColumns = false this.missingValues = [] this.doubleField = false this.requiredFields.forEach(req => { if (!this.mapColumns.find(c => c.value === req.value)) { this.missingValues.push(req.label) } }) this.doubleField = this.mapColumns.map(c => c.value).find((v, i, arr) => v !== 'dontImport' && arr.indexOf(v) !== i) return !(this.missingValues.length || this.doubleField) }, prepareData () { let data = {} let number = 0 this.columns.forEach((col, index) => { if (this.mapColumns[index].value !== 'dontImport') { data[this.mapColumns[index].value] = col } if (this.mapColumns[index].value === 'firstName') { number += col.length } }) return {data: data, number: number} }, nextStep (overwrite = false) { if (this.currentStep === 1) { this.importData() } if (this.currentStep === 2) { if (!this.checkFields()) return } if (this.currentStep < 5) { this.currentStep++ } if (this.currentStep === 3 || (this.currentStep === 5 && overwrite)) { this.dialogLoading = true let data = this.prepareData() this.$http.post(this.action, {'data': data.data, 'number': data.number, 'overwrite': overwrite ? this.conflicts : null}) .then((response) => { this.conflicts = this.conflicts.concat(response.data.data.existsUsers) this.failedToAdd = this.failedToAdd.concat(response.data.data.failedToAdd) this.addedUsers = this.addedUsers.concat(response.data.data.addedUsers) if (!this.conflicts.length) { this.currentStep++ } this.$emit('getEntities') }).catch(e => { console.log(e) }).finally(() => { this.dialogLoading = false this.nextStep() }) } }, closeDialog () { this.$emit('closeDialogImport') } }, components: {} } </script>
Save
Back