Skip to content

Commit b8c799e

Browse files
committed
feat(public-search): display disabled request button with explanatory tooltip
* Only when the patron has reached the maximum number of active loans, fees, or requests, the request button is now displayed in the public UI but disabled with a tooltip explaining the reason. This allows patron to understand why they cannot place a request. * Depends on rero/rero-ils#3992. Co-Authored-by: Pascal Repond <[email protected]>
1 parent 3879aa2 commit b8c799e

File tree

13 files changed

+74
-38
lines changed

13 files changed

+74
-38
lines changed

projects/admin/src/app/service/holdings.service.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ describe('HoldingsService', () => {
6868
});
6969

7070
it('should return true on the possibility of making a request', () => {
71-
httpClientSpy.get.and.returnValue(of(true));
72-
service.canRequest('pid').subscribe((result: any) => expect(result).toBeTrue());
71+
httpClientSpy.get.and.returnValue(of({ can: true, reasons: {} }));
72+
service.canRequest('pid').subscribe((result: any) => expect(result.can).toBeTrue());
7373
});
7474

7575
it('should return a list of pickup locations', () => {

projects/admin/src/app/service/items.service.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ describe('ItemsService', () => {
203203
});
204204

205205
it('canRequest', () => {
206-
httpClientSpy.get.and.returnValue(of(true));
207-
service.canRequest('1').subscribe((result: boolean) => expect(result).toBeTrue());
206+
httpClientSpy.get.and.returnValue(of({ can: true, reasons: {} }));
207+
service.canRequest('1').subscribe((result: any) => expect(result.can).toBeTrue());
208208
});
209209

210210
it('needCallout', () => {

projects/public-holdings-items/src/app/app.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import { HoldingsComponent } from 'projects/public-search/src/app/document-detai
5050
import { ItemsComponent } from 'projects/public-search/src/app/document-detail/holdings/items/items.component';
5151
import { ItemComponent } from 'projects/public-search/src/app/document-detail/item/item.component';
5252
import { PickupLocationComponent } from 'projects/public-search/src/app/document-detail/request/pickup-location/pickup-location.component';
53-
import { RequestComponent } from 'projects/public-search/src/app/document-detail/request/request.component';
53+
import { HoldingsRequestComponent } from 'projects/public-search/src/app/document-detail/request/holdings-request.component';
5454
import { AppConfigService } from './app-config-service.service';
5555
import { AppInitializerService } from './app-initializer.service';
5656
import { ItemRequestComponent } from 'projects/public-search/src/app/document-detail/item/item-request.component';
@@ -88,7 +88,7 @@ import { ItemRequestComponent } from 'projects/public-search/src/app/document-de
8888
ItemComponent,
8989
ItemsComponent,
9090
PickupLocationComponent,
91-
RequestComponent,
91+
HoldingsRequestComponent,
9292
DocumentDetailViewComponent,
9393
ElectronicHoldingsComponent,
9494
ItemRequestComponent

projects/public-search/src/app/api/item-api.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('ItemService', () => {
5858

5959
const canRequest = {
6060
can: true,
61-
reasons: []
61+
reasons: {}
6262
};
6363

6464
const request = {

projects/public-search/src/app/api/loan-api.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe('LoanApiService', () => {
5151

5252
const canExtend = {
5353
can: true,
54-
reasons: []
54+
reasons: {}
5555
};
5656

5757
const renew = {

projects/public-search/src/app/api/loan-api.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import { HttpClient } from '@angular/common/http';
1818
import { inject, Injectable } from '@angular/core';
1919
import { LoanOverduePreview } from '@app/admin/classes/loans';
20-
import { ApiService, Error, Record, RecordService } from '@rero/ng-core';
20+
import { ApiService, Error, Record as EsRecord, RecordService } from '@rero/ng-core';
2121
import { BaseApi } from '@rero/shared';
2222
import { Observable, of } from 'rxjs';
2323
import { catchError, map } from 'rxjs/operators';
@@ -43,7 +43,7 @@ export class LoanApiService extends BaseApi {
4343
patronPid: string, page: number,
4444
itemsPerPage = 20, headers = BaseApi.reroJsonheaders,
4545
sort?: string
46-
): Observable<Record | Error> {
46+
): Observable<EsRecord | Error> {
4747
const loanStates = ['ITEM_ON_LOAN'];
4848
return this.recordService.getRecords(
4949
'loans', this._patronStateQuery(patronPid, loanStates), page, itemsPerPage,
@@ -62,7 +62,7 @@ export class LoanApiService extends BaseApi {
6262
getRequest(
6363
patronPid: string, page: number,
6464
itemsPerPage = 10, headers = BaseApi.reroJsonheaders
65-
): Observable<Record | Error> {
65+
): Observable<EsRecord | Error> {
6666
const requestStates = ['PENDING', 'ITEM_AT_DESK', 'ITEM_IN_TRANSIT_FOR_PICKUP'];
6767
return this.recordService.getRecords(
6868
'loans', this._patronStateQuery(patronPid, requestStates), page, itemsPerPage,
@@ -141,5 +141,5 @@ export class LoanApiService extends BaseApi {
141141

142142
export type CanExtend = {
143143
can: boolean;
144-
reasons: string[];
144+
reasons: Record<string, string>;
145145
}

projects/public-search/src/app/document-detail/holdings/holdings.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ import { ButtonDirective } from 'primeng/button';
2424
import { Message } from 'primeng/message';
2525
import { Ripple } from 'primeng/ripple';
2626
import { HoldingsApiService } from '../../api/holdings-api.service';
27-
import { RequestComponent } from '../request/request.component';
27+
import { HoldingsRequestComponent } from '../request/holdings-request.component';
2828
import { HoldingsStore } from '../store/holdings-store';
2929
import { ItemsComponent } from './items/items.component';
3030
import { MultiSelect } from 'primeng/multiselect';
3131

3232
@Component({
3333
selector: 'public-search-holdings',
3434
templateUrl: './holdings.component.html',
35-
imports: [Message, Accordion, AccordionPanel, Ripple, AccordionHeader, SharedModule, TranslateDirective, AccordionContent, ItemsComponent, RequestComponent, NgClass, ButtonDirective, I18nPluralPipe, TranslatePipe, CoreModule, MultiSelect],
35+
imports: [Message, Accordion, AccordionPanel, Ripple, AccordionHeader, SharedModule, TranslateDirective, AccordionContent, ItemsComponent, HoldingsRequestComponent, NgClass, ButtonDirective, I18nPluralPipe, TranslatePipe, CoreModule, MultiSelect],
3636
providers: [HoldingsStore]
3737
})
3838
export class HoldingsComponent implements OnInit {

projects/public-search/src/app/document-detail/item/item-request.component.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { canRequest } from '../model/can-request-model';
2929
<p-button
3030
class="ui:pointer-events-auto"
3131
outlined
32-
[hidden]="!canRequest().can"
32+
[hidden]="!hiddenRequestButton()"
3333
[disabled]="!canRequest().can"
3434
[tooltipDisabled]="canRequest().can"
3535
[pTooltip]="tooltip()"
@@ -52,9 +52,23 @@ export class ItemRequestComponent implements OnInit {
5252

5353
canRequest = signal<canRequest>({ can: false });
5454

55-
tooltip = computed(() => this.canRequest().reasons?.map(
56-
(reason: string) => this.translateService.instant(reason)
57-
).join('\n\n'));
55+
reasonsToDisplay = [
56+
"patron_type_overdue_items_limit",
57+
"patron_type_fee_amount_limit",
58+
"patron_type_unpaid_subscription",
59+
"patron_type_request_limits"
60+
]
61+
62+
allReasonsDisplayable = computed(() =>
63+
this.canRequest().reasons &&
64+
Object.keys(reasons).every(key => this.reasonsToDisplay.includes(key))
65+
);
66+
67+
hiddenRequestButton = computed(() => this.canRequest().can || this.allReasonsDisplayable());
68+
69+
tooltip = computed(() => Object.values(this.canRequest().reasons || {}).map(
70+
(reason: string) => "- " + this.translateService.instant(reason)
71+
).join('\n'));
5872

5973
private _patron: IPatron;
6074

projects/public-search/src/app/document-detail/model/can-request-model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
*/
1717
export type canRequest = {
1818
can: boolean;
19-
reasons?: string[];
19+
reasons?: Record<string, string>;
2020
}

projects/public-search/src/app/document-detail/request/request.component.html renamed to projects/public-search/src/app/document-detail/request/holdings-request.component.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@
2222
id="record-{{ record.metadata.pid }}-request-button"
2323
outlined
2424
(onClick)="showRequestDialog()"
25-
[hidden]="!canRequest?.can"
25+
[hidden]="!hiddenRequestButton()"
26+
[disabled]="!canRequest().can"
27+
[tooltipDisabled]="canRequest().can"
28+
[pTooltip]="tooltip()"
29+
tooltipPosition="top"
2630
>
2731
<i class="fa fa-cart-arrow-down ui:mr-2"></i>
28-
@if (recordType === 'item') {
29-
{{ 'Request' | translate }}
32+
@if (holdingsItemsCount > 0) {
33+
{{ 'Request another issue' | translate }}
3034
} @else {
31-
@if (holdingsItemsCount > 0) {
32-
{{ 'Request another issue' | translate }}
33-
} @else {
34-
{{ 'Request an issue' | translate }}
35-
}
35+
{{ 'Request an issue' | translate }}
3636
}
3737
</p-button>
3838
} @else {

0 commit comments

Comments
 (0)