Uname: Linux webm012.cluster130.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Software: Apache
PHP version: 8.0.30 [ PHP INFO ] PHP os: Linux
Server Ip: 145.239.37.162
Your Ip: 216.73.216.190
User: dreampi (1009562) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : 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>
© 2026 GrazzMean-Shell