Data store refactor
gitea/salix-front/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2023-01-05 14:57:47 +01:00
parent 70ebb0f286
commit 2fe05f23d1
8 changed files with 210 additions and 43 deletions

View File

@ -11,6 +11,7 @@ const session = useSession();
const state = useState();
const user = state.getUser();
const token = session.getToken();
const appName = 'Lilium';
onMounted(() => (state.headerMounted.value = true));
@ -37,7 +38,7 @@ function onToggleDrawer() {
</q-tooltip>
</q-btn>
</router-link>
<q-toolbar-title shrink class="text-weight-bold">Salix</q-toolbar-title>
<q-toolbar-title shrink class="text-weight-bold">{{ appName }}</q-toolbar-title>
<q-space></q-space>
<div id="searchbar"></div>
<q-space></q-space>

View File

@ -1,7 +1,7 @@
<script setup>
import axios from 'axios';
import { onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useArrayData } from 'composables/useArrayData';
const { t } = useI18n();
@ -45,7 +45,7 @@ const $props = defineProps({
});
const emit = defineEmits(['onFetch', 'onPaginate']);
defineExpose({ refresh });
// defineExpose({ refresh });
onMounted(() => {
if ($props.autoLoad) paginate();
@ -65,10 +65,44 @@ const pagination = ref({
rowsPerPage: $props.rowsPerPage,
page: 1,
});
const rows = ref(null);
async function fetch() {
const { page, rowsPerPage, sortBy } = pagination.value;
const arrayData = useArrayData('customers', {
url: $props.url,
limit: $props.rowsPerPage,
});
const rows = arrayData.data;
// async function fetch() {
// const { page, rowsPerPage, sortBy } = pagination.value;
// if (!$props.url) return;
// const filter = {
// limit: rowsPerPage,
// skip: rowsPerPage * (page - 1),
// };
// Object.assign(filter, $props.filter);
// if ($props.where) filter.where = $props.where;
// if ($props.sortBy) filter.order = $props.sortBy;
// if ($props.limit) filter.limit = $props.limit;
// if (sortBy) filter.order = sortBy;
// arrayData.apply()
// const { data } = await axios.get($props.url, {
// params: { filter },
// });
// isLoading.value = false;
// return data;
// }
async function paginate() {
const { page, rowsPerPage, sortBy, descending } = pagination.value;
if (!$props.url) return;
@ -85,19 +119,7 @@ async function fetch() {
if (sortBy) filter.order = sortBy;
const { data } = await axios.get($props.url, {
params: { filter },
});
isLoading.value = false;
return data;
}
async function paginate() {
const { page, rowsPerPage, sortBy, descending } = pagination.value;
const data = await fetch();
const data = await arrayData.apply(filter);
if (!data) {
isLoading.value = false;
@ -105,11 +127,12 @@ async function paginate() {
}
hasMoreData.value = data.length === rowsPerPage;
console.log(hasMoreData.value);
if (!rows.value) rows.value = [];
for (const row of data) rows.value.push(row);
// if (!rows.value) rows.value = [];
// for (const row of data) rows.value.push(row);
pagination.value.rowsNumber = rows.value.length;
pagination.value.rowsNumber = rows.length;
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
pagination.value.sortBy = sortBy;
@ -121,29 +144,29 @@ async function paginate() {
emit('onPaginate', data);
}
async function refresh() {
const { rowsPerPage } = pagination.value;
// async function refresh() {
// const { rowsPerPage } = pagination.value;
const data = await fetch();
// const data = await fetch();
if (!data) {
isLoading.value = false;
return;
}
// if (!data) {
// isLoading.value = false;
// return;
// }
hasMoreData.value = data.length === rowsPerPage;
// hasMoreData.value = data.length === rowsPerPage;
if (!rows.value) rows.value = [];
rows.value = data;
// if (!rows.value) rows.value = [];
// rows.value = data;
isLoading.value = false;
// isLoading.value = false;
emit('onFetch', rows);
}
// emit('onFetch', rows);
// }
async function onLoad(...params) {
const done = params[1];
if (!rows.value || rows.value.length === 0 || !$props.url) return done(false);
if (!rows || rows.length === 0 || !$props.url) return done(false);
pagination.value.page = pagination.value.page + 1;

View File

@ -0,0 +1,56 @@
import axios from 'axios';
import { useArrayDataStore } from 'stores/useArrayDataStore';
const arrayDataStore = useArrayDataStore();
const options = {
limit: 10,
};
export function useArrayData(key, userOptions) {
if (!key) throw new Error('ArrayData: A key is required to use this composable');
arrayDataStore.set(key, []);
const data = arrayDataStore.get(key);
if (typeof userOptions === 'object') {
Object.assign(options, userOptions);
}
async function fetch() {
if (!options.url) return;
const filter = {
limit: options.limit,
};
const requestOptions = { params: { filter } };
const response = await axios.get(options.url, requestOptions);
for (const row of response.data) data.push(row);
return response.data;
}
async function apply(filter) {
if (!options.url) return;
const requestOptions = { params: { filter } };
const response = await axios.get(options.url, requestOptions);
for (const row of response.data) data.push(row);
return response.data;
}
async function refresh() {
// TODO
}
return {
fetch,
apply,
refresh,
data,
};
}

View File

@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { toCurrency, toPercentage, toDate } from 'src/filters';
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
import { useArrayDataStore } from 'stores/useArrayDataStore';
onMounted(() => fetch());
@ -59,6 +60,10 @@ const creditWarning = computed(() => {
return tooMuchInsurance || noCreditInsurance ? 'negative' : '';
});
const arrayDataStore = useArrayDataStore();
const d = arrayDataStore.get('test');
console.log(d);
</script>
<template>

View File

@ -1,13 +1,16 @@
<script setup>
import { reactive, watch } from 'vue'
import { reactive, watch } from 'vue';
const customer = reactive({
name: '',
});
watch(() => customer.name, () => {
console.log('customer.name changed');
});
watch(
() => customer.name,
() => {
console.log('customer.name changed');
}
);
</script>
<template>
@ -20,7 +23,7 @@ watch(() => customer.name, () => {
label="Your name *"
hint="Name and surname"
lazy-rules
:rules="[val => val && val.length > 0 || 'Please type something']"
:rules="[(val) => (val && val.length > 0) || 'Please type something']"
/>
<q-input
@ -30,8 +33,8 @@ watch(() => customer.name, () => {
label="Your age *"
lazy-rules
:rules="[
val => val !== null && val !== '' || 'Please type your age',
val => val > 0 && val < 100 || 'Please type a real age'
(val) => (val !== null && val !== '') || 'Please type your age',
(val) => (val > 0 && val < 100) || 'Please type a real age',
]"
/>

View File

@ -5,10 +5,21 @@ import { useQuasar } from 'quasar';
import Paginate from 'src/components/PaginateData.vue';
import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
// import { useArrayData } from 'composables/useArrayData';
const router = useRouter();
const quasar = useQuasar();
const { t } = useI18n();
// const arrayData = useArrayData('customers', {
// url: 'Clients',
// });
// onMounted(async () => {
// await arrayData.fetch();
// console.log(arrayData.data);
// });
function navigate(id) {
router.push({ path: `/customer/${id}` });
}

View File

@ -1,11 +1,60 @@
<script setup>
import { useState } from 'src/composables/useState';
import LeftMenu from 'components/LeftMenu.vue';
// import TeleportSlot from 'src/components/ui/TeleportSlot.vue';
const state = useState();
</script>
<template>
<!-- <teleport-slot to="#searchbar">
<q-select
ref="search"
dark
dense
standout
use-input
hide-selected
color="black"
:stack-label="false"
label="Search or jump to..."
v-model="text"
:options="filteredOptions"
@filter="filter"
style="width: 400px"
>
<template #append>
<img src="https://cdn.quasar.dev/img/layout-gallery/img-github-search-key-slash.svg" />
</template>
<template #no-option>
<q-item>
<q-item-section>
<div class="text-center">
<q-spinner-pie color="grey-5" size="24px" />
</div>
</q-item-section>
</q-item>
</template>
<template #option="scope">
<q-item v-bind="scope.itemProps" class="GL__select-GL__menu-link">
<q-item-section side>
<q-icon name="collections_bookmark" />
</q-item-section>
<q-item-section>
<q-item-label>{{ scope.opt.label }}</q-item-label>
</q-item-section>
<q-item-section side :class="{ 'default-type': !scope.opt.type }">
<q-btn outline dense no-caps text-color="blue-grey-5" size="12px" class="bg-grey-1 q-px-sm">
{{ scope.opt.type || 'Jump to' }}
<q-icon name="subdirectory_arrow_left" size="14px" />
</q-btn>
</q-item-section>
</q-item>
</template>
</q-select>
</teleport-slot> -->
<q-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500">
<q-scroll-area class="fit text-grey-8">
<LeftMenu />

View File

@ -0,0 +1,19 @@
import { ref } from 'vue';
import { defineStore } from 'pinia';
export const useArrayDataStore = defineStore('arrayDataStore', () => {
const store = ref({});
function get(key) {
return store.value[key];
}
function set(key, data) {
store.value[key] = data;
}
return {
get,
set,
};
});