Skip to content

Commit cb7e1bb

Browse files
UFAL/Reset pagination on search term change (#1281)
Reset pagination on search term change (cherry picked from commit aa495d3) Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz>
1 parent 7aca074 commit cb7e1bb

3 files changed

Lines changed: 75 additions & 16 deletions

File tree

src/app/clarin-licenses/clarin-license-table/clarin-license-table.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[(ngModel)]="searchingLicenseName"
66
class="form-control ng-pristine ng-valid ng-touched"
77
[placeholder]="'clarin-license.button.search.placeholder' | translate"/>
8-
<span class="input-group-append" (click)="loadAllLicenses()">
8+
<span class="input-group-append" (click)="searchLicenses()">
99
<button type="submit" class="btn btn-primary search-button">
1010
<i class="fas fa-search"></i>{{'clarin-license.button.search' | translate}}</button>
1111
</span>

src/app/clarin-licenses/clarin-license-table/clarin-license-table.component.spec.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('ClarinLicenseTableComponent', () => {
4444
let groupsDataService: GroupDataService;
4545
let service: ConfigurationDataService;
4646
let searchConfigurationServiceStub: SearchConfigurationService;
47+
let paginationServiceStub: PaginationServiceStub;
4748

4849
beforeEach(async () => {
4950
notificationService = new NotificationsServiceStub();
@@ -85,6 +86,7 @@ describe('ClarinLicenseTableComponent', () => {
8586
updateFixedFilter: jasmine.createSpy('updateFixedFilter'),
8687
setPaginationId: jasmine.createSpy('setPaginationId')
8788
});
89+
paginationServiceStub = new PaginationServiceStub();
8890

8991
await TestBed.configureTestingModule({
9092
imports: [
@@ -99,7 +101,7 @@ describe('ClarinLicenseTableComponent', () => {
99101
{ provide: RequestService, useValue: requestService },
100102
{ provide: ClarinLicenseDataService, useValue: clarinLicenseDataService },
101103
{ provide: ClarinLicenseLabelDataService, useValue: clarinLicenseLabelDataService },
102-
{ provide: PaginationService, useValue: new PaginationServiceStub() },
104+
{ provide: PaginationService, useValue: paginationServiceStub },
103105
{ provide: NotificationsService, useValue: notificationService },
104106
{ provide: NgbActiveModal, useValue: modalStub },
105107
{ provide: HostWindowService, useValue: new HostWindowServiceStub(0) },
@@ -181,4 +183,50 @@ describe('ClarinLicenseTableComponent', () => {
181183
expect((component as any).clarinLicenseService.searchBy).toHaveBeenCalled();
182184
expect((component as ClarinLicenseTableComponent).licensesRD$).not.toBeNull();
183185
});
186+
187+
it('should reset pagination to page 1 when the search term changes', () => {
188+
paginationServiceStub.pagination.id = defaultPagination.id;
189+
paginationServiceStub.pagination.currentPage = 2;
190+
paginationServiceStub.pagination.pageSize = 10;
191+
paginationServiceStub.pagination.pageSizeOptions = defaultPagination.pageSizeOptions;
192+
(component as any).clarinLicenseService.searchBy.calls.reset();
193+
paginationServiceStub.resetPage.calls.reset();
194+
195+
component.searchingLicenseName = 'Universal';
196+
197+
component.searchLicenses();
198+
199+
expect(paginationServiceStub.resetPage).toHaveBeenCalledWith(defaultPagination.id);
200+
expect((component as any).clarinLicenseService.searchBy).toHaveBeenCalledWith(
201+
'byNameLike',
202+
jasmine.objectContaining({
203+
currentPage: 1,
204+
elementsPerPage: 10,
205+
}),
206+
false
207+
);
208+
});
209+
210+
it('should not reset pagination when searching with the same term', () => {
211+
paginationServiceStub.pagination.id = defaultPagination.id;
212+
paginationServiceStub.pagination.currentPage = 2;
213+
paginationServiceStub.pagination.pageSize = 10;
214+
paginationServiceStub.pagination.pageSizeOptions = defaultPagination.pageSizeOptions;
215+
(component as any).clarinLicenseService.searchBy.calls.reset();
216+
paginationServiceStub.resetPage.calls.reset();
217+
(component as any).previousSearchTerm = 'Universal';
218+
component.searchingLicenseName = 'Universal';
219+
220+
component.searchLicenses();
221+
222+
expect(paginationServiceStub.resetPage).not.toHaveBeenCalled();
223+
expect((component as any).clarinLicenseService.searchBy).toHaveBeenCalledWith(
224+
'byNameLike',
225+
jasmine.objectContaining({
226+
currentPage: 2,
227+
elementsPerPage: 10,
228+
}),
229+
false
230+
);
231+
});
184232
});

src/app/clarin-licenses/clarin-license-table/clarin-license-table.component.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { RemoteData } from '../../core/data/remote-data';
55
import { PaginatedList } from '../../core/data/paginated-list.model';
66
import { ClarinLicense } from '../../core/shared/clarin/clarin-license.model';
77
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../../core/shared/operators';
8-
import { scan, switchMap } from 'rxjs/operators';
8+
import { switchMap } from 'rxjs/operators';
99
import { PaginationService } from '../../core/pagination/pagination.service';
1010
import { ClarinLicenseDataService } from '../../core/data/clarin/clarin-license-data.service';
1111
import { defaultPagination, defaultSortConfiguration } from '../clarin-license-table-pagination';
@@ -67,6 +67,11 @@ export class ClarinLicenseTableComponent implements OnInit {
6767
*/
6868
searchingLicenseName = '';
6969

70+
/**
71+
* Stores the previous search term to detect when a new search should reset pagination.
72+
*/
73+
private previousSearchTerm = '';
74+
7075
ngOnInit(): void {
7176
this.initializePaginationOptions();
7277
this.loadAllLicenses();
@@ -315,33 +320,39 @@ export class ClarinLicenseTableComponent implements OnInit {
315320
this.loadAllLicenses();
316321
}
317322

323+
/**
324+
* Run a search and reset the route-backed pagination when the search term changes.
325+
*/
326+
searchLicenses() {
327+
const hasSearchTermChanged = this.searchingLicenseName !== this.previousSearchTerm;
328+
329+
if (hasSearchTermChanged) {
330+
this.paginationService.resetPage(this.options.id);
331+
}
332+
333+
this.loadAllLicenses(hasSearchTermChanged ? 1 : undefined);
334+
this.previousSearchTerm = this.searchingLicenseName;
335+
}
336+
318337
/**
319338
* Fetch all licenses from the API.
320339
*/
321-
loadAllLicenses() {
340+
loadAllLicenses(pageOverride?: number) {
322341
this.selectedLicense = null;
323342
this.licensesRD$ = new BehaviorSubject<RemoteData<PaginatedList<ClarinLicense>>>(null);
324343
this.isLoading = true;
325344

326345
// load the current pagination and sorting options
327346
const currentPagination$ = this.getCurrentPagination();
328347
const currentSort$ = this.getCurrentSort();
329-
const searchTerm$ = new BehaviorSubject<string>(this.searchingLicenseName);
330-
331-
observableCombineLatest([currentPagination$, currentSort$, searchTerm$]).pipe(
332-
scan((prevState, [currentPagination, currentSort, searchTerm]) => {
333-
// If search term has changed, reset to page 1; otherwise, keep current page
334-
const currentPage = prevState.searchTerm !== searchTerm ? 1 : currentPagination.currentPage;
335-
return { currentPage, currentPagination, currentSort, searchTerm };
336-
}, { searchTerm: '', currentPage: 1, currentPagination: this.getCurrentPagination(),
337-
currentSort: this.getCurrentSort() }),
338348

339-
switchMap(({ currentPage, currentPagination, currentSort, searchTerm }) => {
349+
observableCombineLatest([currentPagination$, currentSort$]).pipe(
350+
switchMap(([currentPagination, currentSort]) => {
340351
return this.clarinLicenseService.searchBy('byNameLike', {
341-
currentPage: currentPage, // Properly reset page only when needed
352+
currentPage: pageOverride ?? currentPagination.currentPage,
342353
elementsPerPage: currentPagination.pageSize,
343354
sort: { field: currentSort.field, direction: currentSort.direction },
344-
searchParams: [new RequestParam('name', searchTerm)]
355+
searchParams: [new RequestParam('name', this.searchingLicenseName)]
345356
}, false
346357
);
347358
}),

0 commit comments

Comments
 (0)