Merge pull request #28 from tainacan/infinite_scroll_on_collections_list
Infinite scroll on collections list #10.
This commit is contained in:
commit
973bccbbfb
File diff suppressed because it is too large
Load Diff
|
@ -43,7 +43,7 @@
|
||||||
"@vue/cli-plugin-router": "^5.0.4",
|
"@vue/cli-plugin-router": "^5.0.4",
|
||||||
"@vue/cli-plugin-typescript": "^5.0.4",
|
"@vue/cli-plugin-typescript": "^5.0.4",
|
||||||
"@vue/cli-plugin-unit-jest": "^5.0.4",
|
"@vue/cli-plugin-unit-jest": "^5.0.4",
|
||||||
"@vue/cli-service": "^5.0.4",
|
"@vue/cli-service": "5.0.4",
|
||||||
"@vue/eslint-config-typescript": "^9.1.0",
|
"@vue/eslint-config-typescript": "^9.1.0",
|
||||||
"@vue/test-utils": "^2.0.0",
|
"@vue/test-utils": "^2.0.0",
|
||||||
"@vue/vue3-jest": "^27.0.0",
|
"@vue/vue3-jest": "^27.0.0",
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
>
|
>
|
||||||
</ion-loading>
|
</ion-loading>
|
||||||
<items-list :items="tainacanStore.collectionItems"></items-list>
|
<items-list :items="tainacanStore.collectionItems"></items-list>
|
||||||
|
<ion-infinite-scroll ref="infiniteScroll" threshold="5%" @ionInfinite="loadItemsByCollection">
|
||||||
|
<ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll>
|
||||||
<ion-button
|
<ion-button
|
||||||
class="add-items-button"
|
class="add-items-button"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -27,19 +31,17 @@ import {
|
||||||
} from '../store/storeTainacan';
|
} from '../store/storeTainacan';
|
||||||
import { ref, defineComponent } from 'vue';
|
import { ref, defineComponent } from 'vue';
|
||||||
import { add, documentOutline, documentAttachOutline, documentsOutline } from "ionicons/icons";
|
import { add, documentOutline, documentAttachOutline, documentsOutline } from "ionicons/icons";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IonLoading,
|
IonLoading,
|
||||||
IonRefresher,
|
IonRefresher,
|
||||||
IonRefresherContent,
|
IonRefresherContent,
|
||||||
IonIcon,
|
IonIcon,
|
||||||
IonButton,
|
IonButton,
|
||||||
actionSheetController
|
actionSheetController,
|
||||||
|
IonInfiniteScroll
|
||||||
} from '@ionic/vue';
|
} from '@ionic/vue';
|
||||||
|
|
||||||
import BaseLayout from '@/components/base/BaseLayout.vue';
|
import BaseLayout from '@/components/base/BaseLayout.vue';
|
||||||
import ItemsList from '@/components/lists/ItemsList.vue';
|
import ItemsList from '@/components/lists/ItemsList.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
BaseLayout,
|
BaseLayout,
|
||||||
|
@ -48,7 +50,8 @@ export default defineComponent({
|
||||||
IonRefresher,
|
IonRefresher,
|
||||||
IonRefresherContent,
|
IonRefresherContent,
|
||||||
IonIcon,
|
IonIcon,
|
||||||
IonButton
|
IonButton,
|
||||||
|
IonInfiniteScroll
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -56,14 +59,22 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
const infiniteScroll = ref();
|
||||||
const setIsLoading = (state: boolean) => isLoading.value = state;
|
const setIsLoading = (state: boolean) => isLoading.value = state;
|
||||||
const loadItemsByCollection = async () => {
|
const loadItemsByCollection = async (event: any, reset: boolean) => {
|
||||||
await tainacanStore.fetchItemsByCollection(props.id + '', { perPage: '24', orderBy: 'modified'});
|
let hasMoreCollections = await tainacanStore.fetchItemsByCollection(props.id + '', { perPage: '12', orderBy: 'modified', reset: reset});
|
||||||
}
|
|
||||||
const doRefresh = async (event: any) => {
|
|
||||||
await loadItemsByCollection();
|
|
||||||
if (event && event.target)
|
if (event && event.target)
|
||||||
event.target.complete();
|
event.target.complete();
|
||||||
|
if (!hasMoreCollections){
|
||||||
|
infiniteScroll.value.$el.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const doRefresh = async (event: any) => {
|
||||||
|
await loadItemsByCollection({}, true);
|
||||||
|
if (event && event.target){
|
||||||
|
event.target.complete();
|
||||||
|
infiniteScroll.value.$el.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const actionSheetLabels = ref({
|
const actionSheetLabels = ref({
|
||||||
header: '',
|
header: '',
|
||||||
|
@ -109,15 +120,12 @@ export default defineComponent({
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
await actionSheet.present();
|
await actionSheet.present();
|
||||||
|
|
||||||
const { role, data } = await actionSheet.onDidDismiss();
|
const { role, data } = await actionSheet.onDidDismiss();
|
||||||
console.log('onDidDismiss resolved with role and data', role, data);
|
console.log('onDidDismiss resolved with role and data', role, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const collectionObject = props.collection ? JSON.parse(props.collection + '') : false;
|
const collectionObject = props.collection ? JSON.parse(props.collection + '') : false;
|
||||||
|
|
||||||
let tainacanStore = useTainacanStore();
|
let tainacanStore = useTainacanStore();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
tainacanStore,
|
tainacanStore,
|
||||||
|
@ -128,7 +136,8 @@ export default defineComponent({
|
||||||
add,
|
add,
|
||||||
actionSheetLabels,
|
actionSheetLabels,
|
||||||
setActionSheetLabels,
|
setActionSheetLabels,
|
||||||
collectionObject
|
collectionObject,
|
||||||
|
infiniteScroll
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
|
@ -140,9 +149,8 @@ export default defineComponent({
|
||||||
button3: this.$t('label_option_single_item'),
|
button3: this.$t('label_option_single_item'),
|
||||||
cancel: this.$t('label_cancel')
|
cancel: this.$t('label_cancel')
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setIsLoading(true);
|
this.setIsLoading(true);
|
||||||
await this.loadItemsByCollection();
|
await this.loadItemsByCollection({}, true);
|
||||||
this.setIsLoading(false);
|
this.setIsLoading(false);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
<ion-refresher-content></ion-refresher-content>
|
<ion-refresher-content></ion-refresher-content>
|
||||||
</ion-refresher>
|
</ion-refresher>
|
||||||
<items-list :items="tainacanStore.items"></items-list>
|
<items-list :items="tainacanStore.items"></items-list>
|
||||||
|
<ion-infinite-scroll ref="infiniteScroll" threshold="5%" @ionInfinite="loadItems">
|
||||||
|
<ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll-content>
|
||||||
|
</ion-infinite-scroll>
|
||||||
</base-layout>
|
</base-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -19,44 +23,50 @@ import {
|
||||||
import {
|
import {
|
||||||
IonLoading,
|
IonLoading,
|
||||||
IonRefresher,
|
IonRefresher,
|
||||||
IonRefresherContent
|
IonRefresherContent,
|
||||||
|
IonInfiniteScroll
|
||||||
} from '@ionic/vue';
|
} from '@ionic/vue';
|
||||||
import BaseLayout from '@/components/base/BaseLayout.vue';
|
import BaseLayout from '@/components/base/BaseLayout.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import ItemsList from '../components/lists/ItemsList.vue';
|
import ItemsList from '../components/lists/ItemsList.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
IonLoading,
|
IonLoading,
|
||||||
ItemsList,
|
ItemsList,
|
||||||
BaseLayout,
|
BaseLayout,
|
||||||
IonRefresher,
|
IonRefresher,
|
||||||
IonRefresherContent
|
IonRefresherContent,
|
||||||
|
IonInfiniteScroll
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
const setIsLoading = (state: boolean) => isLoading.value = state;
|
const setIsLoading = (state: boolean) => isLoading.value = state;
|
||||||
|
const infiniteScroll = ref();
|
||||||
const loadItems = async () => {
|
const loadItems = async (event: any, reset: boolean) => {
|
||||||
await tainacanStore.fetchItems({ perPage: '24', orderBy: 'modified'});
|
let hasMoreItems = await tainacanStore.fetchItems({ perPage: '12', orderBy: 'modified', reset: reset});
|
||||||
}
|
|
||||||
const doRefresh = async (event: any) => {
|
|
||||||
await loadItems();
|
|
||||||
if (event && event.target)
|
if (event && event.target)
|
||||||
event.target.complete();
|
event.target.complete();
|
||||||
|
if (!hasMoreItems){
|
||||||
|
infiniteScroll.value.$el.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const doRefresh = async (event: any) => {
|
||||||
|
await loadItems({}, true);
|
||||||
|
if (event && event.target){
|
||||||
|
event.target.complete();
|
||||||
|
infiniteScroll.value.$el.disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tainacanStore = useTainacanStore();
|
let tainacanStore = useTainacanStore();
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
setIsLoading,
|
setIsLoading,
|
||||||
tainacanStore,
|
tainacanStore,
|
||||||
doRefresh,
|
doRefresh,
|
||||||
loadItems
|
loadItems,
|
||||||
|
infiniteScroll
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async created(){
|
async created(){
|
||||||
this.setIsLoading(true)
|
this.setIsLoading(true)
|
||||||
await this.loadItems();
|
await this.loadItems();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { defineStore } from "pinia";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { defineStore } from "pinia";
|
||||||
import { useWpStore } from "./storeWp";
|
import { useWpStore } from "./storeWp";
|
||||||
|
|
||||||
const useTainacanStore = defineStore("tainacan", {
|
const useTainacanStore = defineStore("tainacan", {
|
||||||
|
@ -13,7 +13,9 @@ const useTainacanStore = defineStore("tainacan", {
|
||||||
totalCollections: 0,
|
totalCollections: 0,
|
||||||
collectionItems: [],
|
collectionItems: [],
|
||||||
totalCollectionItems: 0,
|
totalCollectionItems: 0,
|
||||||
|
nextItemsByCollectionPage: 1,
|
||||||
items: [],
|
items: [],
|
||||||
|
nextItemsPage: 1,
|
||||||
totalItems: 0,
|
totalItems: 0,
|
||||||
siteUrl: "",
|
siteUrl: "",
|
||||||
userLogin: "",
|
userLogin: "",
|
||||||
|
@ -68,30 +70,48 @@ const useTainacanStore = defineStore("tainacan", {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchItemsByCollection(collectionId: string, params: { perPage: string, orderBy: string }) {
|
async fetchItemsByCollection(collectionId: string, params: { perPage: string, orderBy: string, reset: boolean }) {
|
||||||
try {
|
try {
|
||||||
const wpStore = useWpStore();
|
const wpStore = useWpStore();
|
||||||
this.collectionItems = [];
|
|
||||||
|
|
||||||
let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collection/${collectionId}/items?fetch_only=id,title,thumbnail&perpage=12&orderby=modified`;
|
let endpoint = `${wpStore.userSiteUrl}/wp-json/tainacan/v2/collection/${collectionId}/items?fetch_only=id,title,thumbnail`;
|
||||||
|
|
||||||
if (params && params.perPage)
|
if (params && params.perPage)
|
||||||
endpoint += '&perpage=' + params.perPage;
|
endpoint += '&perpage=' + params.perPage;
|
||||||
|
else
|
||||||
|
endpoint += '&perpage=12';
|
||||||
|
|
||||||
if (params && params.orderBy)
|
if (params && params.orderBy)
|
||||||
endpoint += '&orderby=' + params.orderBy;
|
endpoint += '&orderby=' + params.orderBy;
|
||||||
|
else
|
||||||
|
endpoint += '&orderby=modified';
|
||||||
|
|
||||||
|
if (params.reset) {
|
||||||
|
this.collectionItems = [];
|
||||||
|
this.nextItemsByCollectionPage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint += '&paged=' + this.nextItemsByCollectionPage;
|
||||||
|
|
||||||
const response = await axios.get(endpoint);
|
const response = await axios.get(endpoint);
|
||||||
|
|
||||||
this.collectionItems = response.data.items;
|
this.collectionItems.push(...response.data.items);
|
||||||
this.totalCollectionItems = response.headers['x-wp-total'];
|
this.totalCollectionItems = response.headers['x-wp-total'];
|
||||||
|
|
||||||
|
if (!this.totalCollectionItems ||
|
||||||
|
this.totalCollectionItems === "0") {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.nextItemsByCollectionPage++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.collectionItems = [];
|
this.collectionItems = [];
|
||||||
this.totalCollectionItems = 0;
|
this.totalCollectionItems = 0;
|
||||||
|
this.nextItemsByCollectionPage = 1;
|
||||||
console.error("Erro no carregamento dos items da coleção:", err);
|
console.error("Erro no carregamento dos items da coleção:", err);
|
||||||
|
|
||||||
return err;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -113,7 +133,7 @@ const useTainacanStore = defineStore("tainacan", {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchItems(params: { perPage: string, orderBy: string }) {
|
async fetchItems(params: { perPage: string, orderBy: string, reset: boolean }) {
|
||||||
try {
|
try {
|
||||||
const wpStore = useWpStore();
|
const wpStore = useWpStore();
|
||||||
|
|
||||||
|
@ -125,13 +145,29 @@ const useTainacanStore = defineStore("tainacan", {
|
||||||
if (params && params.orderBy)
|
if (params && params.orderBy)
|
||||||
endpoint += '&orderby=' + params.orderBy;
|
endpoint += '&orderby=' + params.orderBy;
|
||||||
|
|
||||||
|
if(params.reset){
|
||||||
|
this.items = [];
|
||||||
|
this.nextItemsPage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint += '&paged=' + this.nextItemsPage;
|
||||||
|
|
||||||
const response = await axios.get(endpoint);
|
const response = await axios.get(endpoint);
|
||||||
this.items = response.data.items;
|
this.items.push(...response.data.items);
|
||||||
this.totalItems = response.headers['x-wp-total'];
|
this.totalItems = response.headers['x-wp-total'];
|
||||||
|
|
||||||
|
if (!this.totalItems ||
|
||||||
|
this.totalItems === "0") {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.nextItemsPage++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.items = [];
|
this.items = [];
|
||||||
this.totalItems = 0;
|
this.totalItems = 0;
|
||||||
|
this.nextItemsPage = 1;
|
||||||
console.error("Erro no carregamento dos items:", err);
|
console.error("Erro no carregamento dos items:", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue