219 lines
6.0 KiB
Vue
219 lines
6.0 KiB
Vue
<template>
|
|
<DialogFrame ref="dialog" header-title="Import CSV" :height="dialogHeight" :width="dialogWidth">
|
|
<div class="column q-gutter-xs">
|
|
<div class="row">
|
|
<q-uploader
|
|
style="max-width: 300px"
|
|
url="/api/members/import/csv"
|
|
label="Import CSV"
|
|
multiple
|
|
:with-credentials="true"
|
|
accept=".csv"
|
|
field-name="file"
|
|
method="POST"
|
|
:form-fields="metaData"
|
|
v-on:failed="onImportFail"
|
|
:headers="[{ name: 'Accept', value: 'application/json' }]"
|
|
@uploaded="onUploaded"
|
|
/>
|
|
</div>
|
|
<q-card :flat="!showOptions">
|
|
<div class="row q-ma-sm">
|
|
<div class="text-bold q-ma-sm">
|
|
<q-btn
|
|
dense
|
|
flat
|
|
size="sm"
|
|
:icon="showOptions ? 'remove' : 'add'"
|
|
@click="showOptions = !showOptions"
|
|
></q-btn>
|
|
CSV options
|
|
</div>
|
|
<div class="row justify-center q-gutter-md">
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-4"
|
|
label="Row Index of Column titles"
|
|
dense
|
|
borderless
|
|
type="number"
|
|
v-model.number="data.rowIndex"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-4"
|
|
label="Seperator"
|
|
dense
|
|
borderless
|
|
v-model="data.seperator"
|
|
></q-input>
|
|
<q-space class="col-1"></q-space>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="First Name"
|
|
dense
|
|
borderless
|
|
v-model="data.firstName"
|
|
autofocus
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Last Name"
|
|
dense
|
|
borderless
|
|
v-model="data.lastName"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Birthday"
|
|
dense
|
|
borderless
|
|
v-model="data.birthday"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Address"
|
|
dense
|
|
borderless
|
|
v-model="data.address"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Town"
|
|
dense
|
|
borderless
|
|
v-model="data.town"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Zip Code"
|
|
dense
|
|
borderless
|
|
v-model="data.zip"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="Phone"
|
|
dense
|
|
borderless
|
|
v-model="data.phone"
|
|
></q-input>
|
|
<q-input
|
|
v-if="showOptions"
|
|
class="col-2"
|
|
label="E-Mail"
|
|
dense
|
|
borderless
|
|
v-model="data.email"
|
|
></q-input>
|
|
</div>
|
|
</div>
|
|
</q-card>
|
|
<div class="row justify-end q-ma-sm">
|
|
<q-btn no-caps color="primary" class="col-3" v-close-popup>{{ $t('close') }}</q-btn>
|
|
</div>
|
|
</div>
|
|
</DialogFrame>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
|
import { ref, watch } from 'vue';
|
|
import type { MetaData } from 'src/vueLib/models/metaData';
|
|
import { useNotify } from 'src/vueLib/general/useNotify';
|
|
|
|
const dialogHeight = ref(300);
|
|
const dialogWidth = ref(500);
|
|
|
|
const { NotifyResponse } = useNotify();
|
|
|
|
const emit = defineEmits(['update-upload']);
|
|
|
|
const dialog = ref();
|
|
const showOptions = ref(true);
|
|
const data = ref<MetaData>({
|
|
rowIndex: 0,
|
|
seperator: ';',
|
|
firstName: 'firstName',
|
|
lastName: 'lastName',
|
|
birthday: 'birthday',
|
|
address: 'address',
|
|
town: 'town',
|
|
zip: 'zip',
|
|
phone: 'phone',
|
|
email: 'email',
|
|
});
|
|
|
|
const metaData = ref([
|
|
{ name: 'rowIndex', value: String(data.value.rowIndex) },
|
|
{ name: 'seperator', value: data.value.seperator },
|
|
{ name: 'firstName', value: data.value.firstName },
|
|
{ name: 'lastName', value: data.value.lastName },
|
|
{ name: 'birthday', value: data.value.birthday },
|
|
{ name: 'address', value: data.value.address },
|
|
{ name: 'town', value: data.value.town },
|
|
{ name: 'zip', value: data.value.zip },
|
|
{ name: 'phone', value: data.value.phone },
|
|
{ name: 'email', value: data.value.email },
|
|
]);
|
|
|
|
function open() {
|
|
showOptions.value = false;
|
|
dialog.value?.open();
|
|
}
|
|
|
|
watch(showOptions, () => {
|
|
if (dialogWidth.value === 500) {
|
|
dialogWidth.value = 325;
|
|
dialogHeight.value = 325;
|
|
return;
|
|
}
|
|
dialogHeight.value = 500;
|
|
dialogWidth.value = 500;
|
|
});
|
|
|
|
watch(
|
|
data,
|
|
() => {
|
|
metaData.value = [
|
|
{ name: 'rowIndex', value: String(data.value.rowIndex) },
|
|
{ name: 'seperator', value: data.value.seperator },
|
|
{ name: 'firstName', value: data.value.firstName },
|
|
{ name: 'lastName', value: data.value.lastName },
|
|
{ name: 'birthday', value: data.value.birthday },
|
|
{ name: 'address', value: data.value.address },
|
|
{ name: 'town', value: data.value.town },
|
|
{ name: 'zip', value: data.value.zip },
|
|
{ name: 'phone', value: data.value.phone },
|
|
{ name: 'email', value: data.value.email },
|
|
];
|
|
},
|
|
{ deep: true },
|
|
);
|
|
|
|
function onImportFail(info: { files: readonly File[]; xhr: XMLHttpRequest }) {
|
|
const response = JSON.parse(info.xhr.responseText);
|
|
if (response.message) {
|
|
NotifyResponse(response.message, 'error', 15000);
|
|
}
|
|
emit('update-upload');
|
|
}
|
|
|
|
function onUploaded(info: { files: readonly File[]; xhr: XMLHttpRequest }) {
|
|
const response = JSON.parse(info.xhr.responseText);
|
|
if (response.message) {
|
|
NotifyResponse(response.message);
|
|
}
|
|
emit('update-upload');
|
|
}
|
|
|
|
defineExpose({ open });
|
|
</script>
|