feat: add useStateQuery to FetchData and ArrayData
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-dev There was a failure building this commit
Details
This commit is contained in:
parent
856d551503
commit
59f812e6d7
|
@ -1,6 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { useStateQuery } from 'src/composables/useStateQuery';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
autoLoad: {
|
autoLoad: {
|
||||||
|
@ -32,7 +33,7 @@ const $props = defineProps({
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const stateQuery = useStateQuery();
|
||||||
const emit = defineEmits(['onFetch']);
|
const emit = defineEmits(['onFetch']);
|
||||||
defineExpose({ fetch });
|
defineExpose({ fetch });
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ onMounted(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function fetch(fetchFilter = {}) {
|
async function fetch(fetchFilter = {}) {
|
||||||
|
const hash = stateQuery.add();
|
||||||
try {
|
try {
|
||||||
const filter = { ...fetchFilter, ...$props.filter }; // eslint-disable-line vue/no-dupe-keys
|
const filter = { ...fetchFilter, ...$props.filter }; // eslint-disable-line vue/no-dupe-keys
|
||||||
if ($props.where && !fetchFilter.where) filter.where = $props.where;
|
if ($props.where && !fetchFilter.where) filter.where = $props.where;
|
||||||
|
@ -55,8 +57,8 @@ async function fetch(fetchFilter = {}) {
|
||||||
|
|
||||||
emit('onFetch', data);
|
emit('onFetch', data);
|
||||||
return data;
|
return data;
|
||||||
} catch (e) {
|
} finally {
|
||||||
//
|
stateQuery.remove(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { onMounted, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
|
import { useStateQuery } from 'src/composables/useStateQuery';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import PinnedModules from './PinnedModules.vue';
|
import PinnedModules from './PinnedModules.vue';
|
||||||
import UserPanel from 'components/UserPanel.vue';
|
import UserPanel from 'components/UserPanel.vue';
|
||||||
|
@ -12,6 +13,7 @@ import VnAvatar from './ui/VnAvatar.vue';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const stateQuery = useStateQuery();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const appName = 'Lilium';
|
const appName = 'Lilium';
|
||||||
|
@ -50,6 +52,14 @@ const pinnedModulesRef = ref();
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<VnBreadcrumbs v-if="$q.screen.gt.sm" />
|
<VnBreadcrumbs v-if="$q.screen.gt.sm" />
|
||||||
|
<QSpinner
|
||||||
|
color="primary"
|
||||||
|
class="q-ml-md"
|
||||||
|
:class="{
|
||||||
|
'no-visible': !stateQuery.isLoading().value,
|
||||||
|
}"
|
||||||
|
size="xs"
|
||||||
|
/>
|
||||||
<QSpace />
|
<QSpace />
|
||||||
<div id="searchbar" class="searchbar"></div>
|
<div id="searchbar" class="searchbar"></div>
|
||||||
<QSpace />
|
<QSpace />
|
||||||
|
@ -104,6 +114,9 @@ const pinnedModulesRef = ref();
|
||||||
.q-header {
|
.q-header {
|
||||||
background-color: var(--vn-section-color);
|
background-color: var(--vn-section-color);
|
||||||
}
|
}
|
||||||
|
.no-visible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { useRouter, useRoute } from 'vue-router';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
||||||
import { buildFilter } from 'filters/filterPanel';
|
import { buildFilter } from 'filters/filterPanel';
|
||||||
|
import { useStateQuery } from 'src/composables/useStateQuery';
|
||||||
|
|
||||||
const arrayDataStore = useArrayDataStore();
|
const arrayDataStore = useArrayDataStore();
|
||||||
|
const stateQuery = useStateQuery();
|
||||||
|
|
||||||
export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
if (!key) throw new Error('ArrayData: A key is required to use this composable');
|
||||||
|
@ -99,11 +101,18 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
|
|
||||||
params.filter = JSON.stringify(params.filter);
|
params.filter = JSON.stringify(params.filter);
|
||||||
store.currentFilter = params;
|
store.currentFilter = params;
|
||||||
|
|
||||||
store.isLoading = true;
|
store.isLoading = true;
|
||||||
const response = await axios.get(store.url, {
|
const hash = stateQuery.add();
|
||||||
signal: canceller.signal,
|
let response;
|
||||||
params,
|
try {
|
||||||
});
|
response = await axios.get(store.url, {
|
||||||
|
signal: canceller.signal,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
stateQuery.remove(hash);
|
||||||
|
}
|
||||||
|
|
||||||
const { limit } = filter;
|
const { limit } = filter;
|
||||||
store.hasMoreData = limit && response.data.length >= limit;
|
store.hasMoreData = limit && response.data.length >= limit;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
|
const queries = ref(new Set());
|
||||||
|
|
||||||
|
export function useStateQuery() {
|
||||||
|
function add() {
|
||||||
|
const min = 100000;
|
||||||
|
const max = 999999;
|
||||||
|
const hash = String(Math.floor(Math.random() * (max - min + 1)) + min);
|
||||||
|
queries.value.add(hash);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoading() {
|
||||||
|
return computed(() => queries.value.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(hash) {
|
||||||
|
queries.value.delete(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
add,
|
||||||
|
isLoading,
|
||||||
|
remove,
|
||||||
|
};
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ import ItemListFilter from '../ItemListFilter.vue';
|
||||||
search-data-key="ItemList"
|
search-data-key="ItemList"
|
||||||
:searchbar-props="{
|
:searchbar-props="{
|
||||||
url: 'Items/filter',
|
url: 'Items/filter',
|
||||||
label: 'searchbar.labelr',
|
label: 'searchbar.label',
|
||||||
info: 'searchbar.info',
|
info: 'searchbar.info',
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue