#8193: Added filter in ClientNotes #1609

Open
jon wants to merge 18 commits from 8193-AddFilterInClientNotes into dev
7 changed files with 219 additions and 16 deletions

View File

@ -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(

View File

@ -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;
Review

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

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
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>

View File

@ -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>

View File

@ -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"
/>

View File

@ -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

View File

@ -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>

View File

@ -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,
);
});
});
});