4802- Added searchbar & filter panel #39
|
@ -11,6 +11,7 @@ const session = useSession();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const token = session.getToken();
|
const token = session.getToken();
|
||||||
|
const appName = 'Lilium';
|
||||||
|
|
||||||
onMounted(() => (state.headerMounted.value = true));
|
onMounted(() => (state.headerMounted.value = true));
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ function onToggleDrawer() {
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</router-link>
|
</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>
|
<q-space></q-space>
|
||||||
<div id="searchbar"></div>
|
<div id="searchbar"></div>
|
||||||
<q-space></q-space>
|
<q-space></q-space>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
|
||||||
import { onMounted, ref, watch } from 'vue';
|
import { onMounted, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['onFetch', 'onPaginate']);
|
const emit = defineEmits(['onFetch', 'onPaginate']);
|
||||||
defineExpose({ refresh });
|
// defineExpose({ refresh });
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if ($props.autoLoad) paginate();
|
if ($props.autoLoad) paginate();
|
||||||
|
@ -65,10 +65,44 @@ const pagination = ref({
|
||||||
rowsPerPage: $props.rowsPerPage,
|
rowsPerPage: $props.rowsPerPage,
|
||||||
page: 1,
|
page: 1,
|
||||||
});
|
});
|
||||||
const rows = ref(null);
|
|
||||||
|
|
||||||
async function fetch() {
|
const arrayData = useArrayData('customers', {
|
||||||
const { page, rowsPerPage, sortBy } = pagination.value;
|
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;
|
if (!$props.url) return;
|
||||||
|
|
||||||
|
@ -85,19 +119,7 @@ async function fetch() {
|
||||||
|
|
||||||
if (sortBy) filter.order = sortBy;
|
if (sortBy) filter.order = sortBy;
|
||||||
|
|
||||||
const { data } = await axios.get($props.url, {
|
const data = await arrayData.apply(filter);
|
||||||
params: { filter },
|
|
||||||
});
|
|
||||||
|
|
||||||
isLoading.value = false;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function paginate() {
|
|
||||||
const { page, rowsPerPage, sortBy, descending } = pagination.value;
|
|
||||||
|
|
||||||
const data = await fetch();
|
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
@ -105,11 +127,12 @@ async function paginate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMoreData.value = data.length === rowsPerPage;
|
hasMoreData.value = data.length === rowsPerPage;
|
||||||
|
console.log(hasMoreData.value);
|
||||||
|
|
||||||
if (!rows.value) rows.value = [];
|
// if (!rows.value) rows.value = [];
|
||||||
for (const row of data) rows.value.push(row);
|
// 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.page = page;
|
||||||
pagination.value.rowsPerPage = rowsPerPage;
|
pagination.value.rowsPerPage = rowsPerPage;
|
||||||
pagination.value.sortBy = sortBy;
|
pagination.value.sortBy = sortBy;
|
||||||
|
@ -121,29 +144,29 @@ async function paginate() {
|
||||||
emit('onPaginate', data);
|
emit('onPaginate', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refresh() {
|
// async function refresh() {
|
||||||
const { rowsPerPage } = pagination.value;
|
// const { rowsPerPage } = pagination.value;
|
||||||
|
|
||||||
const data = await fetch();
|
// const data = await fetch();
|
||||||
|
|
||||||
if (!data) {
|
// if (!data) {
|
||||||
isLoading.value = false;
|
// isLoading.value = false;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
hasMoreData.value = data.length === rowsPerPage;
|
// hasMoreData.value = data.length === rowsPerPage;
|
||||||
|
|
||||||
if (!rows.value) rows.value = [];
|
// if (!rows.value) rows.value = [];
|
||||||
rows.value = data;
|
// rows.value = data;
|
||||||
|
|
||||||
isLoading.value = false;
|
// isLoading.value = false;
|
||||||
|
|
||||||
emit('onFetch', rows);
|
// emit('onFetch', rows);
|
||||||
}
|
// }
|
||||||
|
|
||||||
async function onLoad(...params) {
|
async function onLoad(...params) {
|
||||||
const done = params[1];
|
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;
|
pagination.value.page = pagination.value.page + 1;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { toCurrency, toPercentage, toDate } from 'src/filters';
|
import { toCurrency, toPercentage, toDate } from 'src/filters';
|
||||||
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
|
import SkeletonSummary from 'components/ui/SkeletonSummary.vue';
|
||||||
|
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
||||||
|
|
||||||
onMounted(() => fetch());
|
onMounted(() => fetch());
|
||||||
|
|
||||||
|
@ -59,6 +60,10 @@ const creditWarning = computed(() => {
|
||||||
|
|
||||||
return tooMuchInsurance || noCreditInsurance ? 'negative' : '';
|
return tooMuchInsurance || noCreditInsurance ? 'negative' : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const arrayDataStore = useArrayDataStore();
|
||||||
|
const d = arrayDataStore.get('test');
|
||||||
|
console.log(d);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, watch } from 'vue'
|
import { reactive, watch } from 'vue';
|
||||||
|
|
||||||
const customer = reactive({
|
const customer = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => customer.name, () => {
|
watch(
|
||||||
console.log('customer.name changed');
|
() => customer.name,
|
||||||
});
|
() => {
|
||||||
|
console.log('customer.name changed');
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -20,7 +23,7 @@ watch(() => customer.name, () => {
|
||||||
label="Your name *"
|
label="Your name *"
|
||||||
hint="Name and surname"
|
hint="Name and surname"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'Please type something']"
|
:rules="[(val) => (val && val.length > 0) || 'Please type something']"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
|
@ -30,8 +33,8 @@ watch(() => customer.name, () => {
|
||||||
label="Your age *"
|
label="Your age *"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
:rules="[
|
:rules="[
|
||||||
val => val !== null && val !== '' || 'Please type your age',
|
(val) => (val !== null && val !== '') || 'Please type your age',
|
||||||
val => val > 0 && val < 100 || 'Please type a real age'
|
(val) => (val > 0 && val < 100) || 'Please type a real age',
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,21 @@ import { useQuasar } from 'quasar';
|
||||||
import Paginate from 'src/components/PaginateData.vue';
|
import Paginate from 'src/components/PaginateData.vue';
|
||||||
import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
|
import CustomerSummaryDialog from './Card/CustomerSummaryDialog.vue';
|
||||||
|
|
||||||
|
// import { useArrayData } from 'composables/useArrayData';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
// const arrayData = useArrayData('customers', {
|
||||||
|
// url: 'Clients',
|
||||||
|
// });
|
||||||
|
|
||||||
|
// onMounted(async () => {
|
||||||
|
// await arrayData.fetch();
|
||||||
|
// console.log(arrayData.data);
|
||||||
|
// });
|
||||||
|
|
||||||
function navigate(id) {
|
function navigate(id) {
|
||||||
router.push({ path: `/customer/${id}` });
|
router.push({ path: `/customer/${id}` });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,60 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import LeftMenu from 'components/LeftMenu.vue';
|
import LeftMenu from 'components/LeftMenu.vue';
|
||||||
|
// import TeleportSlot from 'src/components/ui/TeleportSlot.vue';
|
||||||
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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-drawer v-model="state.drawer.value" show-if-above :width="256" :breakpoint="500">
|
||||||
<q-scroll-area class="fit text-grey-8">
|
<q-scroll-area class="fit text-grey-8">
|
||||||
<LeftMenu />
|
<LeftMenu />
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
});
|
Loading…
Reference in New Issue