#8193: Added filter in ClientNotes #1609
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { ref, reactive, useAttrs, computed, onMounted, onUnmounted } from 'vue';
|
||||
import { onBeforeRouteLeave, useRoute } from 'vue-router';
|
||||
import { onBeforeRouteLeave } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
|
@ -17,6 +17,7 @@ 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']);
|
||||
|
||||
|
@ -25,9 +26,6 @@ const $attrs = computed(() => {
|
|||
const { required, deletable, ...rest } = originalAttrs;
|
||||
return rest;
|
||||
});
|
||||
const stateStore = useStateStore();
|
||||
const route = useRoute();
|
||||
|
||||
const $props = defineProps({
|
||||
url: { type: String, default: null },
|
||||
saveUrl: { type: String, default: null },
|
||||
|
@ -38,7 +36,7 @@ const $props = defineProps({
|
|||
selectType: { type: Boolean, default: false },
|
||||
justInput: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
const newNote = reactive({ text: null, observationTypeFk: null });
|
||||
|
@ -50,10 +48,6 @@ const defaultObservationType = computed(
|
|||
);
|
||||
|
||||
let originalText;
|
||||
const observationTypeFk = ref([]);
|
||||
const selectedFilters = ref({});
|
||||
const userSelect = ref();
|
||||
const filteredWorkers = ref([]);
|
||||
|
||||
function handleClick(e) {
|
||||
if (e.shiftKey && e.key === 'Enter') return;
|
||||
|
@ -137,58 +131,16 @@ const handleObservationTypes = (data) => {
|
|||
}
|
||||
};
|
||||
|
||||
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;
|
||||
});
|
||||
};
|
||||
|
||||
function selectFilter(type) {
|
||||
let filter = {};
|
||||
let reload = true;
|
||||
|
||||
if (type === 'userSelect') {
|
||||
selectedFilters.value.workerFk =
|
||||
userSelect.value !== null ? userSelect.value : undefined;
|
||||
function exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'observationTypeFk':
|
||||
case 'workerFk':
|
||||
return { [param]: value };
|
||||
}
|
||||
if (type === 'observationTypeFk') {
|
||||
selectedFilters.value.observationTypeFk =
|
||||
observationTypeFk.value !== null ? observationTypeFk.value : undefined;
|
||||
}
|
||||
|
||||
const hasValidFilter = Object.values(selectedFilters.value).some(
|
||||
(value) => value !== undefined,
|
||||
);
|
||||
|
||||
if (hasValidFilter) {
|
||||
Object.keys(selectedFilters.value).forEach((key) => {
|
||||
if (selectedFilters.value[key]) filter[key] = selectedFilters.value[key];
|
||||
});
|
||||
}
|
||||
if (reload) applyFilter(filter);
|
||||
}
|
||||
|
||||
async function applyFilter(selectFilter) {
|
||||
const filter = {
|
||||
where: {
|
||||
clientFk: route.params.id,
|
||||
},
|
||||
};
|
||||
if (Object.keys(selectFilter).length) {
|
||||
filter.where.and = [];
|
||||
filter.where.and.push(selectFilter);
|
||||
}
|
||||
vnPaginateRef.value.fetch({ filter });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
stateStore.rightDrawer = true;
|
||||
stateStore.rightDrawerChangeValue(true);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
stateStore.rightDrawer = false;
|
||||
|
@ -209,60 +161,9 @@ onUnmounted(() => {
|
|||
@on-fetch="fetchData"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
url="ClientObservations"
|
||||
:filter="{ fields: ['id', 'workerFk'] }"
|
||||
:where="{ clientFk: route.params.id }"
|
||||
auto-load
|
||||
@on-fetch="setWorkerObservations"
|
||||
/>
|
||||
<RightMenu v-if="route.path.includes('customer')">
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
<QList dense>
|
||||
<QSeparator />
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('Observation type')"
|
||||
url="ObservationTypes"
|
||||
v-model="observationTypeFk"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
@update:model-value="selectFilter('observationTypeFk')"
|
||||
data-cy="VnNotes-observation-type-filter"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('globals.user')"
|
||||
v-model="userSelect"
|
||||
option-label="workerFk"
|
||||
option-value="workerFk"
|
||||
:options="filteredWorkers"
|
||||
@update:model-value="selectFilter('userSelect')"
|
||||
hide-selected
|
||||
>
|
||||
<template #option="{ opt, itemProps }">
|
||||
<QItem v-bind="itemProps">
|
||||
<QItemSection class="col-3 items-center">
|
||||
<VnAvatar :worker-id="opt.workerFk" />
|
||||
</QItemSection>
|
||||
<QItemSection class="col-9 justify-center">
|
||||
<QItemLabel>
|
||||
{{ opt.worker?.user?.name }}
|
||||
</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ `#${opt.workerFk}` }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</QList>
|
||||
<VnNotesFilter :data-key="$props.url" :url="$props.url" />
|
||||
</template>
|
||||
</RightMenu>
|
||||
<QCard
|
||||
|
@ -292,7 +193,6 @@ onUnmounted(() => {
|
|||
:label="$props.justInput && newNote.text ? '' : t('Add note here...')"
|
||||
filled
|
||||
autogrow
|
||||
autofocus
|
||||
@keyup.enter.stop="handleClick"
|
||||
jon marked this conversation as resolved
Outdated
|
||||
:required="'required' in originalAttrs"
|
||||
clearable
|
||||
|
@ -326,8 +226,9 @@ onUnmounted(() => {
|
|||
ref="vnPaginateRef"
|
||||
class="show"
|
||||
v-bind="$attrs"
|
||||
:search-url="false"
|
||||
:search-url="$props.url"
|
||||
@on-fetch="newNote.text = ''"
|
||||
:exprBuilder
|
||||
>
|
||||
<template #body="{ rows }">
|
||||
<TransitionGroup name="list" tag="div" class="column items-center full-width">
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
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';
|
||||
|
||||
const emit = defineEmits(['onFetch']);
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const $props = defineProps({
|
||||
dataKey: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
const filteredWorkers = ref([]);
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'observationTypeFk',
|
||||
},
|
||||
{
|
||||
name: 'workerFk',
|
||||
},
|
||||
]);
|
||||
|
||||
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
|
||||
alexm
commented
Esto no deberia estar en un componente que se usa en mas secciones aparte de clientes. 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
|
||||
url="ClientObservations"
|
||||
:filter="{ fields: ['id', 'workerFk'] }"
|
||||
:where="{ clientFk: route.params.id }"
|
||||
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"
|
||||
@update:modelValue="() => searchFn()"
|
||||
hide-selected
|
||||
dense
|
||||
filled
|
||||
>
|
||||
<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.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>
|
Loading…
Reference in New Issue
Esto no deberia estar en un componente generico, VnNotes se usa en claim, worker, etc