Merge branch 'beta' of https://gitea.verdnatura.es/verdnatura/hedera-web into beta
gitea/hedera-web/pipeline/head There was a failure building this commit
Details
gitea/hedera-web/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
d6f1c8dc04
19
README.md
19
README.md
|
@ -6,31 +6,30 @@ Hedera is the main web page for Verdnatura.
|
|||
|
||||
Required dependencies.
|
||||
|
||||
* PHP >= 7.0
|
||||
* Node.js >= 18.0
|
||||
- PHP >= 7.0
|
||||
- Node.js >= 18.0
|
||||
|
||||
Launch application for development.
|
||||
|
||||
```
|
||||
$ quasar dev
|
||||
```
|
||||
|
||||
Launch Salix backend.
|
||||
```
|
||||
npm run salix
|
||||
|
||||
```
|
||||
|
||||
Launch legacy PHP backend.
|
||||
```
|
||||
npm run back
|
||||
pnpm run back
|
||||
```
|
||||
|
||||
Run server side method from command line.
|
||||
|
||||
```
|
||||
php hedera-web.php -m method_path
|
||||
```
|
||||
|
||||
## Built with
|
||||
|
||||
* [Webpack](https://webpack.js.org/)
|
||||
* [MooTools](https://mootools.net/)
|
||||
* [TinyMCE](https://www.tinymce.com/)
|
||||
- [Webpack](https://webpack.js.org/)
|
||||
- [MooTools](https://mootools.net/)
|
||||
- [TinyMCE](https://www.tinymce.com/)
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Connection } from '../js/db/connection';
|
|||
import { useUserStore } from 'stores/user';
|
||||
import axios from 'axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { useAppStore } from 'src/stores/app';
|
||||
|
||||
const { notify } = useNotify();
|
||||
// Be careful when using SSR for cross-request state pollution
|
||||
|
@ -37,9 +38,11 @@ const onResponseError = error => {
|
|||
|
||||
export default boot(({ app }) => {
|
||||
const userStore = useUserStore();
|
||||
const appStore = useAppStore();
|
||||
function addToken(config) {
|
||||
if (userStore.token) {
|
||||
config.headers.Authorization = userStore.token;
|
||||
config.headers['Accept-Language'] = appStore.siteLang;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ defineExpose({
|
|||
flat
|
||||
:disabled="!showBottomActions && !updatedColumns.length"
|
||||
@click="submit()"
|
||||
data-testid="formDefaultSaveButton"
|
||||
data-cy="formDefaultSaveButton"
|
||||
>
|
||||
<QTooltip>{{ t('save') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -129,17 +129,20 @@ async function filterHandler(val, update) {
|
|||
|
||||
if (!$props.defaultFilter) return update();
|
||||
const newOptions = filter(val, myOptionsOriginal.value);
|
||||
update(
|
||||
() => {
|
||||
myOptions.value = newOptions;
|
||||
},
|
||||
ref => {
|
||||
if (val !== '' && ref.options.length > 0) {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
|
||||
setTimeout(() => {
|
||||
update(
|
||||
() => {
|
||||
myOptions.value = newOptions;
|
||||
},
|
||||
ref => {
|
||||
if (val !== '' && ref.options.length > 0) {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
}, 300);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -178,6 +181,13 @@ async function filterHandler(val, update) {
|
|||
>
|
||||
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
||||
</template>
|
||||
<template #no-option>
|
||||
<QItem>
|
||||
<QItemSection class="text-grey">
|
||||
{{ t('emptyList') }}
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</QSelect>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -100,26 +100,21 @@ const onSubmit = async () => {
|
|||
en-US:
|
||||
name: Name
|
||||
file: File
|
||||
send: Send
|
||||
imageAdded: Image added successfully
|
||||
es-ES:
|
||||
name: Nombre
|
||||
file: Archivo
|
||||
send: Enviar
|
||||
imageAdded: Imagen añadida correctamente
|
||||
ca-ES:
|
||||
name: Nom
|
||||
file: Arxiu
|
||||
send: Enviar
|
||||
imageAdded: Imatge afegida correctament
|
||||
fr-FR:
|
||||
name: Nom
|
||||
file: Fichier
|
||||
send: Envoyer
|
||||
imageAdded: Image ajoutée correctement
|
||||
pt-PT:
|
||||
name: Nome
|
||||
file: Arquivo
|
||||
send: Enviar
|
||||
imageAdded: Imagen adicionada corretamente
|
||||
</i18n>
|
||||
|
|
|
@ -91,7 +91,7 @@ async function confirm() {
|
|||
@click="confirm()"
|
||||
unelevated
|
||||
autofocus
|
||||
data-testid="confirmDialogButton"
|
||||
data-cy="confirmDialogButton"
|
||||
/>
|
||||
</QCardActions>
|
||||
</QCard>
|
||||
|
|
|
@ -67,6 +67,10 @@ const url = computed(() => {
|
|||
return `${props.baseURL ?? app.imageUrl}/${props.storage}/${props.size}/${props.id}`;
|
||||
});
|
||||
|
||||
const zoomUrl = computed(() => {
|
||||
return `${props.baseURL ?? app.imageUrl}/${props.storage}/${props.zoomSize}/${props.id}`;
|
||||
});
|
||||
|
||||
const rounded = computed(() => {
|
||||
const roundedMap = {
|
||||
none: '',
|
||||
|
@ -114,7 +118,7 @@ const rounded = computed(() => {
|
|||
|
||||
<QDialog v-if="props.zoomSize" v-model="showZoom">
|
||||
<QImg
|
||||
:src="url"
|
||||
:src="zoomUrl"
|
||||
size="full"
|
||||
class="img_zoom"
|
||||
v-bind="$attrs"
|
||||
|
|
|
@ -6,10 +6,6 @@ defineProps({
|
|||
type: String,
|
||||
default: 'emptyList'
|
||||
},
|
||||
emptyIcon: {
|
||||
type: String,
|
||||
default: 'block'
|
||||
},
|
||||
rows: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
|
@ -29,7 +25,6 @@ const { t } = useI18n();
|
|||
v-if="!rows?.length"
|
||||
class="flex items-center q-pa-md justify-center items-center"
|
||||
>
|
||||
<QIcon :name="emptyIcon" size="sm" class="q-mr-sm" />
|
||||
{{ t(emptyMessage) }}
|
||||
</span>
|
||||
<QSpinner v-if="loading" color="primary" size="3em" :thickness="2" />
|
||||
|
|
|
@ -40,6 +40,11 @@ const search = async () => {
|
|||
query: searchTerm.value ? { search: searchTerm.value } : {}
|
||||
});
|
||||
|
||||
if (!searchTerm.value) {
|
||||
emit('onSearchError');
|
||||
return;
|
||||
}
|
||||
|
||||
if (props.sqlQuery) {
|
||||
data = await jApi.query(props.sqlQuery, {
|
||||
[props.searchField]: searchTerm.value
|
||||
|
@ -71,7 +76,7 @@ onMounted(() => {
|
|||
is-outlined
|
||||
:clearable="false"
|
||||
class="searchbar"
|
||||
data-testid="searchBar"
|
||||
data-cy="searchBar"
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="search" class="cursor-pointer" @click="search()" />
|
||||
|
|
|
@ -14,7 +14,7 @@ export default function useNotify() {
|
|||
type,
|
||||
icon: icon || defaultIcons[type],
|
||||
attrs: {
|
||||
'data-testid': `${type}Notify`
|
||||
'data-cy': `${type}Notify`
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -134,6 +134,7 @@ export default {
|
|||
minQuantity: 'Quantitat mínima',
|
||||
introduceSearchTerm: 'Introdueix un terme de cerca',
|
||||
noOrdersFound: `No s'han trobat comandes`,
|
||||
send: 'Enviar',
|
||||
// Image related translations
|
||||
'Cant lock cache': 'No es pot bloquejar la memòria cau',
|
||||
'Bad file format': 'Format de fitxer no reconegut',
|
||||
|
|
|
@ -168,6 +168,7 @@ export default {
|
|||
minQuantity: 'Minimum quantity',
|
||||
introduceSearchTerm: 'Enter a search term',
|
||||
noOrdersFound: 'No orders found',
|
||||
send: 'Send',
|
||||
// Image related translations
|
||||
'Cant lock cache': 'The cache could not be blocked',
|
||||
'Bad file format': 'Unrecognized file format',
|
||||
|
|
|
@ -167,6 +167,7 @@ export default {
|
|||
minQuantity: 'Cantidad mínima',
|
||||
introduceSearchTerm: 'Introduce un término de búsqueda',
|
||||
noOrdersFound: 'No se encontrado pedidos',
|
||||
send: 'Enviar',
|
||||
// Image related translations
|
||||
'Cant lock cache': 'La caché no pudo ser bloqueada',
|
||||
'Bad file format': 'Formato de archivo no reconocido',
|
||||
|
|
|
@ -135,6 +135,7 @@ export default {
|
|||
minQuantity: 'Quantité minimum',
|
||||
introduceSearchTerm: 'Entrez un terme de recherche',
|
||||
noOrdersFound: 'Aucune commande trouvée',
|
||||
send: 'Envoyer',
|
||||
// Image related translations
|
||||
'Cant lock cache': "Le cache n'a pas pu être verrouillé",
|
||||
'Bad file format': 'Format de fichier non reconnu',
|
||||
|
|
|
@ -133,6 +133,7 @@ export default {
|
|||
minQuantity: 'Quantidade mínima',
|
||||
introduceSearchTerm: 'Digite um termo de pesquisa',
|
||||
noOrdersFound: 'Nenhum pedido encontrado',
|
||||
send: 'Enviar',
|
||||
// Image related translations
|
||||
'Cant lock cache': 'O cache não pôde ser bloqueado',
|
||||
'Bad file format': 'Formato de arquivo inválido',
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
id="bg"
|
||||
class="fullscreen row justify-center items-center layout-view scroll"
|
||||
>
|
||||
<div class="column q-pa-md row items-center justify-center">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition>
|
||||
<component :is="Component" />
|
||||
</transition>
|
||||
</router-view>
|
||||
</div>
|
||||
<QPageContainer class="column q-pa-md row items-center justify-center">
|
||||
<transition>
|
||||
<router-view />
|
||||
</transition>
|
||||
</QPageContainer>
|
||||
</QLayout>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ const logoutSupplantedUser = async () => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<QLayout view="hhh Lpr fFf">
|
||||
<QLayout view="hhh LpR fFf">
|
||||
<QHeader>
|
||||
<QToolbar>
|
||||
<QBtn
|
||||
|
@ -60,7 +60,7 @@ const logoutSupplantedUser = async () => {
|
|||
class="q-mr-md"
|
||||
/>
|
||||
<img class="logo q-mr-lg" src="statics/logo-dark.svg" />
|
||||
<QToolbarTitle data-testid="headerTitle">
|
||||
<QToolbarTitle data-cy="headerTitle">
|
||||
{{ customTitle || menuTitle }}
|
||||
<div v-if="subtitle" class="subtitle text-caption">
|
||||
{{ subtitle }}
|
||||
|
@ -84,11 +84,11 @@ const logoutSupplantedUser = async () => {
|
|||
v-model="leftDrawerOpen"
|
||||
:width="250"
|
||||
show-if-above
|
||||
data-testid="layoutMenuDrawer"
|
||||
data-cy="layoutMenuDrawer"
|
||||
>
|
||||
<div class="user-info">
|
||||
<div>
|
||||
<span id="user-name" data-testid="layoutUserName">
|
||||
<span id="user-name" data-cy="layoutUserName">
|
||||
{{ mainUser?.nickname }}
|
||||
</span>
|
||||
<QBtn
|
||||
|
@ -96,7 +96,7 @@ const logoutSupplantedUser = async () => {
|
|||
icon="logout"
|
||||
alt="_Exit"
|
||||
@click="logout()"
|
||||
data-testid="logoutButton"
|
||||
data-cy="logoutButton"
|
||||
>
|
||||
<QTooltip>{{ $t('logOut') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -105,7 +105,7 @@ const logoutSupplantedUser = async () => {
|
|||
v-if="supplantedUser"
|
||||
id="supplant"
|
||||
class="supplant"
|
||||
data-testid="layoutSupplantedUserName"
|
||||
data-cy="layoutSupplantedUserName"
|
||||
>
|
||||
<span id="supplanted">
|
||||
{{ supplantedUser?.nickname }}
|
||||
|
@ -216,6 +216,10 @@ const logoutSupplantedUser = async () => {
|
|||
padding: 16px;
|
||||
}
|
||||
|
||||
div .q-drawer-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
@include mobile {
|
||||
#actions {
|
||||
.q-btn {
|
||||
|
|
|
@ -119,7 +119,7 @@ onMounted(() => fetchLanguagesSql());
|
|||
:label="t('nickname')"
|
||||
@keyup.enter="updateUserNickname(data.nickname)"
|
||||
@blur="updateUserNickname(data.nickname)"
|
||||
data-testid="configViewNickname"
|
||||
data-cy="configViewNickname"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.lang"
|
||||
|
@ -128,7 +128,7 @@ onMounted(() => fetchLanguagesSql());
|
|||
option-value="code"
|
||||
:options="langOptions"
|
||||
@update:model-value="updateConfigLang(data.lang)"
|
||||
data-testid="configViewLang"
|
||||
data-cy="configViewLang"
|
||||
/>
|
||||
</template>
|
||||
<template #extraForm>
|
||||
|
|
|
@ -93,36 +93,36 @@ onMounted(() => getCountries());
|
|||
<VnInput
|
||||
v-model="data.nickname"
|
||||
:label="t('name')"
|
||||
data-testid="addressFormNickname"
|
||||
data-cy="addressFormNickname"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.street"
|
||||
:label="t('address')"
|
||||
data-testid="addressFormStreet"
|
||||
data-cy="addressFormStreet"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.city"
|
||||
:label="t('city')"
|
||||
data-testid="addressFormCity"
|
||||
data-cy="addressFormCity"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.postalCode"
|
||||
type="number"
|
||||
:label="t('postalCode')"
|
||||
data-testid="addressFormPostcode"
|
||||
data-cy="addressFormPostcode"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.countryFk"
|
||||
:label="t('country')"
|
||||
:options="countriesOptions"
|
||||
@update:model-value="data.provinceFk = null"
|
||||
data-testid="addressFormCountry"
|
||||
data-cy="addressFormCountry"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.provinceFk"
|
||||
:label="t('province')"
|
||||
:options="provincesOptions"
|
||||
data-testid="addressFormProvince"
|
||||
data-cy="addressFormProvince"
|
||||
/>
|
||||
</template>
|
||||
</VnForm>
|
||||
|
|
|
@ -98,7 +98,7 @@ onMounted(async () => {
|
|||
@click="goToAddressDetails()"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="newAddressBtn"
|
||||
data-cy="newAddressBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('addAddress') }}
|
||||
|
@ -110,7 +110,7 @@ onMounted(async () => {
|
|||
class="rounded-borders shadow-1 shadow-transition"
|
||||
separator
|
||||
:rows="addresses"
|
||||
data-testid="addressCardList"
|
||||
data-cy="addressCardList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(address, index) in addresses"
|
||||
|
@ -158,7 +158,7 @@ onMounted(async () => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop="goToAddressDetails(address.id)"
|
||||
data-testid="editAddressBtn"
|
||||
data-cy="editAddressBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('editAddress') }}
|
||||
|
|
|
@ -44,13 +44,13 @@ const onSearch = data => (items.value = data || []);
|
|||
empty-icon="refresh"
|
||||
:loading="loading"
|
||||
:rows="items"
|
||||
data-testid="itemsViewList"
|
||||
data-cy="itemsViewList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:clickable="false"
|
||||
data-testid="itemsViewCard"
|
||||
data-cy="itemsViewCard"
|
||||
>
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
|
|
|
@ -106,7 +106,7 @@ onMounted(async () => {
|
|||
v-model="data.title"
|
||||
:label="t('title')"
|
||||
:clearable="false"
|
||||
data-testid="newsTitleInput"
|
||||
data-cy="newsTitleInput"
|
||||
/>
|
||||
<div class="row justify-between q-gutter-x-md">
|
||||
<VnSelect
|
||||
|
@ -116,14 +116,14 @@ onMounted(async () => {
|
|||
option-value="name"
|
||||
:options="newsTags"
|
||||
class="col"
|
||||
data-testid="newsTagSelect"
|
||||
data-cy="newsTagSelect"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.priority"
|
||||
:label="t('priority')"
|
||||
:clearable="false"
|
||||
class="col"
|
||||
data-testid="newsPriorityInput"
|
||||
data-cy="newsPriorityInput"
|
||||
/>
|
||||
</div>
|
||||
<QEditor
|
||||
|
|
|
@ -64,7 +64,7 @@ onMounted(async () => getNews());
|
|||
:to="{ name: 'adminNewsDetails' }"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="addNewBtn"
|
||||
data-cy="addNewBtn"
|
||||
>
|
||||
<QTooltip>{{ t('addNew') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -75,7 +75,7 @@ onMounted(async () => getNews());
|
|||
v-for="(newsItem, index) in news"
|
||||
:key="index"
|
||||
:to="{ name: 'adminNewsDetails', params: { id: newsItem.id } }"
|
||||
data-testid="newsCard"
|
||||
data-cy="newsCard"
|
||||
>
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
|
@ -108,7 +108,7 @@ onMounted(async () => getNews());
|
|||
() => deleteNew(newsItem.id, index)
|
||||
)
|
||||
"
|
||||
data-testid="deleteNewBtn"
|
||||
data-cy="deleteNewBtn"
|
||||
>
|
||||
<QTooltip>{{ t('remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -153,7 +153,7 @@ onMounted(async () => getImageCollections());
|
|||
option-label="desc"
|
||||
option-value="name"
|
||||
:options="imageCollections"
|
||||
data-testid="photoCollectionSelect"
|
||||
data-cy="photoCollectionSelect"
|
||||
/>
|
||||
<QUploader
|
||||
ref="fileUploaderRef"
|
||||
|
@ -165,19 +165,19 @@ onMounted(async () => getImageCollections());
|
|||
bordered
|
||||
hide-upload-btn
|
||||
@added="onFilesAdded"
|
||||
data-testid="photoUploader"
|
||||
data-cy="photoUploader"
|
||||
>
|
||||
<template #list="scope">
|
||||
<QList
|
||||
v-if="addedFiles.length"
|
||||
separator
|
||||
data-testid="photoUploaderList"
|
||||
data-cy="photoUploaderList"
|
||||
>
|
||||
<QItem
|
||||
v-for="(file, index) in scope.files"
|
||||
:key="file.__key"
|
||||
class="flex full-width row items-center justify-center"
|
||||
data-testid="photoUploaderItem"
|
||||
data-cy="photoUploaderItem"
|
||||
>
|
||||
<img
|
||||
:src="file.__img.src"
|
||||
|
@ -211,7 +211,7 @@ onMounted(async () => getImageCollections());
|
|||
].icon
|
||||
"
|
||||
size="sm"
|
||||
data-testid="photoUploaderItemsStatusIcon"
|
||||
data-cy="photoUploaderItemsStatusIcon"
|
||||
>
|
||||
<QTooltip>
|
||||
{{
|
||||
|
@ -237,7 +237,7 @@ onMounted(async () => getImageCollections());
|
|||
round
|
||||
icon="delete"
|
||||
@click="removeFile(file, index)"
|
||||
data-testid="photoUploaderItemsDeleteBtn"
|
||||
data-cy="photoUploaderItemsDeleteBtn"
|
||||
>
|
||||
<QTooltip>{{ t('remove') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -257,7 +257,7 @@ onMounted(async () => getImageCollections());
|
|||
no-caps
|
||||
flat
|
||||
@click="clearFiles()"
|
||||
data-testid="photoUploaderClearBtn"
|
||||
data-cy="photoUploaderClearBtn"
|
||||
/>
|
||||
<QBtn
|
||||
:label="t('uploadFiles')"
|
||||
|
@ -266,7 +266,7 @@ onMounted(async () => getImageCollections());
|
|||
flat
|
||||
:disable="!isSubmitable"
|
||||
@click="onSubmit(data)"
|
||||
data-testid="photoUploadSubmitBtn"
|
||||
data-cy="photoUploadSubmitBtn"
|
||||
/>
|
||||
</template>
|
||||
</VnForm>
|
||||
|
|
|
@ -47,7 +47,7 @@ const supplantUser = async user => {
|
|||
search-field="user"
|
||||
@on-search="onSearch"
|
||||
@on-search-error="users = []"
|
||||
data-testid="usersViewSearchBar"
|
||||
data-cy="usersViewSearchBar"
|
||||
/>
|
||||
</Teleport>
|
||||
<QPage class="vn-w-xs">
|
||||
|
@ -57,13 +57,13 @@ const supplantUser = async user => {
|
|||
empty-icon="refresh"
|
||||
:loading="loading"
|
||||
:rows="users"
|
||||
data-testid="usersViewList"
|
||||
data-cy="usersViewList"
|
||||
>
|
||||
<CardList
|
||||
v-for="(user, index) in users"
|
||||
:key="index"
|
||||
:to="{ name: 'accessLog', params: { id: user.id } }"
|
||||
data-testid="userViewCard"
|
||||
data-cy="userViewCard"
|
||||
>
|
||||
<template #content>
|
||||
<span class="text-bold q-mb-sm">
|
||||
|
@ -78,7 +78,7 @@ const supplantUser = async user => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop.prevent="supplantUser(user.name)"
|
||||
data-testid="usersViewSupplantUserBtn"
|
||||
data-cy="usersViewSupplantUserBtn"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Impersonate user') }}
|
||||
|
|
|
@ -109,12 +109,12 @@ const fetchData = async () => {
|
|||
</QBtn>
|
||||
<QBtn
|
||||
icon="shopping_bag"
|
||||
:label="t('catalog')"
|
||||
:label="t('titles.Catalog')"
|
||||
:to="{ name: 'catalog' }"
|
||||
rounded
|
||||
no-caps
|
||||
>
|
||||
<QTooltip>{{ t('catalog') }}</QTooltip>
|
||||
<QTooltip>{{ t('titles.Catalog') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
icon="shopping_cart_checkout"
|
||||
|
@ -122,7 +122,7 @@ const fetchData = async () => {
|
|||
:to="{ name: 'confirm', params: { id: orderId } }"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="basketToConfirmBtn"
|
||||
data-cy="basketToConfirmBtn"
|
||||
>
|
||||
<QTooltip>{{ t('checkout') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -19,19 +19,21 @@ const { t } = useI18n();
|
|||
v-if="viewMode === 'grid'"
|
||||
v-ripple
|
||||
class="catalog-card"
|
||||
data-testid="catalogCardGrid"
|
||||
data-cy="catalogCardGrid"
|
||||
>
|
||||
<VnImg
|
||||
storage="catalog"
|
||||
size="200x200"
|
||||
:id="item.image"
|
||||
height="210px"
|
||||
height="190px"
|
||||
rounded="bottom"
|
||||
zoom-size="1600x900"
|
||||
data-cy="catalogCardImage"
|
||||
/>
|
||||
<div
|
||||
class="column"
|
||||
style="height: 205px; padding: 10px"
|
||||
data-testid="catalogCardGridBody"
|
||||
data-cy="catalogCardGridBody"
|
||||
>
|
||||
<div class="column" style="margin-bottom: auto">
|
||||
<div class="text-subtitle2 ellipsis-2-lines">
|
||||
|
@ -45,7 +47,7 @@ const { t } = useI18n();
|
|||
</span>
|
||||
<span> #{{ item.id }}</span>
|
||||
</div>
|
||||
<div class="tags q-pt-xs text-caption">
|
||||
<div class="tags text-caption">
|
||||
<div
|
||||
v-for="(tag, index) in item.previewTags"
|
||||
:key="index"
|
||||
|
@ -75,7 +77,7 @@ const { t } = useI18n();
|
|||
<div class="row justify-between items-cente q-gutter-x-xs">
|
||||
<QBadge
|
||||
:label="`x${item.grouping}`"
|
||||
color="grey"
|
||||
color="grey-4"
|
||||
class="col-2 justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
@ -85,8 +87,7 @@ const { t } = useI18n();
|
|||
<QBadge
|
||||
outline
|
||||
:label="item.available"
|
||||
color="accent"
|
||||
text-color="black"
|
||||
color="grey-6"
|
||||
class="col justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
@ -97,7 +98,6 @@ const { t } = useI18n();
|
|||
outline
|
||||
:label="currency(item.price)"
|
||||
color="accent"
|
||||
text-color="black"
|
||||
class="col justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
@ -107,7 +107,7 @@ const { t } = useI18n();
|
|||
</div>
|
||||
</div>
|
||||
</QCard>
|
||||
<CardList v-else class="vn-w-sm" data-testid="catalogCardList">
|
||||
<CardList v-else class="vn-w-sm" data-cy="catalogCardList">
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
storage="catalog"
|
||||
|
@ -117,6 +117,8 @@ const { t } = useI18n();
|
|||
height="105px"
|
||||
rounded-borders="full"
|
||||
class="q-mr-md"
|
||||
zoom-size="1600x900"
|
||||
data-cy="catalogCardImage"
|
||||
/>
|
||||
</template>
|
||||
<template #content>
|
||||
|
@ -153,7 +155,8 @@ const { t } = useI18n();
|
|||
<div class="row justify-end items-center q-gutter-x-xs q-mt-sm">
|
||||
<QBadge
|
||||
:label="`x${item.grouping}`"
|
||||
color="grey"
|
||||
color="grey-4"
|
||||
text-color="black"
|
||||
class="col-2 justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
@ -163,8 +166,7 @@ const { t } = useI18n();
|
|||
<QBadge
|
||||
outline
|
||||
:label="item.available"
|
||||
color="accent"
|
||||
text-color="black"
|
||||
color="grey-6"
|
||||
class="col-3 justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
@ -175,7 +177,6 @@ const { t } = useI18n();
|
|||
outline
|
||||
:label="currency(item.price)"
|
||||
color="accent"
|
||||
text-color="black"
|
||||
class="col-3 justify-end text-body2"
|
||||
>
|
||||
<QTooltip>
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<template>
|
||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||
<div class="row">
|
||||
<VnSearchBar :search-term="search" @on-search-error="items = []" />
|
||||
<VnSearchBar
|
||||
@on-search-error="
|
||||
() => {
|
||||
items = [];
|
||||
search = '';
|
||||
}
|
||||
"
|
||||
/>
|
||||
<QBtn
|
||||
:icon="viewTypeButtonContent.icon"
|
||||
:label="viewTypeButtonContent.label"
|
||||
|
@ -19,7 +26,7 @@
|
|||
@click="redirectToBasket()"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="catalogGoToBasketButton"
|
||||
data-cy="catalogGoToBasketButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('shoppingCart') }}
|
||||
|
@ -36,7 +43,7 @@
|
|||
/>
|
||||
</div>
|
||||
</Teleport>
|
||||
<div style="padding-bottom: 5em">
|
||||
<div>
|
||||
<QDrawer v-model="rightDrawerOpen" side="right" :width="250" persistent>
|
||||
<div class="q-pa-md">
|
||||
<div class="basket-info q-gutter-y-sm">
|
||||
|
@ -54,7 +61,10 @@
|
|||
rounded
|
||||
no-caps
|
||||
@click="redirectToCheckout()"
|
||||
data-testid="orderModifyButton"
|
||||
data-cy="orderModifyButton"
|
||||
color="light-green-7"
|
||||
unelevated
|
||||
text-color="white"
|
||||
>
|
||||
{{ t('modify') }}
|
||||
</QBtn>
|
||||
|
@ -80,7 +90,7 @@
|
|||
:class="{ active: category == cat.id }"
|
||||
:key="cat.id"
|
||||
@click="selectedCategory = cat.id"
|
||||
data-testid="catalogCategoryButton"
|
||||
data-cy="catalogCategoryButton"
|
||||
>
|
||||
<img :src="`statics/category/${cat.code}.svg`" />
|
||||
<QTooltip>{{ cat.name }}</QTooltip>
|
||||
|
@ -98,7 +108,7 @@
|
|||
:options="itemFamilies"
|
||||
:disable="!category"
|
||||
:label="t('family')"
|
||||
data-testid="catalogFamilySelect"
|
||||
data-cy="catalogFamilySelect"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="selectedColor"
|
||||
|
@ -132,6 +142,12 @@
|
|||
:disable="!category"
|
||||
:label="t('category')"
|
||||
/>
|
||||
<div
|
||||
v-if="isSomeFilterSelected"
|
||||
class="q-mt-md text-grey-7"
|
||||
>
|
||||
{{ t('orderBy') }}
|
||||
</div>
|
||||
<VnSelect
|
||||
v-if="isSomeFilterSelected"
|
||||
v-model="selectedOrderBy"
|
||||
|
@ -139,7 +155,7 @@
|
|||
option-value="value"
|
||||
option-label="label"
|
||||
:is-clearable="false"
|
||||
:label="t('orderBy')"
|
||||
:label="t('sort')"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
|
@ -153,7 +169,7 @@
|
|||
<div
|
||||
:class="
|
||||
viewMode === 'grid'
|
||||
? 'q-pa-md row justify-center q-gutter-md'
|
||||
? ' row justify-center q-gutter-md'
|
||||
: 'column items-center'
|
||||
"
|
||||
>
|
||||
|
@ -167,7 +183,6 @@
|
|||
v-else-if="!items || !items.length || !isSomeFilterSelected"
|
||||
class="text-subtitle1 text-grey-7 q-pa-md"
|
||||
>
|
||||
<QIcon name="refresh" size="sm" class="q-mr-sm"></QIcon>
|
||||
<span>{{ t('pleaseSetFilter') }}</span>
|
||||
</div>
|
||||
<CatalogCard
|
||||
|
@ -177,16 +192,17 @@
|
|||
:item="_item"
|
||||
:view-mode="viewMode"
|
||||
@click="showItem(_item)"
|
||||
data-cy="catalogCardElement"
|
||||
/>
|
||||
</div>
|
||||
<QDialog v-model="showItemDialog" @hide="resetAmounts()">
|
||||
<QCard style="width: 25em" class="column">
|
||||
<QCard v-if="selectedItem" style="width: 25em" class="column">
|
||||
<div class="q-pa-md relative-position">
|
||||
<div class="q-mb-md" style="display: flex">
|
||||
<VnImg
|
||||
storage="catalog"
|
||||
size="200x200"
|
||||
:id="'asd'"
|
||||
:id="selectedItem.image"
|
||||
width="112px"
|
||||
height="112px"
|
||||
rounded="bottom"
|
||||
|
@ -251,7 +267,7 @@
|
|||
flat
|
||||
dense
|
||||
@click="onAddLotClick(lot)"
|
||||
data-testid="addItemQuantityButton"
|
||||
data-cy="addItemQuantityButton"
|
||||
>
|
||||
<QTooltip>{{ t('add') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -276,12 +292,13 @@
|
|||
flat
|
||||
color="white"
|
||||
@click="onConfirmClick()"
|
||||
data-testid="catalogAddToBasketButton"
|
||||
data-cy="catalogAddToBasketButton"
|
||||
>
|
||||
<QTooltip>{{ t('confirm') }}</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
</QCard>
|
||||
<QSpinner v-else color="primary" size="3em" :thickness="5" />
|
||||
</QDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -744,7 +761,8 @@ const getSubcategories = async () => {
|
|||
DROP TEMPORARY TABLE tmp.itemAvailable;`,
|
||||
{ orderId: basketOrderId.value }
|
||||
);
|
||||
itemSubcategories.value = res.results[1].data;
|
||||
const filtered = res.results[1].data.filter(item => item.category);
|
||||
itemSubcategories.value = filtered.map(i => i.category);
|
||||
} catch (error) {
|
||||
console.error('Error getting subcategories:', error);
|
||||
}
|
||||
|
@ -753,11 +771,13 @@ const getSubcategories = async () => {
|
|||
const showItem = async item => {
|
||||
if (checkGuest()) return;
|
||||
|
||||
const itemLots = await calcItem(item.id);
|
||||
const tags = await getItemTags(item.id);
|
||||
showItemDialog.value = true;
|
||||
const [itemLots, tags] = await Promise.all([
|
||||
calcItem(item.id),
|
||||
getItemTags(item.id)
|
||||
]);
|
||||
item.lots = itemLots;
|
||||
item.tags = tags;
|
||||
showItemDialog.value = true;
|
||||
selectedItem.value = item;
|
||||
};
|
||||
|
||||
|
@ -848,6 +868,7 @@ const onAddLotClick = async lot => {
|
|||
};
|
||||
|
||||
const resetAmounts = () => {
|
||||
selectedItem.value = null;
|
||||
addedItemsAmountAcc.value = {};
|
||||
amount.value = 0;
|
||||
};
|
||||
|
@ -1031,6 +1052,8 @@ en-US:
|
|||
filterBy: Filter by
|
||||
chooseCategory: Choose a category
|
||||
youMustBeLoggedIn: You must be a registered user
|
||||
sort: Order
|
||||
amountNotAvailable: Amount not available
|
||||
es-ES:
|
||||
category: Categoría
|
||||
deleteFilter: Quitar filtro
|
||||
|
@ -1054,6 +1077,8 @@ es-ES:
|
|||
filterBy: Filtrar por
|
||||
chooseCategory: Elige una categoría
|
||||
youMustBeLoggedIn: Debes estar registrado como usuario
|
||||
sort: Ordenar
|
||||
amountNotAvailable: Cantidad no disponible
|
||||
ca-ES:
|
||||
category: Categoría
|
||||
deleteFilter: Eliminar filtro
|
||||
|
@ -1075,6 +1100,8 @@ ca-ES:
|
|||
filterBy: Filtrar per
|
||||
chooseCategory: Tria una categoria
|
||||
youMustBeLoggedIn: Has d'estar registrat com a usuari
|
||||
sort: Ordenar
|
||||
amountNotAvailable: Quantitat no disponible
|
||||
fr-FR:
|
||||
category: Catégorie
|
||||
deleteFilter: Supprimer le filtre
|
||||
|
@ -1096,6 +1123,8 @@ fr-FR:
|
|||
filterBy: Filtrer par
|
||||
chooseCategory: Choisissez une catégorie
|
||||
youMustBeLoggedIn: Vous devez être un utilisateur enregistré
|
||||
sort: Trier
|
||||
amountNotAvailable: Quantité non disponible
|
||||
pt-PT:
|
||||
category: Categoria
|
||||
deleteFilter: Apagar filtro
|
||||
|
@ -1117,4 +1146,6 @@ pt-PT:
|
|||
filterBy: Filtrar por
|
||||
chooseCategory: Escolha uma categoria
|
||||
youMustBeLoggedIn: Deves estar registrado como usuario
|
||||
sort: Ordenar
|
||||
amountNotAvailable: Quantidade não disponível
|
||||
</i18n>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, inject, computed } from 'vue';
|
||||
import { ref, onMounted, inject, computed, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
|
@ -28,6 +28,7 @@ const agencies = ref([]);
|
|||
const warehouses = ref([]);
|
||||
const currentStep = ref('method');
|
||||
const id = route.params.id;
|
||||
const defaultValues = ref(null);
|
||||
const orderForm = ref({
|
||||
method: 'AGENCY',
|
||||
date: formatDate(Date.vnNew(), 'YYYY/MM/DD'),
|
||||
|
@ -179,6 +180,15 @@ const getAgencies = async () => {
|
|||
}
|
||||
);
|
||||
agencies.value = results[1].data;
|
||||
|
||||
if (agencies.value && agencies.value.length && defaultValues.value) {
|
||||
const found = agencies.value.find(
|
||||
agency => agency.id === defaultValues.value.defaultAgencyFk
|
||||
);
|
||||
|
||||
if (found)
|
||||
orderForm.value.agency = defaultValues.value.defaultAgencyFk;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error getting agencies:', error);
|
||||
}
|
||||
|
@ -284,6 +294,13 @@ const submit = async () => {
|
|||
}
|
||||
};
|
||||
|
||||
const getDefaultValues = async () => {
|
||||
return await jApi.query(
|
||||
`SELECT deliveryMethod, agencyModeFk, addressFk, defaultAgencyFk
|
||||
FROM myBasketDefaults`
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
today.value = Date.vnNew();
|
||||
today.value.setHours(0, 0, 0, 0);
|
||||
|
@ -305,10 +322,21 @@ onMounted(async () => {
|
|||
orderForm.value.agency = order.agencyModeFk;
|
||||
orderForm.value.address = order.addressFk;
|
||||
}
|
||||
} else {
|
||||
const [_defaultValues] = await getDefaultValues();
|
||||
if (_defaultValues) defaultValues.value = _defaultValues;
|
||||
}
|
||||
|
||||
getAddresses();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => orderForm.value.method,
|
||||
() => {
|
||||
orderForm.value.address = '';
|
||||
orderForm.value.agency = '';
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -322,7 +350,7 @@ onMounted(async () => {
|
|||
:flat="isMobile"
|
||||
contracted
|
||||
class="default-radius stepper-container"
|
||||
data-testid="checkoutStepper"
|
||||
data-cy="checkoutStepper"
|
||||
>
|
||||
<QStep
|
||||
v-for="(step, stepIndex) in steps[orderForm.method]"
|
||||
|
@ -375,7 +403,7 @@ onMounted(async () => {
|
|||
<QList
|
||||
v-if="step.name === 'address'"
|
||||
class="vn-w-xs q-gutter-y-sm column"
|
||||
data-testid="checkoutAddressStep"
|
||||
data-cy="checkoutAddressStep"
|
||||
>
|
||||
<span class="text-h6 step-title">
|
||||
{{
|
||||
|
@ -419,7 +447,7 @@ onMounted(async () => {
|
|||
option-label="description"
|
||||
option-value="id"
|
||||
:options="agencies"
|
||||
data-testid="agencyStepSelect"
|
||||
data-cy="agencyStepSelect"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
@ -434,7 +462,7 @@ onMounted(async () => {
|
|||
option-label="description"
|
||||
option-value="id"
|
||||
:options="warehouses"
|
||||
data-testid="pickupStepSelect"
|
||||
data-cy="pickupStepSelect"
|
||||
/>
|
||||
</div>
|
||||
<!-- Confirm step -->
|
||||
|
@ -461,14 +489,14 @@ onMounted(async () => {
|
|||
icon="arrow_back"
|
||||
dense
|
||||
class="left-navigation-button"
|
||||
data-testid="checkoutStepperLeftButton"
|
||||
data-cy="checkoutStepperLeftButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t(`${step.backButtonLabel || 'back'}`) }}
|
||||
</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
v-if="showNavigationButtons"
|
||||
v-if="showNavigationButtons || currentStep === 'confirm'"
|
||||
@click="onNextStep(stepIndex)"
|
||||
:color="currentStep === 'confirm' ? 'accent ' : 'primary'"
|
||||
:icon="
|
||||
|
@ -476,7 +504,8 @@ onMounted(async () => {
|
|||
"
|
||||
dense
|
||||
class="right-navigation-button"
|
||||
data-testid="checkoutStepperRightButton"
|
||||
data-cy="checkoutStepperRightButton"
|
||||
:loading="loading"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t(`${step.nextButtonLabel || 'next'}`) }}
|
||||
|
@ -491,7 +520,7 @@ onMounted(async () => {
|
|||
@import 'src/css/responsive';
|
||||
|
||||
.step-title {
|
||||
min-width: 100%;
|
||||
max-width: 90%;
|
||||
margin-bottom: 16px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
@ -523,7 +552,7 @@ onMounted(async () => {
|
|||
.left-navigation-button {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 50%;
|
||||
top: 25px;
|
||||
@include mobile {
|
||||
top: 35%;
|
||||
}
|
||||
|
@ -532,7 +561,7 @@ onMounted(async () => {
|
|||
.right-navigation-button {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
top: 25px;
|
||||
@include mobile {
|
||||
top: 35%;
|
||||
}
|
||||
|
|
|
@ -288,9 +288,8 @@ onMounted(async () => {
|
|||
>
|
||||
<div
|
||||
v-if="!transferAccounts.length"
|
||||
class="row items-center justify-center q-pa-md bg-red"
|
||||
class="row items-center justify-center q-pa-md"
|
||||
>
|
||||
<QIcon class="q-mr-md" name="block" size="sm" />
|
||||
<span>{{ t('emptyList') }}</span>
|
||||
</div>
|
||||
<QList>
|
||||
|
|
|
@ -73,7 +73,7 @@ const onConfirmPay = async () => {
|
|||
@click="onPayClick()"
|
||||
rounded
|
||||
no-caps
|
||||
data-testid="makePaymentButton"
|
||||
data-cy="makePaymentButton"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('makePayment') }}
|
||||
|
@ -126,7 +126,7 @@ const onConfirmPay = async () => {
|
|||
v-model="showAmountToPayDialog"
|
||||
message=" "
|
||||
:promise="onConfirmPay"
|
||||
data-testid="payAmountDialog"
|
||||
data-cy="payAmountDialog"
|
||||
>
|
||||
<template #customHTML>
|
||||
<VnInput
|
||||
|
@ -136,7 +136,7 @@ const onConfirmPay = async () => {
|
|||
type="number"
|
||||
min="0"
|
||||
:max="debt * -1"
|
||||
data-testid="payAmountInput"
|
||||
data-cy="payAmountInput"
|
||||
>
|
||||
<template #append>€</template>
|
||||
</VnInput>
|
||||
|
|
|
@ -71,7 +71,7 @@ onMounted(async () => {
|
|||
<template>
|
||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||
<QBtn
|
||||
data-testid="pendingOrdersNewOrder"
|
||||
data-cy="pendingOrdersNewOrder"
|
||||
:to="{ name: 'checkout' }"
|
||||
icon="add_shopping_cart"
|
||||
:label="t('newOrder')"
|
||||
|
@ -84,16 +84,12 @@ onMounted(async () => {
|
|||
</QBtn>
|
||||
</Teleport>
|
||||
<QPage class="vn-w-sm">
|
||||
<VnList
|
||||
:rows="orders"
|
||||
:loading="loading"
|
||||
data-testid="pendingOrdersList"
|
||||
>
|
||||
<VnList :rows="orders" :loading="loading" data-cy="pendingOrdersList">
|
||||
<CardList
|
||||
v-for="(order, index) in orders"
|
||||
:key="index"
|
||||
:to="{ name: 'basket', params: { id: order.id } }"
|
||||
data-testid="pendingOrderCard"
|
||||
data-cy="pendingOrderCard"
|
||||
>
|
||||
<template #content>
|
||||
<QItemLabel class="text-bold q-mb-sm">
|
||||
|
@ -116,7 +112,7 @@ onMounted(async () => {
|
|||
() => removeOrder(order.id, index)
|
||||
)
|
||||
"
|
||||
data-testid="pendingOrderCardDelete"
|
||||
data-cy="pendingOrderCardDelete"
|
||||
>
|
||||
<QTooltip>{{ t('deleteOrder') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
@ -125,7 +121,7 @@ onMounted(async () => {
|
|||
flat
|
||||
rounded
|
||||
@click.stop.prevent="loadOrder(order.id)"
|
||||
data-testid="addOrderToBasket"
|
||||
data-cy="addOrderToBasket"
|
||||
>
|
||||
<QTooltip>{{ t('loadOrderIntoCart') }}</QTooltip>
|
||||
</QBtn>
|
||||
|
|
|
@ -111,7 +111,7 @@ const deleteRow = id => {
|
|||
</QCardSection>
|
||||
<QSeparator v-if="showItems" inset />
|
||||
<QList v-for="(row, index) in rows" :key="index">
|
||||
<QItem v-if="row" data-testid="basketItemRow">
|
||||
<QItem v-if="row" data-cy="basketItemRow">
|
||||
<QItemSection v-if="canDeleteItems" avatar>
|
||||
<QBtn
|
||||
icon="delete"
|
||||
|
@ -172,7 +172,6 @@ const deleteRow = id => {
|
|||
class="row items-center justify-center q-pa-md"
|
||||
style="margin-top: 32px"
|
||||
>
|
||||
<QIcon class="q-mr-md" name="block" size="sm" />
|
||||
<span>{{ t('emptyList') }}</span>
|
||||
</div>
|
||||
</QCard>
|
||||
|
|
|
@ -73,17 +73,17 @@ const loginAsGuest = async () => {
|
|||
v-model="email"
|
||||
:label="$t('user')"
|
||||
autofocus
|
||||
data-testid="loginUserInput"
|
||||
data-cy="loginUserInput"
|
||||
/>
|
||||
<QInput
|
||||
v-model="password"
|
||||
:label="$t('password')"
|
||||
:type="!showPwd ? 'password' : 'text'"
|
||||
data-testid="loginPasswordInput"
|
||||
data-cy="loginPasswordInput"
|
||||
>
|
||||
<template #append>
|
||||
<QIcon
|
||||
data-testid="showPasswordIcon"
|
||||
data-cy="showPasswordIcon"
|
||||
:name="showPwd ? 'visibility_off' : 'visibility'"
|
||||
class="cursor-pointer"
|
||||
@click="showPwd = !showPwd"
|
||||
|
@ -92,14 +92,14 @@ const loginAsGuest = async () => {
|
|||
</QInput>
|
||||
<div class="row justify-between text-center">
|
||||
<QCheckbox
|
||||
data-testid="rememberCheckbox"
|
||||
data-cy="rememberCheckbox"
|
||||
v-model="remember"
|
||||
:label="$t('remindMe')"
|
||||
dense
|
||||
class="col"
|
||||
/>
|
||||
<QSelect
|
||||
data-testid="switchLanguage"
|
||||
data-cy="switchLanguage"
|
||||
v-model="selectedLocaleValue"
|
||||
:options="localeOptions"
|
||||
:label="t('language')"
|
||||
|
@ -126,7 +126,7 @@ const loginAsGuest = async () => {
|
|||
</div>
|
||||
<div class="justify-center">
|
||||
<QBtn
|
||||
data-testid="loginAsGuestButton"
|
||||
data-cy="loginAsGuestButton"
|
||||
@click="loginAsGuest()"
|
||||
:label="$t('logInAsGuest')"
|
||||
class="full-width"
|
||||
|
@ -136,8 +136,11 @@ const loginAsGuest = async () => {
|
|||
outline
|
||||
/>
|
||||
</div>
|
||||
<p class="password-forgotten text-center q-mt-lg">
|
||||
<router-link to="/remember-password" class="link">
|
||||
<p
|
||||
class="password-forgotten text-center q-mt-lg"
|
||||
data-cy="recoverPasswordViewLink"
|
||||
>
|
||||
<router-link :to="{ name: 'recoverPassword' }" class="link">
|
||||
{{ $t('haveForgottenPassword') }}
|
||||
</router-link>
|
||||
</p>
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { api } from 'boot/axios';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const user = ref('');
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const { notify } = useNotify();
|
||||
|
||||
const onSend = async () => {
|
||||
const params = {
|
||||
user: user.value,
|
||||
app: 'hedera'
|
||||
};
|
||||
await api.post('VnUsers/recoverPassword', params);
|
||||
notify(t('weHaveSentEmailToRecover'), 'positive');
|
||||
router.push('/login');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="text-center">
|
||||
<div>
|
||||
<QIcon
|
||||
name="contact_support"
|
||||
class="block q-mx-auto text-accent"
|
||||
style="font-size: 120px"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<QForm @submit="onSend" class="q-gutter-y-md text-grey-8">
|
||||
<VnInput
|
||||
v-model="user"
|
||||
:label="t('user')"
|
||||
autofocus
|
||||
data-cy="recoverPasswordUserInput"
|
||||
/>
|
||||
<div class="q-mt-lg">
|
||||
{{ t('weSendEmail') }}
|
||||
</div>
|
||||
<div>
|
||||
<QBtn
|
||||
type="submit"
|
||||
:label="t('send')"
|
||||
class="full-width q-mt-md"
|
||||
color="primary"
|
||||
rounded
|
||||
no-caps
|
||||
unelevated
|
||||
data-cy="recoverPasswordSubmitButton"
|
||||
/>
|
||||
<div class="text-center q-mt-md">
|
||||
<router-link to="/login" class="link">
|
||||
{{ t('back') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</QForm>
|
||||
</div>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.q-btn {
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
inputEmail: Input email
|
||||
rememberPassword: Rememeber password
|
||||
weSendEmail: We will sent you an email to recover your password
|
||||
weHaveSentEmailToRecover: We've sent you an email where you can recover your password
|
||||
es-ES:
|
||||
inputEmail: Introduce el correo electrónico
|
||||
rememberPassword: Recordar contraseña
|
||||
weSendEmail: Te enviaremos un correo para restablecer tu contraseña
|
||||
weHaveSentEmailToRecover: Te hemos enviado un correo donde podrás recuperar tu contraseña
|
||||
ca-ES:
|
||||
inputEmail: Introdueix el correu electrònic
|
||||
rememberPassword: Recordar contrasenya
|
||||
weSendEmail: T'enviarem un correu per restablir la teva contrasenya
|
||||
weHaveSentEmailToRecover: T'hem enviat un correu on podràs recuperar la teva contrasenya
|
||||
fr-FR:
|
||||
inputEmail: Entrez l'email
|
||||
rememberPassword: Se souvenir du mot de passe
|
||||
weSendEmail: Nous vous enverrons un e-mail pour récupérer votre mot de passe
|
||||
weHaveSentEmailToRecover: Nous vous avons envoyé un e-mail où vous pouvez récupérer votre mot de passe
|
||||
pr-BR:
|
||||
inputEmail: Digite o e-mail
|
||||
rememberPassword: Lembrar senha
|
||||
weSendEmail: Enviaremos um e-mail para recuperar sua senha
|
||||
weHaveSentEmailToRecover: Enviamos um e-mail onde você pode recuperar sua senha
|
||||
</i18n>
|
|
@ -1,114 +0,0 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<div>
|
||||
<QIcon
|
||||
name="contact_support"
|
||||
class="block q-mx-auto text-accent"
|
||||
style="font-size: 120px"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<QForm
|
||||
@submit="onSend"
|
||||
class="q-gutter-y-md text-grey-8"
|
||||
>
|
||||
<div class="text-h5">
|
||||
<div>
|
||||
{{ $t('dontWorry') }}
|
||||
</div>
|
||||
<div>
|
||||
{{ $t('fillData') }}
|
||||
</div>
|
||||
</div>
|
||||
<QInput
|
||||
v-model="email"
|
||||
:label="$t('user')"
|
||||
:rules="[val => !!val || $t('inputEmail')]"
|
||||
autofocus
|
||||
/>
|
||||
<div class="q-mt-lg">
|
||||
{{ $t('weSendEmail') }}
|
||||
</div>
|
||||
<div>
|
||||
<QBtn
|
||||
type="submit"
|
||||
:label="$t('send')"
|
||||
class="full-width q-mt-md"
|
||||
color="primary"
|
||||
rounded
|
||||
no-caps
|
||||
unelevated
|
||||
/>
|
||||
<div class="text-center q-mt-md">
|
||||
<router-link
|
||||
to="/login"
|
||||
class="link"
|
||||
>
|
||||
{{ $t('return') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</QForm>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#image {
|
||||
height: 190px;
|
||||
}
|
||||
.q-btn {
|
||||
height: 50px;
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'VnRememberPasword',
|
||||
data() {
|
||||
return {
|
||||
email: ''
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async onSend() {
|
||||
const params = {
|
||||
email: this.email
|
||||
};
|
||||
await this.$axios.post('Users/reset', params);
|
||||
this.$q.notify({
|
||||
message: this.$t('weHaveSentEmailToRecover'),
|
||||
type: 'positive'
|
||||
});
|
||||
this.$router.push('/login');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
user: User
|
||||
inputEmail: Input email
|
||||
rememberPassword: Rememeber password
|
||||
dontWorry: Don't worry!
|
||||
fillData: Fill the data
|
||||
weSendEmail: We will sent you an email to recover your password
|
||||
weHaveSentEmailToRecover: We've sent you an email where you can recover your password
|
||||
send: Send
|
||||
return: Return
|
||||
es-ES:
|
||||
user: Usuario
|
||||
inputEmail: Introduce el correo electrónico
|
||||
rememberPassword: Recordar contraseña
|
||||
dontWorry: ¡No te preocupes!
|
||||
fillData: Rellena los datos
|
||||
weSendEmail: Te enviaremos un correo para restablecer tu contraseña
|
||||
weHaveSentEmailToRecover: Te hemos enviado un correo donde podrás recuperar tu contraseña
|
||||
send: Enviar
|
||||
return: Volver
|
||||
</i18n>
|
|
@ -39,10 +39,11 @@ export default route(function (/* { store, ssrContext } */) {
|
|||
|
||||
Router.beforeEach((to, from, next) => {
|
||||
const userStore = useUserStore();
|
||||
const allowedRoutes = ['login', 'recoverPassword'];
|
||||
|
||||
if (
|
||||
!userStore.storage.getItem('token') &&
|
||||
to.name !== 'login' &&
|
||||
!allowedRoutes.includes(to.name) &&
|
||||
!userStore.isGuest
|
||||
) {
|
||||
return next({ name: 'login' });
|
||||
|
|
|
@ -5,17 +5,17 @@ const routes = [
|
|||
children: [
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login/:email?',
|
||||
path: '',
|
||||
component: () => import('pages/Login/LoginView.vue')
|
||||
},
|
||||
{
|
||||
name: 'rememberPassword',
|
||||
path: '/remember-password',
|
||||
component: () => import('pages/Login/RememberPassword.vue')
|
||||
name: 'recoverPassword',
|
||||
path: 'recover',
|
||||
component: () => import('pages/Login/RecoverPassword.vue')
|
||||
},
|
||||
{
|
||||
name: 'resetPassword',
|
||||
path: '/reset-password',
|
||||
path: 'reset',
|
||||
component: () => import('pages/Login/ResetPassword.vue')
|
||||
}
|
||||
]
|
||||
|
|
|
@ -20,12 +20,7 @@ export const useAppStore = defineStore('hedera', {
|
|||
menuEssentialLinks: [],
|
||||
hiddenMenuLinks: new Set(['Reports']),
|
||||
basketOrderId: null,
|
||||
localeDates: {
|
||||
days: [],
|
||||
months: [],
|
||||
daysShort: [],
|
||||
monthsShort: []
|
||||
},
|
||||
|
||||
siteLang: null,
|
||||
localeOptions: [
|
||||
{ label: t('langs.en'), lang: 'en-US', value: 'en' },
|
||||
|
@ -66,20 +61,9 @@ export const useAppStore = defineStore('hedera', {
|
|||
this.$patch({ imageUrl });
|
||||
},
|
||||
|
||||
getLocaleDates() {
|
||||
const { messages, locale } = i18n.global;
|
||||
this.localeDates = {
|
||||
days: messages.value[locale.value].date.days,
|
||||
months: messages.value[locale.value].date.months,
|
||||
daysShort: messages.value[locale.value].date.daysShort,
|
||||
monthsShort: messages.value[locale.value].date.monthsShort
|
||||
};
|
||||
},
|
||||
|
||||
async init() {
|
||||
this.updateSiteLocale(localStorage.getItem('siteLang') || 'es-ES');
|
||||
this.getBasketOrderId();
|
||||
this.getLocaleDates();
|
||||
},
|
||||
|
||||
getBasketOrderId() {
|
||||
|
@ -187,6 +171,12 @@ export const useAppStore = defineStore('hedera', {
|
|||
isDesktop() {
|
||||
const $q = useQuasar();
|
||||
return $q?.screen?.width > 1024;
|
||||
},
|
||||
localeDates() {
|
||||
const { messages, locale } = i18n.global;
|
||||
const { days, months, daysShort, monthsShort } =
|
||||
messages.value[locale.value].date;
|
||||
return { days, months, daysShort, monthsShort };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('NewsView', () => {
|
|||
cy.dataCy('newsTitleInput').should('exist');
|
||||
cy.dataCy('newsTitleInput').find('input').type('Test new');
|
||||
cy.dataCy('newsTagSelect').should('exist');
|
||||
cy.selectOption('[data-testid="newsTagSelect"]', 'Curso');
|
||||
cy.selectOption('[data-cy="newsTagSelect"]', 'Curso');
|
||||
cy.dataCy('newsPriorityInput').should('exist');
|
||||
cy.dataCy('newsPriorityInput').find('input').type('2');
|
||||
cy.dataCy('formDefaultSaveButton').should('not.be.disabled');
|
||||
|
|
|
@ -15,8 +15,8 @@ describe('Photo Uploader Component', () => {
|
|||
|
||||
it('should allow selecting a photo collection', () => {
|
||||
// Simular la selección de una colección de fotos
|
||||
cy.selectOption('[data-testid="photoCollectionSelect"]', 'Enlace');
|
||||
cy.getValue('[data-testid="photoCollectionSelect"]').should(
|
||||
cy.selectOption('[data-cy="photoCollectionSelect"]', 'Enlace');
|
||||
cy.getValue('[data-cy="photoCollectionSelect"]').should(
|
||||
'equal',
|
||||
'Enlace'
|
||||
);
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
Cypress.Commands.add('addItemToBasketFlow', () => {
|
||||
// 1- Seleccionar categoría
|
||||
cy.dataCy('catalogCategoryButton').should('exist');
|
||||
cy.get('[data-testid="catalogCategoryButton"]:first').click();
|
||||
cy.get('[data-cy="catalogCategoryButton"]:first').click();
|
||||
// 2- Seleccionar familia
|
||||
cy.dataCy('catalogFamilySelect').should('exist');
|
||||
cy.selectOption('[data-testid="catalogFamilySelect"]', 'Anthurium');
|
||||
cy.getValue('[data-testid="catalogFamilySelect"]').should(
|
||||
'equal',
|
||||
'Anthurium'
|
||||
);
|
||||
cy.selectOption('[data-cy="catalogFamilySelect"]', 'Anthurium');
|
||||
cy.getValue('[data-cy="catalogFamilySelect"]').should('equal', 'Anthurium');
|
||||
cy.dataCy('catalogFamilySelect').should('exist');
|
||||
// 3- Seleccionar item
|
||||
cy.dataCy('catalogCardGridBody').should('exist');
|
||||
cy.get('[data-testid="catalogCardGridBody"]:first').click();
|
||||
cy.get('[data-cy="catalogCardGridBody"]:first').click();
|
||||
// 4- Añadir item al carrito
|
||||
cy.dataCy('addItemQuantityButton').should('exist');
|
||||
cy.get('[data-testid="addItemQuantityButton"]:first').click();
|
||||
cy.get('[data-cy="addItemQuantityButton"]:first').click();
|
||||
cy.dataCy('catalogAddToBasketButton').should('exist');
|
||||
cy.dataCy('catalogAddToBasketButton').click();
|
||||
cy.checkNotify('positive', 'Añadido');
|
||||
|
|
|
@ -42,4 +42,14 @@ describe('CatalogView', () => {
|
|||
cy.dataCy('catalogGoToBasketButton').click();
|
||||
cy.url().should('contain', '/#/ecomerce/basket');
|
||||
});
|
||||
|
||||
it('Open item details and image exists', () => {
|
||||
// cy.resetDB();
|
||||
cy.login('developer');
|
||||
cy.createOrderReceiveFlow();
|
||||
cy.addItemToBasketFlow();
|
||||
cy.dataCy('catalogCardElement').first().click();
|
||||
cy.wait(200);
|
||||
cy.dataCy('catalogCardImage').find('img').should('exist');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const checkoutNextStep = () => {
|
||||
cy.dataCy('checkoutStepperRightButton').should('be.visible').click();
|
||||
cy.dataCy('checkoutStepperRightButton').last().should('be.visible').click();
|
||||
};
|
||||
|
||||
Cypress.Commands.add('createOrderReceive', () => {
|
||||
|
@ -29,7 +29,7 @@ Cypress.Commands.add('createOrderReceive', () => {
|
|||
'¿Cómo quieres recibir el pedido?'
|
||||
);
|
||||
cy.dataCy('agencyStepSelect').should('exist');
|
||||
cy.selectOption('[data-testid="agencyStepSelect"]', 'Other agency');
|
||||
cy.selectOption('[data-cy="agencyStepSelect"]', 'Other agency');
|
||||
checkoutNextStep();
|
||||
checkoutNextStep();
|
||||
cy.url().should('contain', '/#/ecomerce/catalog');
|
||||
|
@ -69,7 +69,7 @@ Cypress.Commands.add('createOrderPickup', () => {
|
|||
'¿En qué almacén quieres recoger tu pedido?'
|
||||
);
|
||||
cy.dataCy('pickupStepSelect').should('exist');
|
||||
cy.selectOption('[data-testid="pickupStepSelect"]', 'Teleportation device');
|
||||
cy.selectOption('[data-cy="pickupStepSelect"]', 'Teleportation device');
|
||||
checkoutNextStep();
|
||||
checkoutNextStep();
|
||||
cy.url().should('contain', '/#/ecomerce/catalog');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Cypress.Commands.add('changeUserNickname', (oldNickname, newNickname) => {
|
||||
cy.dataCy('configViewNickname').find('input').should('exist');
|
||||
|
||||
cy.getValue('input[data-testid="configViewNickname"]').should(
|
||||
cy.getValue('input[data-cy="configViewNickname"]').should(
|
||||
'equal',
|
||||
oldNickname
|
||||
);
|
||||
|
|
|
@ -11,9 +11,9 @@ describe('Changes user nickname', () => {
|
|||
|
||||
it('changes site lang when changing user lang', () => {
|
||||
cy.dataCy('configViewLang').should('exist');
|
||||
cy.selectOption('[data-testid="configViewLang"]', 'Español');
|
||||
cy.selectOption('[data-cy="configViewLang"]', 'Español');
|
||||
cy.dataCy('headerTitle').should('contain', 'Configuración');
|
||||
cy.selectOption('[data-testid="configViewLang"]', 'English');
|
||||
cy.selectOption('[data-cy="configViewLang"]', 'English');
|
||||
cy.dataCy('headerTitle').should('contain', 'Configuration');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,8 +23,8 @@ describe('PendingOrders', () => {
|
|||
cy.dataCy('addressFormCity').find('input').type(data.city);
|
||||
cy.dataCy('addressFormPostcode').find('input').click();
|
||||
cy.dataCy('addressFormPostcode').find('input').type(data.postcode);
|
||||
cy.selectOption('[data-testid="addressFormCountry"]', 'España');
|
||||
cy.selectOption('[data-testid="addressFormProvince"]', 'Province one');
|
||||
cy.selectOption('[data-cy="addressFormCountry"]', 'España');
|
||||
cy.selectOption('[data-cy="addressFormProvince"]', 'Province one');
|
||||
};
|
||||
|
||||
const verifyAddressCardData = data => {
|
||||
|
@ -63,7 +63,7 @@ describe('PendingOrders', () => {
|
|||
cy.dataCy('addressCardList')
|
||||
.children()
|
||||
.last()
|
||||
.find('[data-testid="editAddressBtn"]')
|
||||
.find('[data-cy="editAddressBtn"]')
|
||||
.click();
|
||||
// Clear form data
|
||||
cy.get('form input').each(input => {
|
||||
|
|
|
@ -40,12 +40,9 @@ Cypress.Commands.add('logout', user => {
|
|||
Cypress.Commands.add('loginFlow', (user, visitLogin = true) => {
|
||||
if (visitLogin) cy.visit('/#/login');
|
||||
cy.dataCy('loginUserInput').type(user);
|
||||
cy.getValue('[data-testid="loginUserInput"]').should('equal', user);
|
||||
cy.getValue('[data-cy="loginUserInput"]').should('equal', user);
|
||||
cy.dataCy('loginPasswordInput').type('nightmare');
|
||||
cy.getValue('[data-testid="loginPasswordInput"]').should(
|
||||
'equal',
|
||||
'nightmare'
|
||||
);
|
||||
cy.getValue('[data-cy="loginPasswordInput"]').should('equal', 'nightmare');
|
||||
|
||||
cy.get('button[type="submit"]').click();
|
||||
cy.url().should('contain', '/#/cms/home');
|
||||
|
@ -54,7 +51,7 @@ Cypress.Commands.add('loginFlow', (user, visitLogin = true) => {
|
|||
Cypress.Commands.add('changeLanguage', language => {
|
||||
const languagesOrder = ['en', 'es', 'ca', 'fr', 'pt'];
|
||||
const index = languagesOrder.indexOf(language);
|
||||
cy.waitForElement('[data-testid="switchLanguage"]');
|
||||
cy.waitForElement('[data-cy="switchLanguage"]');
|
||||
cy.dataCy('switchLanguage').click();
|
||||
cy.get('.q-menu .q-item').eq(index).click(); // Selecciona y hace clic en el tercer elemento "index" de la lista
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
describe('Login Tests', () => {
|
||||
const rememberCheckbox = '[data-testid="rememberCheckbox"]';
|
||||
const rememberCheckbox = '[data-cy="rememberCheckbox"]';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/#/login');
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
describe('Login Tests', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/#/login');
|
||||
});
|
||||
|
||||
it('should ssend recover email', () => {
|
||||
cy.dataCy('recoverPasswordViewLink').should('exist');
|
||||
cy.dataCy('recoverPasswordViewLink').click();
|
||||
cy.dataCy('recoverPasswordUserInput').find('input').should('exist');
|
||||
cy.dataCy('recoverPasswordUserInput').find('input').type('developer');
|
||||
cy.dataCy('recoverPasswordSubmitButton').should('exist');
|
||||
cy.dataCy('recoverPasswordSubmitButton').click();
|
||||
cy.checkNotify(
|
||||
'positive',
|
||||
'Te hemos enviado un correo donde podrás recuperar tu contraseña'
|
||||
);
|
||||
});
|
||||
});
|
File diff suppressed because one or more lines are too long
|
@ -36,6 +36,7 @@ requireCommands.keys().forEach(requireCommands);
|
|||
// Common commands
|
||||
Cypress.Commands.add('selectOption', (selector, option) => {
|
||||
cy.waitForElement(selector);
|
||||
cy.wait(400);
|
||||
cy.get(selector).click();
|
||||
cy.get('.q-menu .q-item').contains(option).click();
|
||||
});
|
||||
|
@ -55,7 +56,7 @@ Cypress.Commands.add('waitForElement', (element, timeout = 5000) => {
|
|||
cy.get(element, { timeout }).should('be.visible');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('dataCy', (dataTestId, attr = 'data-testid') => {
|
||||
Cypress.Commands.add('dataCy', (dataTestId, attr = 'data-cy') => {
|
||||
return cy.get(`[${attr}="${dataTestId}"]`);
|
||||
});
|
||||
|
||||
|
@ -80,7 +81,7 @@ Cypress.Commands.add('setSessionStorage', (key, value) => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add('resetDB', () => {
|
||||
cy.exec('npm run resetDatabase');
|
||||
cy.exec('pnpm run db');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('setConfirmDialog', () => {
|
||||
|
|
Loading…
Reference in New Issue