feat: refs #8193 make VnNotes use VnNotesFilter
gitea/salix-front/pipeline/pr-dev This commit is unstable Details

This commit is contained in:
Jon Elias 2025-04-04 12:01:03 +02:00
parent 60fc6bee45
commit 0d0433bec4
2 changed files with 116 additions and 112 deletions

View File

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

View File

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