feat: refs #8193 make VnNotes use VnNotesFilter
gitea/salix-front/pipeline/pr-dev This commit is unstable
Details
gitea/salix-front/pipeline/pr-dev This commit is unstable
Details
This commit is contained in:
parent
60fc6bee45
commit
0d0433bec4
|
@ -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">
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue