Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pagination #1929

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions app/models/index-card-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,30 @@ export default class IndexCardSearchModel extends Model {

@belongsTo('index-property-search', { inverse: null })
relatedPropertySearch!: AsyncBelongsTo<IndexPropertySearchModel> & IndexPropertySearchModel;

get firstPageCursor() {
if (this.searchResultPage.links.first?.href) {
const firstPageLinkUrl = new URL(this.searchResultPage.links.first?.href);
return firstPageLinkUrl.searchParams.get('page[cursor]');
}
return null;
}

get prevPageCursor() {
if (this.searchResultPage.links.prev?.href) {
const prevPageLinkUrl = new URL(this.searchResultPage.links.prev?.href);
return prevPageLinkUrl.searchParams.get('page[cursor]');
}
return null;
}

get nextPageCursor() {
if (this.searchResultPage.links.next?.href) {
const nextPageLinkUrl = new URL(this.searchResultPage.links.next?.href);
return nextPageLinkUrl.searchParams.get('page[cursor]');
}
return null;
}
}

declare module 'ember-data/types/registries/model' {
Expand Down
4 changes: 3 additions & 1 deletion app/search/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { OnSearchParams, ResourceTypeFilterValue } from 'osf-components/componen
export default class SearchController extends Controller {
@tracked cardSearchText?: string = '';
@tracked sort?: string = '-relevance';
@tracked resourceType?: ResourceTypeFilterValue | null = null;
@tracked resourceType?: ResourceTypeFilterValue | null = null;
@tracked page?: string = '';

queryParams = ['cardSearchText', 'page', 'sort', 'resourceType'];

Expand All @@ -15,5 +16,6 @@ export default class SearchController extends Controller {
this.cardSearchText = queryOptions.cardSearchText;
this.sort = queryOptions.sort;
this.resourceType = queryOptions.resourceType;
this.page = queryOptions.page;
}
}
3 changes: 2 additions & 1 deletion app/search/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

<SearchPage
@route='search'
@query={{this.q}}
@cardSearchText={{this.cardSearchText}}
@queryParams={{this.queryParams}}
@onSearch={{action this.onSearch}}
@showResourceTypeFilter={{true}}
@sort={{this.sort}}
@resourceType={{this.resourceType}}
@page={{this.page}}
/>
29 changes: 22 additions & 7 deletions lib/osf-components/addon/components/search-page/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export interface OnSearchParams {

interface SearchArgs {
onSearch?: (obj: OnSearchParams) => void;
query?: string;
cardSearchText: string;
cardSearchFilters: Filter[];
propertyCard: IndexCardModel;
Expand All @@ -59,6 +58,7 @@ interface SearchArgs {
defaultQueryOptions: Record<string, string>;
provider?: ProviderModel;
showResourceTypeFilter: boolean;
page: string;
}

const searchDebounceTime = 100;
Expand All @@ -69,15 +69,18 @@ export default class SearchPage extends Component<SearchArgs> {
@service store!: Store;
@service media!: Media;

@tracked searchText?: string;
@tracked cardSearchText?: string;
@tracked searchResults?: SearchResultModel[];
@tracked propertySearch?: IndexPropertySearchModel;
@tracked page?: number = 1;
@tracked page?: string = '';
@tracked totalResultCount?: number;
@tracked firstPageCursor?: string | null;
@tracked prevPageCursor?: string | null;
@tracked nextPageCursor?: string | null;

constructor( owner: unknown, args: SearchArgs) {
super(owner, args);
this.searchText = this.args.query;
this.cardSearchText = this.args.cardSearchText;
this.sort = this.args.sort;
this.resourceType = this.args.resourceType;
taskFor(this.search).perform();
Expand Down Expand Up @@ -188,7 +191,7 @@ export default class SearchPage extends Component<SearchArgs> {
@waitFor
async search() {
try {
const cardSearchText = this.searchText;
const cardSearchText = this.cardSearchText;
const { page, sort, activeFilters, resourceType } = this;
let filterQueryObject = activeFilters.reduce((acc, filter) => {
acc[filter.property] = filter.value;
Expand All @@ -202,21 +205,30 @@ export default class SearchPage extends Component<SearchArgs> {
filterQueryObject = { ...filterQueryObject, ...this.args.defaultQueryOptions };
const searchResult = await this.store.queryRecord('index-card-search', {
cardSearchText,
page,
'page[cursor]': page,
sort,
cardSearchFilter: filterQueryObject,
});
this.firstPageCursor = searchResult.firstPageCursor;
this.nextPageCursor = searchResult.nextPageCursor;
this.prevPageCursor = searchResult.prevPageCursor;
this.propertySearch = await searchResult.relatedPropertySearch;
this.searchResults = searchResult.searchResultPage.toArray();
this.totalResultCount = searchResult.totalResultCount;
if (this.args.onSearch) {
this.args.onSearch({cardSearchText, sort, resourceType});
this.args.onSearch({cardSearchText, sort, resourceType, page});
}
} catch (e) {
this.toast.error(e);
}
}

@action
switchPage(pageCursor: string) {
this.page = pageCursor;
taskFor(this.search).perform();
}

@task({ restartable: true })
@waitFor
async doDebounceSearch() {
Expand All @@ -234,18 +246,21 @@ export default class SearchPage extends Component<SearchArgs> {
} else {
this.activeFilters.pushObject(filter);
}
this.page = '';
taskFor(this.search).perform();
}

@action
updateSort(sortOption: SortOption) {
this.sort = sortOption.value;
this.page = '';
taskFor(this.search).perform();
}

@action
updateResourceType(resourceTypeOption: ResourceTypeOption) {
this.resourceType = resourceTypeOption.value;
this.page = '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updateSort and toggleFilter should reset the page too

taskFor(this.search).perform();
}
}
4 changes: 4 additions & 0 deletions lib/osf-components/addon/components/search-page/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,7 @@
display: flex;
justify-content: space-between;
}

.pagination-buttons {
display: flex;
}
23 changes: 23 additions & 0 deletions lib/osf-components/addon/components/search-page/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,29 @@ as |layout|>
<p local-class='no-results'>{{t 'search.no-results'}}</p>
{{/each}}
{{/if}}
<div local-class='pagination-buttons'>
{{#if this.firstPageCursor}}
<Button
{{on 'click' (fn this.switchPage this.firstPageCursor)}}
>
{{t 'search.first'}}
</Button>
{{/if}}
{{#if this.prevPageCursor}}
<Button
{{on 'click' (fn this.switchPage this.prevPageCursor)}}
>
{{t 'search.prev'}}
</Button>
{{/if}}
{{#if this.nextPageCursor}}
<Button
{{on 'click' (fn this.switchPage this.nextPageCursor)}}
>
{{t 'search.next'}}
</Button>
{{/if}}
</div>
</layout.main>
</OsfLayout>
{{#if this.showTooltip1}}
Expand Down
3 changes: 3 additions & 0 deletions translations/en-us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ search:
preprints: 'Preprints'
files: 'Files'
users: 'Users'
first: First
prev: Prev
next: Next
sort:
sort-by: 'Sort by'
relevance: 'Relevance'
Expand Down
Loading