+
-
+
-
{
value = null;
+ vnInputRef.focus();
emit('remove');
}
"
- />
+ >
+
+
+ {{ t('Convert to uppercase') }}
+
+
+
+
+
{{ info }}
@@ -120,20 +197,44 @@ const inputRules = [
+
+
en-US:
inputMin: Must be more than {value}
+ maxLength: The value exceeds {value} characters
inputMax: Must be less than {value}
+ Convert to uppercase: Convert to uppercase
es-ES:
inputMin: Debe ser mayor a {value}
+ maxLength: El valor excede los {value} carácteres
inputMax: Debe ser menor a {value}
+ Convert to uppercase: Convertir a mayúsculas
ca-ES:
inputMin: Ha de ser més gran que {value}
- inputMax: Ha de ser menys que {value}
+ maxLength: El valor excedeix els {value} caràcters
+ inputMax: Ha de ser menor que {value}
+ Convert to uppercase: Convertir a majúscules
fr-FR:
inputMin: Doit être supérieur à {value}
- inputMax: Doit être supérieur à {value}
+ maxLength: La valeur dépasse {value} caractères
+ inputMax: Doit être inférieur à {value}
+ Convert to uppercase: Convertir en majuscules
pt-PT:
inputMin: Deve ser maior que {value}
- inputMax: Deve ser maior que {value}
+ maxLength: O valor excede {value} caracteres
+ inputMax: Deve ser menor que {value}
+ Convert to uppercase: Converter para maiúsculas
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index c4a3e1df..65dbb2f2 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -67,7 +67,7 @@ const $props = defineProps({
});
const { t } = useI18n();
-const requiredFieldRule = val => val ?? t('globals.fieldRequired');
+const requiredFieldRule = val => val ?? t('fieldRequired');
const { optionLabel, optionValue, options } = toRefs($props);
const myOptions = ref([]);
diff --git a/src/composables/useRequired.js b/src/composables/useRequired.js
new file mode 100644
index 00000000..a77345b5
--- /dev/null
+++ b/src/composables/useRequired.js
@@ -0,0 +1,17 @@
+import { useI18n } from 'vue-i18n';
+
+export function useRequired($attrs) {
+ const { t } = useI18n();
+
+ const isRequired =
+ typeof $attrs['required'] === 'boolean'
+ ? $attrs['required']
+ : Object.keys($attrs).includes('required');
+ const requiredFieldRule = val =>
+ isRequired ? !!val || t('fieldRequired') : null;
+
+ return {
+ isRequired,
+ requiredFieldRule
+ };
+}
diff --git a/src/i18n/ca-ES/index.js b/src/i18n/ca-ES/index.js
index 456795a5..48d214e0 100644
--- a/src/i18n/ca-ES/index.js
+++ b/src/i18n/ca-ES/index.js
@@ -134,6 +134,8 @@ export default {
introduceSearchTerm: 'Introdueix un terme de cerca',
noOrdersFound: `No s'han trobat comandes`,
send: 'Enviar',
+ fieldRequired: 'Aquest camp és obligatori',
+ noChanges: 'No s’han fet canvis',
// Image related translations
'Cant lock cache': 'No es pot bloquejar la memòria cau',
'Bad file format': 'Format de fitxer no reconegut',
diff --git a/src/i18n/en-US/index.js b/src/i18n/en-US/index.js
index 3e21b66d..80107dd5 100644
--- a/src/i18n/en-US/index.js
+++ b/src/i18n/en-US/index.js
@@ -167,6 +167,8 @@ export default {
introduceSearchTerm: 'Enter a search term',
noOrdersFound: 'No orders found',
send: 'Send',
+ fieldRequired: 'Field required',
+ noChanges: 'No changes',
// Image related translations
'Cant lock cache': 'The cache could not be blocked',
'Bad file format': 'Unrecognized file format',
diff --git a/src/i18n/es-ES/index.js b/src/i18n/es-ES/index.js
index 5034ff70..15639c2d 100644
--- a/src/i18n/es-ES/index.js
+++ b/src/i18n/es-ES/index.js
@@ -166,6 +166,8 @@ export default {
introduceSearchTerm: 'Introduce un término de búsqueda',
noOrdersFound: 'No se encontrado pedidos',
send: 'Enviar',
+ fieldRequired: 'Campo requerido',
+ noChanges: 'No se han hecho cambios',
// Image related translations
'Cant lock cache': 'La caché no pudo ser bloqueada',
'Bad file format': 'Formato de archivo no reconocido',
diff --git a/src/i18n/fr-FR/index.js b/src/i18n/fr-FR/index.js
index d30dee52..2eea9a38 100644
--- a/src/i18n/fr-FR/index.js
+++ b/src/i18n/fr-FR/index.js
@@ -134,6 +134,8 @@ export default {
introduceSearchTerm: 'Entrez un terme de recherche',
noOrdersFound: 'Aucune commande trouvée',
send: 'Envoyer',
+ fieldRequired: 'Champ obligatoire',
+ noChanges: 'Aucun changement',
// Image related translations
'Cant lock cache': "Le cache n'a pas pu être verrouillé",
'Bad file format': 'Format de fichier non reconnu',
diff --git a/src/i18n/pt-PT/index.js b/src/i18n/pt-PT/index.js
index 39bbe5de..460335e0 100644
--- a/src/i18n/pt-PT/index.js
+++ b/src/i18n/pt-PT/index.js
@@ -133,6 +133,8 @@ export default {
introduceSearchTerm: 'Digite um termo de pesquisa',
noOrdersFound: 'Nenhum pedido encontrado',
send: 'Enviar',
+ fieldRequired: 'Campo obrigatório',
+ noChanges: 'Sem alterações',
// Image related translations
'Cant lock cache': 'O cache não pôde ser bloqueado',
'Bad file format': 'Formato de arquivo inválido',
diff --git a/src/pages/Account/AccountConfig.vue b/src/pages/Account/AccountConfig.vue
index 0aec3240..edbb181e 100644
--- a/src/pages/Account/AccountConfig.vue
+++ b/src/pages/Account/AccountConfig.vue
@@ -3,8 +3,9 @@ import { ref, inject, onMounted, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
-import VnForm from 'src/components/common/VnForm.vue';
import ChangePasswordForm from 'src/components/ui/ChangePasswordForm.vue';
+import FormModel from 'src/components/common/FormModel.vue';
+import useNotify from 'src/composables/useNotify.js';
import { useUserStore } from 'stores/user';
import { useAppStore } from 'stores/app';
@@ -12,54 +13,76 @@ import { storeToRefs } from 'pinia';
const userStore = useUserStore();
const { t } = useI18n();
-const jApi = inject('jApi');
+const api = inject('api');
const appStore = useAppStore();
const { isHeaderMounted } = storeToRefs(appStore);
const { user } = storeToRefs(userStore);
+const { notify } = useNotify();
const vnFormRef = ref(null);
-const vnFormRef2 = ref(null);
const changePasswordFormDialog = ref(null);
const showChangePasswordForm = ref(false);
const langOptions = ref([]);
-const pks = computed(() => ({ id: userStore?.user?.id }));
-const fetchConfigDataSql = {
- query: `
- SELECT u.id, u.name, u.email, u.nickname,
- u.lang, c.isToBeMailed, c.id clientFk
- FROM account.myUser u
- LEFT JOIN myClient c
- ON u.id = c.id`,
- params: {}
-};
+const formInitialData = ref({});
+const showForm = ref(false);
-const fetchLanguagesSql = async () => {
+const fetchLanguages = async () => {
try {
- const data = await jApi.query(
- 'SELECT code, name FROM language WHERE isActive'
- );
+ const filter = { fields: ['code', 'name'], where: { isActive: true } };
+ const { data } = await api.get('/languages', {
+ params: { filter: JSON.stringify(filter) }
+ });
langOptions.value = data;
} catch (error) {
console.error(error);
}
};
+const fetchFormInitialData = async () => {
+ try {
+ const filter = {
+ where: { id: user?.value?.id },
+ fields: ['id', 'name', 'isToBeMailed'],
+ include: {
+ relation: 'user',
+ scope: {
+ fields: ['nickname', 'lang', 'email']
+ }
+ }
+ };
+ const { data } = await api.get('/Clients', {
+ params: { filter: JSON.stringify(filter) }
+ });
+
+ const { user: userData, ...restOfData } = data[0];
+
+ formInitialData.value = {
+ ...restOfData,
+ nickname: userData?.nickname,
+ lang: userData?.lang,
+ email: userData?.email
+ };
+ } catch (error) {
+ console.error(error);
+ } finally {
+ showForm.value = true;
+ }
+};
+
const updateUserNickname = async nickname => {
try {
- await vnFormRef.value.submit();
+ await submitAccountData(nickname);
+ await submitNickname(nickname);
user.value.nickname = nickname;
} catch (error) {
console.error(error);
}
};
-const formatMailData = data => {
- data.isToBeMailed = Boolean(data.isToBeMailed);
-};
-
const updateConfigLang = async lang => {
try {
- await vnFormRef.value.submit();
+ if (!lang) return;
+ await submitAccountData({ lang });
userStore.updateUserLang(lang);
const siteLocaleLang = appStore.localeOptions.find(
locale => locale.value === lang
@@ -70,7 +93,32 @@ const updateConfigLang = async lang => {
}
};
-onMounted(() => fetchLanguagesSql());
+const submitAccountData = async data => {
+ try {
+ const params = {
+ ...data
+ };
+ await api.patch(`/VnUsers/${user?.value?.id}`, params);
+ notify(t('dataSaved'), 'positive');
+ } catch (error) {
+ console.error(error);
+ }
+};
+
+const submitIsToBeMailed = async isToBeMailed => {
+ try {
+ const payload = { isToBeMailed };
+ await api.patch(`/Clients/${user.value.id}`, payload);
+ notify(t('dataSaved'), 'positive');
+ } catch (error) {
+ console.error(error);
+ }
+};
+
+onMounted(async () => {
+ fetchLanguages();
+ fetchFormInitialData();
+});
@@ -92,14 +140,14 @@ onMounted(() => fetchLanguagesSql());
@click="showChangePasswordForm = true"
/>
-
fetchLanguagesSql());
fetchLanguagesSql());
@update:model-value="updateConfigLang(data.lang)"
data-cy="configViewLang"
/>
+
-
- formatMailData($event)"
- >
-
-
-
-
-
-
+
{
router.push({ name: 'login' });
}
} else {
- await fetchTokenConfig();
await fetchUser();
+ await fetchTokenConfig();
await supplantInit();
startInterval();
}