Skip to content

Commit 66f630b

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 0852b4c commit 66f630b

File tree

6 files changed

+56
-26
lines changed

6 files changed

+56
-26
lines changed

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/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: 20 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]="!shouldDisplay()"
3333
[disabled]="!canRequest().can"
3434
[tooltipDisabled]="canRequest().can"
3535
[pTooltip]="tooltip()"
@@ -52,9 +52,25 @@ 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+
const reasons = this.canRequest().reasons;
64+
return reasons && Object.keys(reasons).every(key => this.reasonsToDisplay.includes(key));
65+
});
66+
67+
shouldDisplay = computed(() => {
68+
return this.canRequest().can || this.allReasonsDisplayable();
69+
});
70+
71+
tooltip = computed(() => Object.values(this.canRequest().reasons || {}).map(
72+
(reason: string) => "- " + this.translateService.instant(reason)
73+
).join('\n'));
5874

5975
private _patron: IPatron;
6076

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]="!shouldDisplay()"
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 {

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,27 @@
1414
* You should have received a copy of the GNU Affero General Public License
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
17-
import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core';
17+
import { Component, EventEmitter, inject, Input, OnInit, Output, signal, computed } from '@angular/core';
1818
import { IPatron, UserService, SharedModule } from '@rero/shared';
1919
import { ItemApiService } from '../../api/item-api.service';
2020
import { HoldingsApiService } from '../../api/holdings-api.service';
2121
import { Button } from 'primeng/button';
2222
import { Tooltip } from 'primeng/tooltip';
2323
import { PickupLocationComponent } from './pickup-location/pickup-location.component';
24-
import { TranslatePipe } from '@ngx-translate/core';
24+
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
25+
import { canRequest } from '../model/can-request-model';
2526

2627
@Component({
2728
selector: 'public-search-request',
28-
templateUrl: './request.component.html',
29+
templateUrl: './holdings-request.component.html',
2930
imports: [Button, Tooltip, PickupLocationComponent, TranslatePipe, SharedModule]
3031
})
31-
export class RequestComponent implements OnInit {
32+
export class HoldingsRequestComponent implements OnInit {
3233

3334
private itemApiService: ItemApiService = inject(ItemApiService);
3435
private holdingsApiService: HoldingsApiService = inject(HoldingsApiService);
3536
private userService: UserService = inject(UserService);
37+
private translateService: TranslateService = inject(TranslateService);
3638

3739
/** Record: item or holding */
3840
@Input() record: any;
@@ -47,10 +49,22 @@ export class RequestComponent implements OnInit {
4749
@Input() holdingsItemsCount: number;
4850

4951
/** Item Can request with reason(s) */
50-
canRequest = {
51-
can: false,
52-
reasons: []
53-
};
52+
canRequest = signal<canRequest>({ can: false, reasons: {} });
53+
54+
reasonsToDisplay = ["patron_type_overdue_items_limit", "patron_type_fee_amount_limit", "patron_type_unpaid_subscription", "patron_type_request_limits"]
55+
56+
allReasonsDisplayable = computed(() => {
57+
const reasons = this.canRequest().reasons;
58+
return reasons && Object.keys(reasons).every(key => this.reasonsToDisplay.includes(key));
59+
});
60+
61+
shouldDisplay = computed(() => {
62+
return this.canRequest().can || this.allReasonsDisplayable();
63+
});
64+
65+
tooltip = computed(() => Object.values(this.canRequest().reasons || {}).map(
66+
(reason: string) => "- " + this.translateService.instant(reason)
67+
).join('\n'));
5468

5569
/** Request dialog */
5670
requestDialog = false;
@@ -84,7 +98,7 @@ export class RequestComponent implements OnInit {
8498
this.record.metadata.pid,
8599
this.record.metadata.library.pid,
86100
this._patron.patron.barcode[0],
87-
).subscribe((can: any) => this.canRequest = can);
101+
).subscribe((can: canRequest) => this.canRequest.set(can));
88102
}
89103
}
90104
}

0 commit comments

Comments
 (0)