WIP Исправил баги ASTRA-53, ASTRA-54, добавил валибацию

This commit is contained in:
DwCay
2023-04-20 19:52:58 +03:00
parent b1a7d106ea
commit fcabea8f86
7 changed files with 177 additions and 35 deletions

View File

@@ -11,6 +11,7 @@
:type="type", :type="type",
:readonly="readonly", :readonly="readonly",
:disable="disabled", :disable="disabled",
:name="name"
:filled="filled", :filled="filled",
:bg-color="filled || standout ? '' : 'white'", :bg-color="filled || standout ? '' : 'white'",
:rules="rule", :rules="rule",
@@ -88,6 +89,7 @@ export default {
label: String, label: String,
readonly: Boolean, readonly: Boolean,
iconLeft: Boolean, iconLeft: Boolean,
name: String,
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
computed: { computed: {

View File

@@ -8,15 +8,21 @@
:cancel="cancelEdit" :cancel="cancelEdit"
:open-edit="openEdit" :open-edit="openEdit"
) )
.flex.flex-col.gap-19px.w-full q-form.flex.flex-col.gap-19px.w-full(ref="formAllergies")
.flex.flex-col.gap-4.w-full .flex.flex-col.gap-4.w-full
.flex.gap-4.items-center.w-full.justify-between(v-for="(allergy, index) in allergies") .flex.items-center.w-full.justify-between(v-for="(allergy, index) in allergies")
.label-field.font-sm.text-sm.whitespace-nowrap {{ `Аллерген ${index+1}:` }} .w-32.justify-start
.flex.gap-2.w-full.items-center .label-field.font-sm.text-sm.whitespace-nowrap {{ `Аллерген ${index+1}:` }}
.flex.min-w-64.gap-2.w-full.items-center
base-input( base-input(
:disabled="!isEdit" :disabled="!isEdit"
v-model="allergy.name" v-model="allergy.name"
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
name="name"
:rule="configData.name.rules"
no-error-icon
:width="278"
placeholder="Аллерген"
type="text" type="text"
:standout="!isEdit" :standout="!isEdit"
:outlined="isEdit" :outlined="isEdit"
@@ -26,6 +32,10 @@
:disabled="!isEdit" :disabled="!isEdit"
v-model="allergy.title" v-model="allergy.title"
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
name="title"
:rule="configData.title.rules"
no-error-icon
placeholder="Проявление аллергии"
type="text" type="text"
:standout="!isEdit" :standout="!isEdit"
:outlined="isEdit" :outlined="isEdit"
@@ -49,18 +59,28 @@
import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue"; import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue";
import BaseButton from "@/components/base/BaseButton.vue"; import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue"; import BaseInput from "@/components/base/BaseInput.vue";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider.vue";
import { getFieldsNameUnvalidated } from "@/shared/utils/changesObjects";
import { addNotification } from "@/components/Notifications/notificationContext";
import { checkChangeData } from "@/shared/utils/changesObjects"; import { checkChangeData } from "@/shared/utils/changesObjects";
import { allergiesConfig } from "@/pages/newMedicalCard/utils/medicalConfig";
import { mapState, mapGetters } from "vuex"; import { mapState, mapGetters } from "vuex";
import { getRequestArrayData } from "@/shared/utils/wrapperRequestChangeData"; import { getRequestArrayData } from "@/shared/utils/wrapperRequestChangeData";
export default { export default {
name: "AllergiesForm", name: "AllergiesForm",
components: { MedicalFormWrapper, BaseButton, BaseInput }, components: {
MedicalFormWrapper,
BaseButton,
BaseInput,
TheNotificationProvider,
},
data() { data() {
return { return {
isEdit: false, isEdit: false,
isLoadingData: false, isLoadingData: false,
isCheckChange: false, isCheckChange: false,
configData: allergiesConfig,
}; };
}, },
computed: { computed: {
@@ -87,14 +107,29 @@ export default {
); );
}, },
saveChange() { saveChange() {
this.isLoadingData = true; const form = this.$refs.formAllergies;
Promise.allSettled(this.updateAllergies()) form.validate().then((res) => {
.then(() => this.$store.dispatch("getMedicalCardData")) if (res) {
.then(() => { this.isLoadingData = true;
this.isLoadingData = false; Promise.allSettled(this.updateAllergies())
this.isEdit = false; .then(() => this.$store.dispatch("getMedicalCardData"))
this.isCheckChange = false; .then(() => {
}); this.isLoadingData = false;
this.isEdit = false;
this.isCheckChange = false;
});
} else {
getFieldsNameUnvalidated(form).forEach((errorKey) => {
addNotification(
this.configData[errorKey].title,
this.configData[errorKey].title,
this.configData[errorKey].error,
"error",
5000
);
});
}
});
}, },
cancelEdit() { cancelEdit() {
this.$store.dispatch("returnInitData"); this.$store.dispatch("returnInitData");

View File

@@ -8,7 +8,7 @@
:cancel="cancelEdit" :cancel="cancelEdit"
:open-edit="openEdit" :open-edit="openEdit"
) )
.form-wrap.gap-24.w-full q-form.form-wrap.gap-24.w-full(ref="formBasicData")
.flex.flex-col.gap-4(v-for="data in configData") .flex.flex-col.gap-4(v-for="data in configData")
.font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}} .font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}}
.flex.w-full.justify-between.items-center.gap-4(v-for="field in data.fields") .flex.w-full.justify-between.items-center.gap-4(v-for="field in data.fields")
@@ -44,9 +44,11 @@
v-model="basic[data.dataKey][field.key]" v-model="basic[data.dataKey][field.key]"
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
:type="field.type" :type="field.type"
:name="field.key"
:width="278" :width="278"
:standout="!isEdit" :standout="!isEdit"
:outlined="isEdit" :outlined="isEdit"
no-error-icon
:rule="field.rules" :rule="field.rules"
text-color="black" text-color="black"
) )
@@ -59,6 +61,9 @@ import BaseAvatar from "@/components/base/BaseAvatar.vue";
import BaseModal from "@/components/base/BaseModal.vue"; import BaseModal from "@/components/base/BaseModal.vue";
import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue"; import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue";
import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue"; import MedicalFormWrapper from "@/pages/newMedicalCard/components/MedicalFormWrapper.vue";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider.vue";
import { getFieldsNameUnvalidated } from "@/shared/utils/changesObjects";
import { addNotification } from "@/components/Notifications/notificationContext";
import { getRequestChangeData } from "@/shared/utils/wrapperRequestChangeData"; import { getRequestChangeData } from "@/shared/utils/wrapperRequestChangeData";
import { checkChangeData } from "@/shared/utils/changesObjects"; import { checkChangeData } from "@/shared/utils/changesObjects";
import { fetchWrapper } from "@/shared/fetchWrapper"; import { fetchWrapper } from "@/shared/fetchWrapper";
@@ -66,6 +71,7 @@ import moment from "moment";
import { import {
baseDataForm, baseDataForm,
genderOptions, genderOptions,
errorMap,
} from "@/pages/newMedicalCard/utils/medicalConfig.js"; } from "@/pages/newMedicalCard/utils/medicalConfig.js";
import { mapGetters, mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
@@ -78,6 +84,7 @@ export default {
BaseSelect, BaseSelect,
BaseModal, BaseModal,
BaseUploadPhoto, BaseUploadPhoto,
TheNotificationProvider,
}, },
data() { data() {
return { return {
@@ -87,6 +94,7 @@ export default {
isCheckChange: false, isCheckChange: false,
genderOptions: genderOptions, genderOptions: genderOptions,
configData: baseDataForm, configData: baseDataForm,
errorMapBasic: errorMap,
}; };
}, },
computed: { computed: {
@@ -176,15 +184,30 @@ export default {
return request; return request;
}, },
saveChange() { saveChange() {
this.isLoadingData = true; const form = this.$refs.formBasicData;
let updateBasic = this.updateBasicData(); form.validate().then((validate) => {
Promise.allSettled(updateBasic) if (validate) {
.then(() => this.$store.dispatch("getMedicalCardData")) this.isLoadingData = true;
.then(() => { let updateBasic = this.updateBasicData();
this.isLoadingData = false; Promise.allSettled(updateBasic)
this.isEdit = false; .then(() => this.$store.dispatch("getMedicalCardData"))
this.isCheckChange = false; .then(() => {
}); this.isLoadingData = false;
this.isEdit = false;
this.isCheckChange = false;
});
} else {
getFieldsNameUnvalidated(form).forEach((errorKey) => {
addNotification(
this.errorMapBasic[errorKey].title,
this.errorMapBasic[errorKey].title,
this.errorMapBasic[errorKey].error,
"error",
5000
);
});
}
});
}, },
openEdit() { openEdit() {
this.isEdit = true; this.isEdit = true;

View File

@@ -31,10 +31,11 @@
:size-input="50" :size-input="50"
) )
base-input.w-full( base-input.w-full(
:disabled="!isEdit"
v-model="data.username" v-model="data.username"
:mask="configData[key].inputMask"
type="text" type="text"
:name="key"
no-error-icon
:rule="configData[key].rules"
:standout="!isEdit" :standout="!isEdit"
:outlined="isEdit" :outlined="isEdit"
text-color="black" text-color="black"
@@ -43,8 +44,10 @@
v-else v-else
:disabled="!isEdit" :disabled="!isEdit"
v-model="data.username" v-model="data.username"
:name="key"
:mask="configData[key].inputMask" :mask="configData[key].inputMask"
:rule="configData[key].rules" :rule="configData[key].rules"
no-error-icon
@update:model-value="checkChangeInput" @update:model-value="checkChangeInput"
type="text" type="text"
:standout="!isEdit" :standout="!isEdit"
@@ -71,14 +74,25 @@ import BaseInput from "@/components/base/BaseInput.vue";
import BaseButton from "@/components/base/BaseButton.vue"; import BaseButton from "@/components/base/BaseButton.vue";
import BaseSelectNetworks from "@/components/base/BaseSelectNetworks.vue"; import BaseSelectNetworks from "@/components/base/BaseSelectNetworks.vue";
import { mapNetworks } from "@/pages/newMedicalCard/utils/medicalConfig"; import { mapNetworks } from "@/pages/newMedicalCard/utils/medicalConfig";
import { checkChangeData } from "@/shared/utils/changesObjects"; import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider.vue";
import { addNotification } from "@/components/Notifications/notificationContext";
import {
checkChangeData,
getFieldsNameUnvalidated,
} from "@/shared/utils/changesObjects";
import { contactsDataForm } from "@/pages/newMedicalCard/utils/medicalConfig"; import { contactsDataForm } from "@/pages/newMedicalCard/utils/medicalConfig";
import { getRequestArrayData } from "@/shared/utils/wrapperRequestChangeData"; import { getRequestArrayData } from "@/shared/utils/wrapperRequestChangeData";
import { mapState, mapGetters } from "vuex"; import { mapState, mapGetters } from "vuex";
export default { export default {
name: "ContactsForm", name: "ContactsForm",
components: { MedicalFormWrapper, BaseInput, BaseSelectNetworks, BaseButton }, components: {
MedicalFormWrapper,
BaseInput,
BaseSelectNetworks,
BaseButton,
TheNotificationProvider,
},
data() { data() {
return { return {
isEdit: false, isEdit: false,
@@ -145,6 +159,16 @@ export default {
this.isEdit = false; this.isEdit = false;
this.isCheckChange = false; this.isCheckChange = false;
}); });
} else {
getFieldsNameUnvalidated(form).forEach((errorKey) => {
addNotification(
this.configData[errorKey].title,
this.configData[errorKey].title,
this.configData[errorKey].error,
"error",
5000
);
});
} }
}); });
}, },
@@ -161,12 +185,12 @@ export default {
if (key === "networks") { if (key === "networks") {
this.contacts[key].push({ this.contacts[key].push({
filled: false, filled: false,
kind: null, kind: this.configData[key]?.kind,
username: null, username: null,
}); });
} else { } else {
this.contacts[key].push({ this.contacts[key].push({
kind: this.configData[key].kind, kind: this.configData[key]?.kind,
username: null, username: null,
}); });
} }
@@ -190,7 +214,7 @@ export default {
&.new &.new
color: var(--icon-violet-color) color: var(--icon-violet-color)
.input-wrapper .input-wrapper
width: 324px width: 302px
.form-wrap .form-wrap
display: grid display: grid
grid-template-columns: repeat(3, auto) grid-template-columns: repeat(3, auto)

View File

@@ -1,4 +1,9 @@
import { ruleLengthValue, ruleEmailValue } from "@/shared/utils/rulesInputs"; import {
ruleLengthValue,
ruleEmailValue,
ruleMaxLength,
ruleNotValue,
} from "@/shared/utils/rulesInputs";
export const baseDataForm = [ export const baseDataForm = [
{ {
@@ -61,12 +66,16 @@ export const baseDataForm = [
label: "Дом", label: "Дом",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
error:
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
}, },
{ {
key: "apartment_number", key: "apartment_number",
label: "Квартира", label: "Квартира",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
error:
"Номер квартиры должен начинатся не с нуля и только с цифробуквенного символа",
}, },
], ],
}, },
@@ -94,17 +103,34 @@ export const baseDataForm = [
label: "Дом", label: "Дом",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
error:
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
}, },
{ {
key: "apartment_number", key: "apartment_number",
label: "Квартира", label: "Квартира",
type: "text", type: "text",
rules: [(val) => !/^[\W0]/.test(val)], rules: [(val) => !/^[\W0]/.test(val)],
error:
"Номер квартиры должен начинатся не с нуля и только с цифробуквенного символа",
}, },
], ],
}, },
]; ];
export const errorMap = {
house_number: {
title: "Дом",
error:
"Номер дома должен начинатся не с нуля и только с цифробуквенного символа",
},
apartment_number: {
title: "Квартира",
error:
"Номер квартиры должен начинатся не с нуля и только с цифробуквенного символа",
},
};
export const mapNetworks = { export const mapNetworks = {
VK: { VK: {
title: "VK", title: "VK",
@@ -148,6 +174,8 @@ export const contactsDataForm = {
phones: { phones: {
title: "Телефон", title: "Телефон",
fieldName: "Телефон", fieldName: "Телефон",
error:
"Не корректно введен номер телефона. Номер телефона должен состоять из 10 цифр (без учета +7)",
kind: "PHONE", kind: "PHONE",
rules: [(val) => ruleLengthValue(val, 18)], rules: [(val) => ruleLengthValue(val, 18)],
inputMask: "+7 (###) ###-##-##", inputMask: "+7 (###) ###-##-##",
@@ -155,12 +183,31 @@ export const contactsDataForm = {
emails: { emails: {
title: "Почта", title: "Почта",
fieldName: "Email", fieldName: "Email",
error:
"Не корректно введен адрес почты. Почта должна содержать локальное имя, знак @ и имя домена",
rules: [(val) => ruleEmailValue(val)], rules: [(val) => ruleEmailValue(val)],
kind: "EMAIL", kind: "EMAIL",
}, },
networks: { networks: {
title: "Социальные сети", title: "Социальные сети",
fieldName: "Соцсеть", fieldName: "Соцсеть",
error: "Отсутсвует ссылка соцсети",
rules: [(val) => ruleNotValue(val)],
kind: "TELEGRAM",
},
};
export const allergiesConfig = {
name: {
title: "Аллерген",
error:
"Некорректно введен аллерген. Значение должно быть больше 1 и меньше 50 символов",
},
title: {
title: "Проявление аллергии",
rules: [(val) => ruleMaxLength(val, 100)],
error:
"Некорректно введено проявление аллергии. Значение должно быть больше 1 и меньше 100 символов",
}, },
}; };

View File

@@ -27,3 +27,10 @@ export function checkTypeofObject(obj) {
export function checkChangeData(dataInit, dataChange) { export function checkChangeData(dataInit, dataChange) {
return JSON.stringify(dataInit) !== JSON.stringify(dataChange); return JSON.stringify(dataInit) !== JSON.stringify(dataChange);
} }
export function getFieldsNameUnvalidated(form) {
const unvalidatedFields = form
.getValidationComponents()
.filter((el) => !el.validate());
return [...new Set(unvalidatedFields.map((field) => field.name))];
}

View File

@@ -1,5 +1,5 @@
export function ruleNotValue(val, text) { export function ruleNotValue(val, text) {
return val || text || false; return !!val || text || false;
} }
export function ruleLengthValue(val, minLength, text) { export function ruleLengthValue(val, minLength, text) {
@@ -17,3 +17,7 @@ export function ruleEmailValue(val, text) {
false false
); );
} }
export function ruleMaxLength(val, maxLength, text) {
return (!!val && val.length <= maxLength) || text || false;
}