first commit
This commit is contained in:
139
src/components/EditAllDialog.vue
Normal file
139
src/components/EditAllDialog.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<DialogFrame
|
||||
ref="dialog"
|
||||
:header-title="
|
||||
newMember ? 'Add new Member' : 'Edit ' + localMember.firstName + ' ' + localMember.lastName
|
||||
"
|
||||
:height="600"
|
||||
:width="500"
|
||||
>
|
||||
<div class="row justify-center q-gutter-md">
|
||||
<q-input
|
||||
class="q-ml-md col-5"
|
||||
label="First Name"
|
||||
filled
|
||||
v-model="localMember.firstName"
|
||||
autofocus
|
||||
></q-input>
|
||||
<q-input
|
||||
class="q-ml-md col-5"
|
||||
label="Last Name"
|
||||
filled
|
||||
v-model="localMember.lastName"
|
||||
></q-input>
|
||||
<q-input
|
||||
class="q-ml-md col-5"
|
||||
label="Birthday"
|
||||
filled
|
||||
v-model="localMember.birthday"
|
||||
></q-input>
|
||||
<q-input class="q-ml-md col-5" label="Address" filled v-model="localMember.address"></q-input>
|
||||
<q-input class="q-ml-md col-5" label="Town" filled v-model="localMember.town"></q-input>
|
||||
<q-input class="q-ml-md col-5" label="Zip Code" filled v-model="localMember.zip"></q-input>
|
||||
<q-input class="q-ml-md col-5" label="Phone" filled v-model="localMember.phone"></q-input>
|
||||
<q-input class="q-ml-md col-5" label="E-Mail" filled v-model="localMember.email"></q-input>
|
||||
<q-input class="q-ml-md col-5" label="Group" filled v-model="localMember.group"></q-input>
|
||||
<q-input
|
||||
class="q-ml-md col-5"
|
||||
label="Responsible"
|
||||
filled
|
||||
v-model="localMember.responsiblePerson"
|
||||
></q-input>
|
||||
<q-input
|
||||
v-if="!newMember"
|
||||
class="q-ml-md col-11"
|
||||
label="First Visit"
|
||||
filled
|
||||
v-model="localMember.firstVisit"
|
||||
></q-input>
|
||||
<q-input
|
||||
v-if="!newMember"
|
||||
class="q-ml-md col-11"
|
||||
label="Last Visit"
|
||||
filled
|
||||
v-model="localMember.lastVisit"
|
||||
></q-input>
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { Member } from 'src/vueLib/models/member';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
|
||||
const { NotifyResponse } = useNotify();
|
||||
const dialog = ref();
|
||||
const newMember = ref(false);
|
||||
const localMember = ref<Member>({
|
||||
id: 0,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
birthday: '',
|
||||
age: '',
|
||||
address: '',
|
||||
town: '',
|
||||
zip: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
group: '',
|
||||
responsiblePerson: '',
|
||||
firstVisit: '',
|
||||
lastVisit: '',
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update-member']);
|
||||
|
||||
function open(member: Member | null) {
|
||||
if (member === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (member !== null) {
|
||||
localMember.value = member;
|
||||
newMember.value = false;
|
||||
} else {
|
||||
localMember.value = {
|
||||
id: 0,
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
birthday: '',
|
||||
age: '',
|
||||
address: '',
|
||||
town: '',
|
||||
zip: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
group: '',
|
||||
responsiblePerson: '',
|
||||
firstVisit: '',
|
||||
lastVisit: '',
|
||||
};
|
||||
newMember.value = true;
|
||||
}
|
||||
|
||||
dialog.value?.open();
|
||||
}
|
||||
|
||||
function save() {
|
||||
let query = 'secure/members/edit?id=' + localMember.value.id;
|
||||
if (newMember.value) {
|
||||
query = 'ecure/members/add';
|
||||
}
|
||||
|
||||
appApi
|
||||
.post(query, JSON.stringify(localMember.value))
|
||||
.then(() => {
|
||||
emit('update-member', '');
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => NotifyResponse(err, 'error'));
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
207
src/components/EditOneDialog.vue
Normal file
207
src/components/EditOneDialog.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<DialogFrame ref="dialog" :header-title="'Edit ' + localTitle">
|
||||
<div class="row justify-center">
|
||||
<q-input
|
||||
autofocus
|
||||
class="q-ml-md col-6"
|
||||
:label="localTitle"
|
||||
filled
|
||||
v-model="value"
|
||||
@keyup.enter="save"
|
||||
></q-input>
|
||||
</div>
|
||||
<div class="row justify-center">
|
||||
<q-btn class="q-ma-md" color="primary" no-caps @click="save">Save</q-btn>
|
||||
</div>
|
||||
</DialogFrame>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue';
|
||||
import { ref } from 'vue';
|
||||
import { appApi } from 'src/boot/axios';
|
||||
import type { Member } from 'src/vueLib/models/member';
|
||||
import { useNotify } from 'src/vueLib/general/useNotify';
|
||||
|
||||
const dialog = ref();
|
||||
const localMember = ref();
|
||||
const localTitle = ref('');
|
||||
const localField = ref('');
|
||||
const value = ref();
|
||||
|
||||
const emit = defineEmits(['update-member']);
|
||||
const { NotifyResponse } = useNotify();
|
||||
|
||||
function open(label: string, field: string, member: Member) {
|
||||
localTitle.value = label;
|
||||
localField.value = field;
|
||||
localMember.value = member;
|
||||
|
||||
switch (field) {
|
||||
case 'firstName':
|
||||
value.value = member.firstName;
|
||||
break;
|
||||
case 'lastName':
|
||||
value.value = member.lastName;
|
||||
break;
|
||||
case 'birthday':
|
||||
value.value = member.birthday;
|
||||
break;
|
||||
case 'address':
|
||||
value.value = member.address;
|
||||
break;
|
||||
case 'town':
|
||||
value.value = member.town;
|
||||
break;
|
||||
case 'zip':
|
||||
value.value = member.zip;
|
||||
break;
|
||||
case 'phone':
|
||||
value.value = member.phone;
|
||||
break;
|
||||
case 'email':
|
||||
value.value = member.email;
|
||||
break;
|
||||
case 'group':
|
||||
value.value = member.group;
|
||||
break;
|
||||
case 'responsiblePerson':
|
||||
value.value = member.responsiblePerson;
|
||||
break;
|
||||
case 'firstVisit':
|
||||
value.value = member.firstVisit;
|
||||
break;
|
||||
case 'lastVisit':
|
||||
value.value = member.lastVisit;
|
||||
break;
|
||||
}
|
||||
dialog.value?.open();
|
||||
}
|
||||
|
||||
function save() {
|
||||
const query = 'secure/members/edit?id=' + localMember.value.id;
|
||||
let payload = {};
|
||||
|
||||
switch (localField.value) {
|
||||
case 'firstName':
|
||||
if (value.value === localMember.value.firstName) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
firstName: value.value,
|
||||
};
|
||||
break;
|
||||
case 'lastName':
|
||||
if (value.value === localMember.value.lastName) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
lastName: value.value,
|
||||
};
|
||||
break;
|
||||
case 'birthday':
|
||||
if (value.value === localMember.value.birthday) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
birthday: value.value,
|
||||
};
|
||||
break;
|
||||
case 'address':
|
||||
if (value.value === localMember.value.address) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
address: value.value,
|
||||
};
|
||||
break;
|
||||
case 'town':
|
||||
if (value.value === localMember.value.town) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
town: value.value,
|
||||
};
|
||||
break;
|
||||
case 'zip':
|
||||
if (value.value === localMember.value.zip) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
zip: value.value,
|
||||
};
|
||||
break;
|
||||
case 'phone':
|
||||
if (value.value === localMember.value.phone) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
phone: value.value,
|
||||
};
|
||||
break;
|
||||
case 'email':
|
||||
if (value.value === localMember.value.email) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
email: value.value,
|
||||
};
|
||||
break;
|
||||
case 'group':
|
||||
if (value.value === localMember.value.group) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
group: value.value,
|
||||
};
|
||||
break;
|
||||
case 'responsiblePerson':
|
||||
if (value.value === localMember.value.responsiblePerson) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
responsiblePerson: value.value,
|
||||
};
|
||||
break;
|
||||
case 'firstVisit':
|
||||
if (value.value === localMember.value.firstVisit) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
firstVisit: value.value,
|
||||
};
|
||||
break;
|
||||
case 'lastVisit':
|
||||
if (value.value === localMember.value.lastVisit) {
|
||||
dialog.value.close();
|
||||
return;
|
||||
}
|
||||
payload = {
|
||||
lastVisit: value.value,
|
||||
};
|
||||
break;
|
||||
}
|
||||
appApi
|
||||
.post(query, payload)
|
||||
.then(() => {
|
||||
emit('update-member', '');
|
||||
dialog.value.close();
|
||||
})
|
||||
.catch((err) => {
|
||||
NotifyResponse(err, 'error');
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
218
src/components/UploadDialog.vue
Normal file
218
src/components/UploadDialog.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<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="`http://localhost:` + portApp + `/api/members/import/csv`"
|
||||
label="Import CSV"
|
||||
multiple
|
||||
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';
|
||||
import { portApp } from 'src/boot/axios';
|
||||
|
||||
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>
|
||||
92
src/components/dialog/OkDialog.vue
Normal file
92
src/components/dialog/OkDialog.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<q-dialog ref="dialog">
|
||||
<q-card :style="'width:' + props.width">
|
||||
<q-card-section
|
||||
v-if="props.dialogLabel"
|
||||
class="text-h6 text-center"
|
||||
:class="'text-' + props.labelColor"
|
||||
>{{ props.dialogLabel }}</q-card-section
|
||||
>
|
||||
<q-card-section v-if="props.text" class="text-center" style="white-space: pre-line">{{
|
||||
props.text
|
||||
}}</q-card-section>
|
||||
<q-card-actions align="right" class="text-primary">
|
||||
<q-btn
|
||||
v-if="props.buttonCancelLabel"
|
||||
:flat="props.buttonCancelFlat"
|
||||
:label="props.buttonCancelLabel"
|
||||
v-close-popup
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
v-if="props.buttonOkLabel"
|
||||
:flat="props.buttonOkFlat"
|
||||
:label="props.buttonOkLabel"
|
||||
:color="props.buttonOkColor"
|
||||
v-close-popup
|
||||
@click="confirm"
|
||||
>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
buttonOkLabel: {
|
||||
type: String,
|
||||
default: 'OK',
|
||||
},
|
||||
buttonOkColor: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
buttonOkFlat: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
labelColor: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
},
|
||||
dialogLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
buttonCancelLabel: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
buttonCancelFlat: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '300px',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update-confirm']);
|
||||
|
||||
const dialog = ref();
|
||||
const localInput = ref();
|
||||
|
||||
const open = (input?: unknown) => {
|
||||
localInput.value = input;
|
||||
dialog.value?.show();
|
||||
};
|
||||
|
||||
const confirm = () => {
|
||||
emit('update-confirm', localInput.value);
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
</script>
|
||||
Reference in New Issue
Block a user