diff --git a/src/locales/translation-strings.ts b/src/locales/translation-strings.ts index e32aa7e..78fc701 100644 --- a/src/locales/translation-strings.ts +++ b/src/locales/translation-strings.ts @@ -26,6 +26,8 @@ export const translationStrings = { label_option_multiple_attachments: 'Single item with document and attachments from file selection', label_option_single_item: 'Single empty item', label_cancel: 'Cancel', + label_search: 'Search', + label_no_results_found: 'No results found', info_application_password: 'This password is not the same of your WordPress admin.', label_learn_more_here: 'Learn more here' }, @@ -56,6 +58,8 @@ export const translationStrings = { label_option_multiple_attachments: 'Um item com documento e anexos provenientes de ums seleção de aquivos', label_option_single_item: 'Um item vazio', label_cancel: 'Cancelar', + label_search: 'Buscar', + label_no_results_found: 'Nenhum resultado encontrado', info_application_password: 'Esta senha não é a mesma do seu painel admin do WordPress.', label_learn_more_here: 'Saiba mais aqui.' } diff --git a/src/pages/CollectionPage.vue b/src/pages/CollectionPage.vue index aa40e74..6f3e6a6 100644 --- a/src/pages/CollectionPage.vue +++ b/src/pages/CollectionPage.vue @@ -5,11 +5,21 @@ + + + + +
+ {{$t('label_no_results_found')}} +
@@ -40,6 +50,9 @@ import { IonButton, actionSheetController, IonInfiniteScroll, + IonToolbar, + IonSearchbar, + IonSpinner, IonInfiniteScrollContent } from '@ionic/vue'; import BaseLayout from '@/components/base/BaseLayout.vue'; @@ -56,6 +69,9 @@ export default defineComponent({ IonIcon, IonButton, IonInfiniteScroll, + IonToolbar, + IonSearchbar, + IonSpinner, IonInfiniteScrollContent }, props: { @@ -64,15 +80,36 @@ export default defineComponent({ }, setup(props) { const isLoading = ref(false); + const isSearching = ref(false) + const search = ref(); const infiniteScroll = ref(); const setIsLoading = (state: boolean) => isLoading.value = state; + const setIsSearching = (state: boolean) => isSearching.value = state; + const setSearch = (value: string) => search.value = value; const loadItemsByCollection = async (event: any, reset: boolean) => { - let hasMoreCollections = await tainacanStore.fetchItemsByCollection(props.id + '', { perPage: '12', orderBy: 'modified', reset: reset}); + await tainacanStore.fetchItemsByCollection(props.id + '', { perPage: '12', orderBy: 'modified', reset: reset, search: search.value}); + let hasMoreCollectionsItems = tainacanStore.totalCollectionItems && tainacanStore.totalCollectionItems !== 0; if (event && event.target) event.target.complete(); - if (!hasMoreCollections){ + if (!hasMoreCollectionsItems){ infiniteScroll.value.$el.disabled = true; } + } + const cancelSearch = async () => { + await loadItemsByCollection(null, true); + } + const handleSearch = async (event: any) => { + let search = event && event.detail && event.detail.value; + + setSearch(search); + setIsSearching(true); + + if(search !== '') { + await loadItemsByCollection(null, true); + } else { + await cancelSearch(); + } + setIsSearching(false); } const doRefresh = async (event: any) => { await loadItemsByCollection({}, true); @@ -146,6 +183,7 @@ export default defineComponent({ let tainacanStore = useTainacanStore(); return { isLoading, + isSearching, tainacanStore, wpStore, setIsLoading, @@ -156,7 +194,8 @@ export default defineComponent({ actionSheetLabels, setActionSheetLabels, collectionObject, - infiniteScroll + infiniteScroll, + handleSearch, } }, async created() { @@ -176,15 +215,18 @@ export default defineComponent({ \ No newline at end of file diff --git a/src/pages/ItemsPage.vue b/src/pages/ItemsPage.vue index e88f3e2..6377c1a 100644 --- a/src/pages/ItemsPage.vue +++ b/src/pages/ItemsPage.vue @@ -5,10 +5,18 @@ :message="$t('label_loading')" > + + + + +
+ {{$t('label_no_results_found')}} +
+ @@ -25,6 +33,9 @@ import { IonRefresher, IonRefresherContent, IonInfiniteScroll, + IonToolbar, + IonSearchbar, + IonSpinner, IonInfiniteScrollContent } from '@ionic/vue'; import BaseLayout from '@/components/base/BaseLayout.vue'; @@ -38,19 +49,44 @@ export default { IonRefresher, IonRefresherContent, IonInfiniteScroll, + IonToolbar, + IonSearchbar, + IonSpinner, IonInfiniteScrollContent }, setup() { const isLoading = ref(false); + const isSearching = ref(false) + const search = ref(); const setIsLoading = (state: boolean) => isLoading.value = state; + const setIsSearching = (state: boolean) => isSearching.value = state; + const setSearch = (value: string) => search.value = value; const infiniteScroll = ref(); const loadItems = async (event: any, reset: boolean) => { - let hasMoreItems = await tainacanStore.fetchItems({ perPage: '12', orderBy: 'modified', reset: reset}); + await tainacanStore.fetchItems({ perPage: '12', orderBy: 'modified', reset: reset, search: search.value}); + let hasMoreItems = tainacanStore.totalItems && tainacanStore.totalItems !== 0; if (event && event.target) event.target.complete(); if (!hasMoreItems){ infiniteScroll.value.$el.disabled = true; } + } + const cancelSearch = async () => { + await loadItems(null, true); + } + const handleSearch = async (event: any) => { + let search = event && event.detail && event.detail.value; + + setSearch(search); + setIsSearching(true); + + if(search !== '') { + await loadItems(null, true); + setIsSearching(false); + } else { + await cancelSearch(); + } + setIsSearching(false); } const doRefresh = async (event: any) => { await loadItems({}, true); @@ -62,11 +98,13 @@ export default { let tainacanStore = useTainacanStore(); return { isLoading, + isSearching, setIsLoading, tainacanStore, doRefresh, loadItems, - infiniteScroll + infiniteScroll, + handleSearch } }, async created(){ @@ -75,4 +113,10 @@ export default { this.setIsLoading(false) }, } - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/store/storeTainacan.ts b/src/store/storeTainacan.ts index 298e192..b35c79c 100644 --- a/src/store/storeTainacan.ts +++ b/src/store/storeTainacan.ts @@ -77,7 +77,7 @@ const useTainacanStore = defineStore("tainacan", { } }, - async fetchItemsByCollection(collectionId: string, params: { perPage: string, orderBy: string, reset: boolean }) { + async fetchItemsByCollection(collectionId: string, params: { perPage: string, orderBy: string, reset?: boolean, search?: string }) { try { const wpStore = useWpStore(); @@ -93,6 +93,9 @@ const useTainacanStore = defineStore("tainacan", { endpoint += '&orderby=' + params.orderBy; else endpoint += '&orderby=modified'; + + if (params && params.search && params.search !== '') + endpoint += '&search=' + params.search if (params.reset) { this.collectionItems = []; @@ -110,13 +113,10 @@ const useTainacanStore = defineStore("tainacan", { this.collectionItems.push(...response.data.items); this.totalCollectionItems = response.headers['x-wp-total']; - if (!this.totalCollectionItems || - this.totalCollectionItems === "0") { - return false; - } else { - this.nextItemsByCollectionPage++; - return true; + if (this.totalCollectionItems && this.totalCollectionItems !== "0") { + this.nextItemsByCollectionPage++; } + } catch (err) { this.collectionItems = []; this.totalCollectionItems = 0; @@ -151,7 +151,7 @@ const useTainacanStore = defineStore("tainacan", { } }, - async fetchItems(params: { perPage: string, orderBy: string, reset: boolean }) { + async fetchItems(params: { perPage: string, orderBy: string, reset?: boolean, search?: string }) { try { const wpStore = useWpStore(); @@ -164,6 +164,9 @@ const useTainacanStore = defineStore("tainacan", { if (params && params.orderBy) endpoint += '&orderby=' + params.orderBy; + if (params && params.search && params.search !== '') + endpoint += '&search=' + params.search + if (params.reset) { this.items = []; this.nextItemsPage = 1; @@ -180,12 +183,8 @@ const useTainacanStore = defineStore("tainacan", { this.items.push(...response.data.items); this.totalItems = response.headers['x-wp-total']; - if (!this.totalItems || - this.totalItems === "0") { - return false; - } else { + if (this.totalItems && this.totalItems !== "0") { this.nextItemsPage++; - return true; } } catch (err) { diff --git a/src/theme/core.css b/src/theme/core.css index e69de29..f9eb550 100644 --- a/src/theme/core.css +++ b/src/theme/core.css @@ -0,0 +1,7 @@ +ion-spinner { + display: block; + margin: auto; +} +.results-not-found { + text-align: center; +} \ No newline at end of file