feat: refs #7957 open in new tab #1086
|
@ -141,13 +141,16 @@ const handleInsertMode = (e) => {
|
|||
<QIcon
|
||||
name="close"
|
||||
size="xs"
|
||||
v-if="
|
||||
:style="{
|
||||
|
||||
visibility:
|
||||
hover &&
|
||||
value &&
|
||||
!$attrs.disabled &&
|
||||
!$attrs.readonly &&
|
||||
$props.clearable
|
||||
"
|
||||
? 'visible'
|
||||
: 'hidden',
|
||||
}"
|
||||
@click="
|
||||
() => {
|
||||
value = null;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { onMounted, ref, computed, watch } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useArrayData } from 'composables/useArrayData';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStateStore } from 'src/stores/useStateStore';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const state = useStateStore();
|
||||
const route = useRoute();
|
||||
|
||||
const props = defineProps({
|
||||
dataKey: {
|
||||
|
@ -83,6 +85,17 @@ if (props.redirect)
|
|||
};
|
||||
let arrayData = useArrayData(props.dataKey, arrayDataProps);
|
||||
let store = arrayData.store;
|
||||
const to = computed(() => {
|
||||
const url = { path: route.path, query: { ...(route.query ?? {}) } };
|
||||
jorgep marked this conversation as resolved
Outdated
alexm
commented
Has mirado si store.currentFilter te valia? Ahi en teoria estan los params sin tratar Has mirado si store.currentFilter te valia? Ahi en teoria estan los params sin tratar
|
||||
const searchUrl = arrayData.store.searchUrl;
|
||||
jorgep
commented
Por defecto vn-input pone null y esto es un parámetro valido de búsqueda, Para que no se añada hay declararlo como undefined. Por defecto vn-input pone null y esto es un parámetro valido de búsqueda, Para que no se añada hay declararlo como undefined.
|
||||
const currentFilter = {
|
||||
...arrayData.store.currentFilter,
|
||||
search: searchText.value || undefined,
|
||||
};
|
||||
|
||||
if (searchUrl) url.query[searchUrl] = JSON.stringify(currentFilter);
|
||||
return url;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.dataKey,
|
||||
|
@ -132,23 +145,32 @@ async function search() {
|
|||
<template>
|
||||
<Teleport to="#searchbar" v-if="state.isHeaderMounted()">
|
||||
<QForm @submit="search" id="searchbarForm">
|
||||
<VnInput
|
||||
jorgep
commented
No reconcee ctrl + click o shift + click en un link. No sé porque, con un QInput nativo tampoco funciona. No reconcee ctrl + click o shift + click en un link. No sé porque, con un QInput nativo tampoco funciona.
|
||||
id="searchbar"
|
||||
v-model.trim="searchText"
|
||||
:placeholder="t(props.label)"
|
||||
dense
|
||||
standout
|
||||
autofocus
|
||||
data-cy="vnSearchBar"
|
||||
<RouterLink
|
||||
:to="to"
|
||||
@click="
|
||||
!$event.shiftKey && !$event.ctrlKey && search();
|
||||
$refs.input.focus();
|
||||
"
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon
|
||||
v-if="!quasar.platform.is.mobile"
|
||||
class="cursor-pointer"
|
||||
name="search"
|
||||
@click="search"
|
||||
/>
|
||||
</template>
|
||||
size="sm"
|
||||
>
|
||||
<QTooltip>{{ t('link') }}</QTooltip>
|
||||
</QIcon>
|
||||
</RouterLink>
|
||||
<VnInput
|
||||
id="searchbar"
|
||||
ref="input"
|
||||
v-model.trim="searchText"
|
||||
:placeholder="t(props.label)"
|
||||
dense
|
||||
autofocus
|
||||
data-cy="vn-searchbar"
|
||||
borderless
|
||||
>
|
||||
<template #append>
|
||||
<QIcon
|
||||
v-if="props.info && $q.screen.gt.xs"
|
||||
|
@ -173,20 +195,52 @@ async function search() {
|
|||
.q-field {
|
||||
transition: width 0.36s;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
:deep(.q-field__native) {
|
||||
padding-top: 10px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
:deep(.q-field--dark .q-field__native:focus) {
|
||||
color: black;
|
||||
}
|
||||
|
||||
:deep(.q-field--focused) {
|
||||
.q-icon {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
jorgep
commented
Antes cogia los colores de la clase &--standout, si no, no tiene color. Antes cogia los colores de la clase &--standout, si no, no tiene color.
|
||||
|
||||
.cursor-info {
|
||||
cursor: help;
|
||||
}
|
||||
#searchbar {
|
||||
.q-field--standout.q-field--highlighted .q-field__control {
|
||||
|
||||
.q-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
padding: 0 5px;
|
||||
background-color: var(--vn-search-color);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--vn-search-color-hover);
|
||||
}
|
||||
&:focus-within {
|
||||
background-color: white;
|
||||
color: black;
|
||||
.q-field__native,
|
||||
|
||||
.q-icon {
|
||||
color: black !important;
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.q-icon {
|
||||
color: var(--vn-label-color);
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
en:
|
||||
link: click to search, ctrl + click to open in a new tab, shift + click to open in a new window
|
||||
es:
|
||||
link: clic para buscar, ctrl + clic para abrir en una nueva pestaña, shift + clic para abrir en una nueva ventana
|
||||
</i18n>
|
||||
|
|
|
@ -76,26 +76,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
|
||||
cancelRequest();
|
||||
canceller = new AbortController();
|
||||
|
||||
const filter = {
|
||||
limit: store.limit,
|
||||
};
|
||||
let userParams = { ...store.userParams };
|
||||
|
||||
Object.assign(filter, store.userFilter);
|
||||
|
||||
let where;
|
||||
if (filter?.where || store.filter?.where)
|
||||
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
||||
Object.assign(filter, store.filter);
|
||||
filter.where = where;
|
||||
const params = { filter };
|
||||
|
||||
Object.assign(params, userParams);
|
||||
if (params.filter) params.filter.skip = store.skip;
|
||||
if (store?.order && typeof store?.order == 'string') store.order = [store.order];
|
||||
if (store.order?.length) params.filter.order = [...store.order];
|
||||
else delete params.filter.order;
|
||||
const { params, limit } = getCurrentFilter();
|
||||
|
||||
store.currentFilter = JSON.parse(JSON.stringify(params));
|
||||
delete store.currentFilter.filter.include;
|
||||
|
@ -121,7 +102,6 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
params,
|
||||
});
|
||||
|
||||
const { limit } = filter;
|
||||
store.hasMoreData = limit && response.data.length >= limit;
|
||||
|
||||
processData(response.data, { map: !!store.mapKey, append });
|
||||
|
@ -291,6 +271,31 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
router.replace(newUrl);
|
||||
}
|
||||
|
||||
function getCurrentFilter() {
|
||||
const filter = {
|
||||
limit: store.limit,
|
||||
};
|
||||
|
||||
let userParams = { ...store.userParams };
|
||||
|
||||
Object.assign(filter, store.userFilter);
|
||||
|
||||
let where;
|
||||
if (filter?.where || store.filter?.where)
|
||||
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
||||
Object.assign(filter, store.filter);
|
||||
filter.where = where;
|
||||
const params = { filter };
|
||||
|
||||
Object.assign(params, userParams);
|
||||
if (params.filter) params.filter.skip = store.skip;
|
||||
if (store?.order && typeof store?.order == 'string') store.order = [store.order];
|
||||
if (store.order?.length) params.filter.order = [...store.order];
|
||||
else delete params.filter.order;
|
||||
|
||||
return { filter, params, limit: filter.limit };
|
||||
}
|
||||
|
||||
function processData(data, { map = true, append = true }) {
|
||||
if (!append) {
|
||||
store.data = [];
|
||||
|
@ -323,6 +328,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
fetch,
|
||||
applyFilter,
|
||||
addFilter,
|
||||
getCurrentFilter,
|
||||
addFilterWhere,
|
||||
addOrder,
|
||||
deleteOrder,
|
||||
|
|
|
@ -10,6 +10,8 @@ body.body--light {
|
|||
--vn-text-color: black;
|
||||
--vn-label-color: #5f5f5f;
|
||||
--vn-accent-color: #e7e3e3;
|
||||
--vn-search-color: #d4d4d4;
|
||||
--vn-search-color-hover: #cfcfcf;
|
||||
--vn-empty-tag: #acacac;
|
||||
--vn-black-text-color: black;
|
||||
--vn-text-color-contrast: white;
|
||||
|
@ -28,6 +30,8 @@ body.body--dark {
|
|||
--vn-text-color: white;
|
||||
--vn-label-color: #a8a8a8;
|
||||
--vn-accent-color: #424242;
|
||||
--vn-search-color: #4b4b4b;
|
||||
--vn-search-color-hover: #5b5b5b;
|
||||
--vn-empty-tag: #2d2d2d;
|
||||
--vn-black-text-color: black;
|
||||
--vn-text-color-contrast: black;
|
||||
|
|
|
@ -41,7 +41,7 @@ describe('OrderCatalog', () => {
|
|||
}
|
||||
});
|
||||
cy.get(
|
||||
'[data-cy="vnSearchBar"] > .q-field > .q-field__inner > .q-field__control'
|
||||
'[data-cy="vn-searchbar"] > .q-field > .q-field__inner > .q-field__control'
|
||||
).type('{enter}');
|
||||
cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
|
||||
cy.dataCy('catalogFilterValueDialogBtn').last().click();
|
||||
|
|
|
@ -9,9 +9,9 @@ describe('TicketList', () => {
|
|||
});
|
||||
|
||||
const searchResults = (search) => {
|
||||
cy.dataCy('vnSearchBar').find('input').focus();
|
||||
if (search) cy.dataCy('vnSearchBar').find('input').type(search);
|
||||
cy.dataCy('vnSearchBar').find('input').type('{enter}');
|
||||
cy.dataCy('vn-searchbar').find('input').focus();
|
||||
if (search) cy.dataCy('vn-searchbar').find('input').type(search);
|
||||
cy.dataCy('vn-searchbar').find('input').type('{enter}');
|
||||
cy.dataCy('ticketListTable').should('exist');
|
||||
cy.get(firstRow).should('exist');
|
||||
};
|
||||
|
|
|
@ -274,15 +274,11 @@ Cypress.Commands.add('openLeftMenu', (element) => {
|
|||
|
||||
Cypress.Commands.add('clearSearchbar', (element) => {
|
||||
if (element) cy.waitForElement(element);
|
||||
cy.get(
|
||||
'#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input'
|
||||
).clear();
|
||||
cy.get('[data-cy="vn-searchbar"]').clear();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('typeSearchbar', (value) => {
|
||||
cy.get('#searchbar > form > div:nth-child(1) > label > div:nth-child(1) input').type(
|
||||
value
|
||||
);
|
||||
Cypress.Commands.add('writeSearchbar', (value) => {
|
||||
cy.get('[data-cy="vn-searchbar"]').type(value);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('validateContent', (selector, expectedValue) => {
|
||||
|
|
Loading…
Reference in New Issue
Así siempre tiene el mismo ancho