#8193: Added filter in ClientNotes #1609
|
@ -1,10 +1,11 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { ref, reactive, useAttrs, computed } from 'vue';
|
||||
import { ref, reactive, useAttrs, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { toDateHourMin } from 'src/filters';
|
||||
|
||||
import VnPaginate from 'components/ui/VnPaginate.vue';
|
||||
|
@ -15,6 +16,8 @@ import VnRow from 'components/ui/VnRow.vue';
|
|||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import VnInput from 'components/common/VnInput.vue';
|
||||
import RightMenu from '../common/RightMenu.vue';
|
||||
import VnNotesFilter from './VnNotesFilter.vue';
|
||||
|
||||
const emit = defineEmits(['onFetch']);
|
||||
|
||||
|
@ -23,9 +26,9 @@ const $attrs = computed(() => {
|
|||
const { required, deletable, ...rest } = originalAttrs;
|
||||
return rest;
|
||||
});
|
||||
|
||||
const $props = defineProps({
|
||||
url: { type: String, default: null },
|
||||
dataKey: { type: String, default: null },
|
||||
saveUrl: { type: String, default: null },
|
||||
userFilter: { type: Object, default: () => {} },
|
||||
filter: { type: Object, default: () => {} },
|
||||
|
@ -33,16 +36,19 @@ const $props = defineProps({
|
|||
addNote: { type: Boolean, default: false },
|
||||
selectType: { type: Boolean, default: false },
|
||||
justInput: { type: Boolean, default: false },
|
||||
filterColumns: { type: Array, default: () => [] },
|
||||
});
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
const newNote = reactive({ text: null, observationTypeFk: null });
|
||||
const observationTypes = ref([]);
|
||||
const vnPaginateRef = ref();
|
||||
|
||||
const defaultObservationType = computed(() =>
|
||||
observationTypes.value.find(ot => ot.code === 'salesPerson')?.id
|
||||
const state = useState();
|
||||
const user = state.getUser();
|
||||
const userRole = ref();
|
||||
const defaultObservationType = computed(
|
||||
() => observationTypes.value.find((ot) => ot.code === 'salesPerson')?.id,
|
||||
);
|
||||
|
||||
let originalText;
|
||||
|
@ -122,15 +128,39 @@ function fetchData([data]) {
|
|||
emit('onFetch', data);
|
||||
}
|
||||
|
||||
const handleObservationTypes = (data) => {
|
||||
const handleObservationTypes = async (data) => {
|
||||
observationTypes.value = data;
|
||||
if(defaultObservationType.value) {
|
||||
newNote.observationTypeFk = defaultObservationType.value;
|
||||
}
|
||||
const { data: res } = await axios.get(`VnRoles/${userRole?.value[0]?.roleFk}`);
|
||||
const hasObservationType = observationTypes.value.find((ot) => ot.code === res.name);
|
||||
newNote.observationTypeFk = hasObservationType
|
||||
? hasObservationType.code
|
||||
: defaultObservationType.value;
|
||||
};
|
||||
|
||||
function exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'observationTypeFk':
|
||||
case 'workerFk':
|
||||
return { [param]: value };
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
stateStore.rightDrawerChangeValue(true);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
stateStore.rightDrawer = false;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
v-if="selectType"
|
||||
url="VnUsers/preview"
|
||||
:filter="{ fields: ['id', 'roleFk', 'username'] }"
|
||||
:where="{ id: user.id }"
|
||||
auto-load
|
||||
@on-fetch="(data) => (userRole = data)"
|
||||
/>
|
||||
<FetchData
|
||||
v-if="selectType"
|
||||
url="ObservationTypes"
|
||||
|
@ -145,6 +175,16 @@ const handleObservationTypes = (data) => {
|
|||
@on-fetch="fetchData"
|
||||
auto-load
|
||||
/>
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<VnNotesFilter
|
||||
:data-key="$props.dataKey"
|
||||
:url="$props.url"
|
||||
:columns="$props.filterColumns"
|
||||
:body="$props.body"
|
||||
/>
|
||||
</template>
|
||||
</RightMenu>
|
||||
<QCard
|
||||
class="q-pa-xs q-mb-lg full-width"
|
||||
:class="{ 'just-input': $props.justInput }"
|
||||
|
@ -164,6 +204,7 @@ const handleObservationTypes = (data) => {
|
|||
style="flex: 0.15"
|
||||
:required="'required' in originalAttrs"
|
||||
@keyup.enter.stop="insert"
|
||||
data-cy="VnNotes-observation-type"
|
||||
/>
|
||||
<VnInput
|
||||
v-model.trim="newNote.text"
|
||||
|
@ -171,10 +212,10 @@ const handleObservationTypes = (data) => {
|
|||
:label="$props.justInput && newNote.text ? '' : t('Add note here...')"
|
||||
filled
|
||||
autogrow
|
||||
autofocus
|
||||
@keyup.enter.stop="handleClick"
|
||||
:required="'required' in originalAttrs"
|
||||
clearable
|
||||
data-cy="VnNotes-text-input"
|
||||
>
|
||||
<template #append>
|
||||
<QBtn
|
||||
|
@ -204,10 +245,9 @@ const handleObservationTypes = (data) => {
|
|||
ref="vnPaginateRef"
|
||||
class="show"
|
||||
v-bind="$attrs"
|
||||
:search-url="false"
|
||||
@on-fetch="
|
||||
newNote.text = '';
|
||||
"
|
||||
:search-url="$props.url"
|
||||
@on-fetch="newNote.text = ''"
|
||||
:exprBuilder
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<TransitionGroup name="list" tag="div" class="column items-center full-width">
|
||||
|
@ -234,6 +274,7 @@ const handleObservationTypes = (data) => {
|
|||
outline
|
||||
color="grey"
|
||||
v-if="selectType && note.observationTypeFk"
|
||||
data-cy="VnNotes-observation-type-badge"
|
||||
>
|
||||
{{
|
||||
observationTypes.find(
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnAvatar from 'components/ui/VnAvatar.vue';
|
||||
import VnSelect from 'components/common/VnSelect.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
|
||||
import VnTableFilter from '../VnTable/VnTableFilter.vue';
|
||||
// import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
const emit = defineEmits(['onFetch']);
|
||||
const { t } = useI18n();
|
||||
const $props = defineProps({
|
||||
dataKey: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
body: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
// const arrayData = useArrayData($props.url);
|
||||
// const store = arrayData.store;
|
||||
// console.log('store: ', store);
|
||||
// const users = store.data;
|
||||
// console.log('users: ', users);
|
||||
// const workers = $props.users.map((user) => user.worker);
|
||||
// console.log('workers: ', workers);
|
||||
|
||||
const where = { [Object.keys($props.body)[0]]: $props.body[Object.keys($props.body)[0]] };
|
||||
const columns = $props.columns.map((col) => ({ name: col }));
|
||||
const filteredWorkers = ref([]);
|
||||
const setWorkerObservations = (data) => {
|
||||
const seen = new Set();
|
||||
filteredWorkers.value = data;
|
||||
|
||||
filteredWorkers.value = data.filter((worker) => {
|
||||
if (!seen.has(worker.workerFk)) {
|
||||
seen.add(worker.workerFk);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
:url="$props.url"
|
||||
:filter="{ fields: ['id', 'workerFk'] }"
|
||||
:where="where"
|
||||
auto-load
|
||||
@on-fetch="setWorkerObservations"
|
||||
/>
|
||||
<VnTableFilter
|
||||
v-if="dataKey"
|
||||
:data-key
|
||||
:columns="columns"
|
||||
:redirect="false"
|
||||
:exprBuilder
|
||||
:search-url="$props.dataKey"
|
||||
:showTagChips="false"
|
||||
>
|
||||
<template #filter-observationTypeFk="{ params, columnName, searchFn }">
|
||||
<VnSelect
|
||||
:label="t('Observation type')"
|
||||
url="ObservationTypes"
|
||||
v-model="params[columnName]"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
@keyup.enter="searchFn"
|
||||
@update:modelValue="() => searchFn()"
|
||||
dense
|
||||
filled
|
||||
data-cy="VnNotes-observation-type-filter"
|
||||
/>
|
||||
</template>
|
||||
<template #filter-workerFk="{ params, columnName, searchFn }">
|
||||
<VnSelect
|
||||
:label="t('globals.user')"
|
||||
v-model="params[columnName]"
|
||||
option-label="workerFk"
|
||||
option-value="workerFk"
|
||||
:options="filteredWorkers"
|
||||
@keyup.enter="searchFn"
|
||||
@update:modelValue="() => searchFn()"
|
||||
hide-selected
|
||||
dense
|
||||
filled
|
||||
data-cy="VnNotes-user-filter"
|
||||
>
|
||||
<template #option="{ opt, itemProps }">
|
||||
<QItem v-bind="itemProps" class="q-pa-xs row items-center">
|
||||
<QItemSection class="col-3 items-center">
|
||||
<VnAvatar :worker-id="opt.worker.id" />
|
||||
</QItemSection>
|
||||
<QItemSection class="col-9 justify-center">
|
||||
<span>{{ opt.worker?.user?.name }}</span>
|
||||
<span class="text-grey">
|
||||
{{ `#${opt.worker?.user?.id}` }}
|
||||
</span>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</template>
|
||||
</VnTableFilter>
|
||||
</template>
|
|
@ -38,11 +38,13 @@ const body = {
|
|||
<template>
|
||||
<VnNotes
|
||||
url="claimObservations"
|
||||
data-key="claimObservations"
|
||||
:add-note="$props.addNote"
|
||||
:user-filter="claimFilter"
|
||||
:filter="{ where: { claimFk: claimId } }"
|
||||
:body="body"
|
||||
v-bind="$attrs"
|
||||
:filter-columns="['workerFk']"
|
||||
style="overflow-y: auto"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -4,11 +4,13 @@ import VnNotes from 'src/components/ui/VnNotes.vue';
|
|||
<template>
|
||||
<VnNotes
|
||||
url="clientObservations"
|
||||
:data-key="'clientObservations'"
|
||||
:add-note="true"
|
||||
:filter="{ where: { clientFk: $route.params.id } }"
|
||||
:body="{ clientFk: $route.params.id }"
|
||||
style="overflow-y: auto"
|
||||
:select-type="true"
|
||||
:filter-columns="['workerFk', 'observationTypeFk']"
|
||||
required
|
||||
order="created DESC"
|
||||
/>
|
||||
|
|
|
@ -25,9 +25,11 @@ const body = {
|
|||
<template>
|
||||
<VnNotes
|
||||
url="vehicleObservations"
|
||||
data-key="vehicleObservations"
|
||||
:add-note="true"
|
||||
:filter="noteFilter"
|
||||
:body="body"
|
||||
:filter-columns="['workerFk']"
|
||||
style="overflow-y: auto"
|
||||
required
|
||||
deletable
|
||||
|
|
|
@ -29,8 +29,10 @@ const body = { workerFk: route.params.id };
|
|||
<VnNotes
|
||||
:add-note="true"
|
||||
url="WorkerObservations"
|
||||
data-key="WorkerObservations"
|
||||
:user-filter="userFilter"
|
||||
:filter="{ where: { workerFk: $route.params.id } }"
|
||||
:filter-columns="['workerFk']"
|
||||
:body="body"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/// <reference types="cypress" />
|
||||
describe('VnNotes', () => {
|
||||
const obervationType = 'Packager';
|
||||
const user = 'developer';
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
cy.visit('#/customer/1102/notes');
|
||||
});
|
||||
|
||||
it('should add and filter notes by observation type', () => {
|
||||
cy.selectOption("[data-cy='VnNotes-observation-type']", obervationType);
|
||||
cy.dataCy('VnNotes-text-input').type('Test note {enter}');
|
||||
|
||||
cy.selectOption("[data-cy='VnNotes-observation-type-filter']", obervationType);
|
||||
cy.get('.column.full-width')
|
||||
.children()
|
||||
.each(($el) => {
|
||||
cy.dataCy('VnNotes-observation-type-badge').should(
|
||||
'include.text',
|
||||
obervationType,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should filter notes by user', () => {
|
||||
cy.selectOption("[data-cy='VnNotes-user-filter']", user);
|
||||
cy.get('.column.full-width')
|
||||
.children()
|
||||
.each(($el) => {
|
||||
cy.dataCy('VnNotes-observation-type-badge').should(
|
||||
'include.text',
|
||||
obervationType,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Esto no deberia estar en un componente que se usa en mas secciones aparte de clientes.
Para lo que tratas de hacer puedes usar obtener de alguna manera los datos del arrayData y sacarte los users/workers