diff --git a/projects/admin/src/app/circulation/checkin/checkin-action/checkin-action.component.html b/projects/admin/src/app/circulation/checkin/checkin-action/checkin-action.component.html index 447fb1c2d..55593f073 100644 --- a/projects/admin/src/app/circulation/checkin/checkin-action/checkin-action.component.html +++ b/projects/admin/src/app/circulation/checkin/checkin-action/checkin-action.component.html @@ -14,15 +14,14 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> -
-
+
One item and one patron were found. -
-
+
{ if (action) { @@ -316,7 +324,7 @@ export class CheckinComponent implements OnInit { private _checkinErrorManagement(error: any, item: Item) { // get the error message from the raised error. This will be the Toast message core. let message = (error.hasOwnProperty('error') && error.error.hasOwnProperty('status')) - ? error.error.status.replace(/^error:/, '').trim() + ? this.processErrorMessage(error.error.status) : error.message; message = this.translate.instant(message); message += `
${this.translate.instant('Status')}: ${this.translate.instant(item.status.toString())}`; @@ -372,6 +380,10 @@ export class CheckinComponent implements OnInit { } } + private processErrorMessage(message: string): string { + return message.replace(/^error:/, '').trim(); + } + /** Reset search input */ private _resetSearchInput(): void { setTimeout(() => { diff --git a/projects/admin/src/app/circulation/items-list/items-list.component.scss b/projects/admin/src/app/circulation/circulation-main.component.ts similarity index 52% rename from projects/admin/src/app/circulation/items-list/items-list.component.scss rename to projects/admin/src/app/circulation/circulation-main.component.ts index 8fc910644..b841f059f 100644 --- a/projects/admin/src/app/circulation/items-list/items-list.component.scss +++ b/projects/admin/src/app/circulation/circulation-main.component.ts @@ -1,7 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2022 RERO - * Copyright (C) 2022 UCLouvain + * Copyright (C) 2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -15,11 +14,24 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { Component } from '@angular/core'; -@import 'bootstrap/scss/functions'; -@import 'bootstrap/scss/variables'; - -.btn-show-more { - background-color: transparent !important; - color: $white; +@Component({ + selector: 'admin-circulation-main', + template: ` + + + +
+
+ {{ message.summary }} +
+

+
+
+
+ + ` +}) +export class CirculationMainComponent { } diff --git a/projects/admin/src/app/circulation/circulation-routing.module.ts b/projects/admin/src/app/circulation/circulation-routing.module.ts index c2de9654c..e0a76f98a 100644 --- a/projects/admin/src/app/circulation/circulation-routing.module.ts +++ b/projects/admin/src/app/circulation/circulation-routing.module.ts @@ -1,6 +1,6 @@ /* * RERO ILS UI - * Copyright (C) 2019-2023 RERO + * Copyright (C) 2019-2024 RERO * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -14,7 +14,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ - import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { PERMISSIONS } from '@rero/shared'; @@ -30,67 +29,76 @@ import { PendingComponent } from './patron/pending/pending.component'; import { PickupComponent } from './patron/pickup/pickup.component'; import { ProfileComponent } from './patron/profile/profile.component'; import { keepHistoryGuard } from './guard/keep-history.guard'; +import { CirculationMainComponent } from './circulation-main.component'; const routes: Routes = [ { path: '', - redirectTo: 'checkout', - pathMatch: 'full' - }, - { - path: 'patron/:barcode', - component: MainComponent, + component: CirculationMainComponent, children: [ { path: '', - redirectTo: 'loan', - pathMatch: 'full' - }, - { - path: 'loan', - component: LoanComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + redirectTo: 'checkout', + pathMatch: 'full', }, { - path: 'pickup', - component: PickupComponent, + path: 'checkout', + component: CheckinComponent, canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } }, { - path: 'pending', - component: PendingComponent, + path: 'requests', + component: MainRequestComponent, canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } }, { - path: 'ill', - component: IllRequestComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + path: 'patron/:barcode', + component: MainComponent, + children: [ + { + path: '', + redirectTo: 'loan', + pathMatch: 'full' + }, + { + path: 'loan', + component: LoanComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'pickup', + component: PickupComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'pending', + component: PendingComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'ill', + component: IllRequestComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'profile', + component: ProfileComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'fees', + component: PatronTransactionsComponent, + canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + }, + { + path: 'history', + component: HistoryComponent, + canActivate: [ keepHistoryGuard, PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } + } + ] }, - { - path: 'profile', - component: ProfileComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } - }, - { - path: 'fees', - component: PatronTransactionsComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } - }, - { - path: 'history', - component: HistoryComponent, - canActivate: [ keepHistoryGuard, PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } - } ] - }, { - path: 'checkout', - component: CheckinComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } - }, { - path: 'requests', - component: MainRequestComponent, - canActivate: [ PermissionGuard ], data: { permissions: [ PERMISSIONS.CIRC_ADMIN ] } - } + }, ]; @NgModule({ diff --git a/projects/admin/src/app/circulation/circulation.module.ts b/projects/admin/src/app/circulation/circulation.module.ts index 833bf3791..e7297304e 100644 --- a/projects/admin/src/app/circulation/circulation.module.ts +++ b/projects/admin/src/app/circulation/circulation.module.ts @@ -32,6 +32,7 @@ import { TagModule } from 'primeng/tag'; import { JournalVolumePipe } from 'projects/public-search/src/app/pipe/journal-volume.pipe'; import { CheckinActionComponent } from './checkin/checkin-action/checkin-action.component'; import { CheckinComponent } from './checkin/checkin.component'; +import { CirculationMainComponent } from './circulation-main.component'; import { CirculationRoutingModule } from './circulation-routing.module'; import { ItemComponent } from './item/item.component'; import { ItemsListComponent } from './items-list/items-list.component'; @@ -106,7 +107,8 @@ import { GetLoanCipoPipe } from './pipe/get-loan-cipo.pipe'; IllRequestComponent, IllRequestItemComponent, JournalVolumePipe, - CirculationSettingsComponent + CirculationSettingsComponent, + CirculationMainComponent ], imports: [ CirculationRoutingModule, @@ -125,7 +127,7 @@ import { GetLoanCipoPipe } from './pipe/get-loan-cipo.pipe'; MessagesModule, InputSwitchModule, SplitButtonModule - ], + ], providers: [ CurrencyPipe ] diff --git a/projects/admin/src/app/circulation/circulation.scss b/projects/admin/src/app/circulation/circulation.scss deleted file mode 100644 index 2e8057c8b..000000000 --- a/projects/admin/src/app/circulation/circulation.scss +++ /dev/null @@ -1,37 +0,0 @@ -/* - * RERO ILS UI - * Copyright (C) 2023-2024 RERO - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - - @import 'bootstrap/scss/functions'; - @import 'bootstrap/scss/variables'; - - .item { - margin-bottom: map-get($spacers, 1) !important; - padding: map-get($spacers, 1) !important; - border: $border-width solid $border-color; - border-radius: $border-radius; - position: relative; - - &:hover{ - background-color: $light; - } - - div.actions { - position: absolute; - top: map-get($spacers, 1); - right: 15px; - } - } diff --git a/projects/admin/src/app/circulation/item/item.component.html b/projects/admin/src/app/circulation/item/item.component.html index 3f520a4a4..0a4002359 100644 --- a/projects/admin/src/app/circulation/item/item.component.html +++ b/projects/admin/src/app/circulation/item/item.component.html @@ -16,32 +16,17 @@ along with this program. If not, see . --> @if (item && !(item.loading || false)) { -
- - -
- @if (patron) { - - } -
+
-
+
@if (!item.actions || item.loan || totalAmountOfFee || item.pending_loans || notifications$) { } -
+
{{ item.barcode }} @if (isCollapsed) { @@ -59,7 +44,7 @@ }
-
+ - -
- @if (item.loan) { - - } @else { - {{ item.status | translate }} - } -
- -
- @if (item.actionDone) { - @switch (item.actionDone) { - @case (itemAction.checkin) { - - checked in - } - @case (itemAction.checkout) { - - checked out - } - @case (itemAction.extend_loan) { - - renewed - } - @default { - {{ item.actionDone | translate }} - } - } - } -
- + @if (!isCollapsed) { -
-
-
Call number
-
+
+ +
+ } +
+ +
+ @if (item.loan) { +
    + @switch (item.status) { + @case ('on_loan') { +
  • + {{ item.status | translate }} + + + {{ item.loan.dueDate | dateTranslate :'shortDate' }} + +
  • + } + @case ('in_transit') { +
  • + {{ item.status | translate }} + @if (getTransitLocationPid() | getRecord: 'locations' | async; as location) { + ({{ 'to' | translate }} + @if (item.loan && item.loan.state === 'ITEM_IN_TRANSIT_FOR_PICKUP') { + {{ $any(location).metadata.pickup_name }} + } @else { + {{ $any(location).metadata.library.pid | getRecord: 'libraries' : 'field' : 'name' | async }} + }) + } +
  • + } + @case ('on_shelf') { +
  • {{ item.status | translate }}
  • + } + @case ('at_desk') { +
  • + {{ item.status | translate }} + @if (item.loan && item.loan.pickup_location) { + ({{ item.loan.pickup_location.pickup_name }}) + } + @if (!item.loan && item.pending_loans && item.pending_loans.length > 0 && item.pending_loans[0].pickup_location) { + ({{ item.pending_loans[0].pickup_location.pickup_name }}) + + } +
  • + } + @default { +
  • {{ item.status | translate }}
  • } } - - @if (canUseDebugMode) { - + +
  • + @if (isCollapsed && item.loan && item.loan.extension_count && (!item.actionDone || item.actionDone !== itemAction.checkin)) { + + {{ item.loan.extension_count }} + + } + @if (isCollapsed && totalAmountOfFee > 0) { + + {{ totalAmountOfFee | currency: organisation.default_currency }} + + } + @if (isCollapsed && item.pending_loans && item.pending_loans.length) { + + + + {{ item.pending_loans[0].patron.name }} + + + } +
  • +
+ } @else { + {{ item.status | translate }} + } +
+ +
+
+ @if (item.actionDone) { +
+ @switch (item.actionDone) { + @case (itemAction.checkin) { + + checked in + } + @case (itemAction.checkout) { + + checked out + } + @case (itemAction.extend_loan) { + + renewed + } + @default { + {{ item.actionDone | translate }} + } + } +
} + @if (patron) { +
+ +
+ } +
+ @if (canUseDebugMode && !isCollapsed) { +
+ + + +
+ } +
+ @if (debugMode && !isCollapsed) { +
+
 {{ 'Debug' | translate }}
+
+ @if (loan) { +
+
+

Loan

+
{{ loan | json }}
+
+
+
+ @if (loan | getLoanCipo | async; as cipo) { +
+

+ {{ 'Circulation policy' | translate }}  + + + +

+
{{ cipo | json }}
+
+ } +
+ } @else { +
+
+

Item

+
{{ item | json }}
+
+
+ } +
}
diff --git a/projects/admin/src/app/circulation/item/item.component.ts b/projects/admin/src/app/circulation/item/item.component.ts index f2bc990cb..1998972ba 100644 --- a/projects/admin/src/app/circulation/item/item.component.ts +++ b/projects/admin/src/app/circulation/item/item.component.ts @@ -30,8 +30,7 @@ import { map } from 'rxjs/operators'; @Component({ selector: 'admin-item', - templateUrl: './item.component.html', - styleUrls: ['../circulation.scss'] + templateUrl: './item.component.html' }) export class ItemComponent implements OnInit { diff --git a/projects/admin/src/app/circulation/items-list/items-list.component.html b/projects/admin/src/app/circulation/items-list/items-list.component.html index 6e58e63a3..ef7aad22a 100644 --- a/projects/admin/src/app/circulation/items-list/items-list.component.html +++ b/projects/admin/src/app/circulation/items-list/items-list.component.html @@ -21,44 +21,52 @@ } @if ((checkedOutItems && checkedOutItems.length > 0) || (checkedInItems && checkedInItems.length > 0)) { -
-
- - {{ 'Items' | translate }} -
-
Document
-
Circulation info
-
- @if (patron) { - + + + + +
+ + @for (item of checkedOutItems; track item) { + } -
-
- - @for (item of checkedOutItems; track item) { - - - } - - - - @for (item of checkedInItems; track item) { - - - } + + + @for (item of checkedInItems; track item) { + + } +
+ } diff --git a/projects/admin/src/app/circulation/items-list/items-list.component.ts b/projects/admin/src/app/circulation/items-list/items-list.component.ts index 6b90bcd1b..a755f7e98 100644 --- a/projects/admin/src/app/circulation/items-list/items-list.component.ts +++ b/projects/admin/src/app/circulation/items-list/items-list.component.ts @@ -21,7 +21,6 @@ import { ItemAction } from '../../classes/items'; @Component({ selector: 'admin-circulation-items-list', - styleUrls: ['./items-list.component.scss'], templateUrl: './items-list.component.html' }) export class ItemsListComponent implements OnInit{ diff --git a/projects/admin/src/app/circulation/main-request/main-request.component.html b/projects/admin/src/app/circulation/main-request/main-request.component.html index dd265ff9c..0c73d4620 100644 --- a/projects/admin/src/app/circulation/main-request/main-request.component.html +++ b/projects/admin/src/app/circulation/main-request/main-request.component.html @@ -25,30 +25,49 @@ />
-
- -
- - -
+
-
- - +
+
+ + +
+
+ @if (refreshInterval > 0) { + + +
+ +
{{ item.label }}
+
+
+ +
+ +
{{ item.label }}
+
+
+
+ + } + + + +
+ +
{{ item.label }}
+
+
+ +
+ +
{{ item.label }}
+
+
+
+
+
- @if (refreshInterval > 0) { - - } - -
@@ -56,7 +75,6 @@
diff --git a/projects/admin/src/app/circulation/main-request/main-request.component.ts b/projects/admin/src/app/circulation/main-request/main-request.component.ts index 433da8321..31d466297 100644 --- a/projects/admin/src/app/circulation/main-request/main-request.component.ts +++ b/projects/admin/src/app/circulation/main-request/main-request.component.ts @@ -38,24 +38,24 @@ export class MainRequestComponent implements OnInit, OnDestroy { // COMPONENT ATTRIBUTES ================================================================== /** options used for auto-refresh select box */ public refreshOptions = [ - {value: '15000', label: '15 s', icon: 'fa-clock-o'}, - {value: '30000', label: '30 s', icon: 'fa-clock-o'}, - {value: '60000', label: '1 m', icon: 'fa-clock-o'}, - {value: '300000', label: '5 m', icon: 'fa-clock-o'}, - {value: '600000', label: '10 m', icon: 'fa-clock-o'}, - {value: '3000000', label: '30 m', icon: 'fa-clock-o'} + {value: '15000', label: '15 s', icon: 'fa fa-clock-o'}, + {value: '30000', label: '30 s', icon: 'fa fa-clock-o'}, + {value: '60000', label: '1 m', icon: 'fa fa-clock-o'}, + {value: '300000', label: '5 m', icon: 'fa fa-clock-o'}, + {value: '600000', label: '10 m', icon: 'fa fa-clock-o'}, + {value: '3000000', label: '30 m', icon: 'fa fa-clock-o'} ]; /** options used to sort requested items list */ public sortingCriteria = [ - {value: 'requestdate', label: this.translateService.instant('Request date'), icon: 'fa-sort-numeric-asc'}, - {value: '-requestdate', label: this.translateService.instant('Request date (desc)'), icon: 'fa-sort-numeric-desc'}, - {value: 'callnumber', label: this.translateService.instant('Call number'), icon: 'fa-sort-alpha-asc'}, - {value: '-callnumber', label: this.translateService.instant('Call number (desc)'), icon: 'fa-sort-alpha-desc'}, - {value: 'location', label: this.translateService.instant('Location'), icon: 'fa-sort-alpha-asc'}, - {value: '-location', label: this.translateService.instant('Location (desc)'), icon: 'fa-sort-alpha-desc'}, - {value: 'pickuplocation', label: this.translateService.instant('Pick-up location'), icon: 'fa-sort-alpha-asc'}, - {value: '-pickuplocation', label: this.translateService.instant('Pick-up location (desc)'), icon: 'fa-sort-alpha-desc'}, + {value: 'requestdate', label: this.translateService.instant('Request date'), icon: 'fa fa-sort-numeric-asc'}, + {value: '-requestdate', label: this.translateService.instant('Request date (desc)'), icon: 'fa fa-sort-numeric-desc'}, + {value: 'callnumber', label: this.translateService.instant('Call number'), icon: 'fa fa-sort-alpha-asc'}, + {value: '-callnumber', label: this.translateService.instant('Call number (desc)'), icon: 'fa fa-sort-alpha-desc'}, + {value: 'location', label: this.translateService.instant('Location'), icon: 'fa fa-sort-alpha-asc'}, + {value: '-location', label: this.translateService.instant('Location (desc)'), icon: 'fa fa-sort-alpha-desc'}, + {value: 'pickuplocation', label: this.translateService.instant('Pick-up location'), icon: 'fa fa-sort-alpha-asc'}, + {value: '-pickuplocation', label: this.translateService.instant('Pick-up location (desc)'), icon: 'fa fa-sort-alpha-desc'}, ]; /** the placeholder string used on the */ @@ -66,8 +66,6 @@ export class MainRequestComponent implements OnInit, OnDestroy { public items = null; /** the interval (in millis) between 2 calls of requested items (0 = no refresh) */ public refreshInterval = 0; - /** is the requested items detail should be collapsed or not */ - public isDetailCollapsed = true; /** Focus attribute of the search input */ public searchInputFocus = true; /** Disabled attribute of the search input */ diff --git a/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.html b/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.html index 1ee714091..fcc86c679 100644 --- a/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.html +++ b/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.html @@ -15,24 +15,14 @@ along with this program. If not, see . --> @if (document) { -
-
- @if (item.loan.state === LoanState.PENDING) { - - } -
- +
-
+
@if (document.title | mainTitle; as title) { {{ title }} @@ -40,49 +30,57 @@ }
-
+
-
{{ item.loan.creation_date | dateTranslate :'medium' }}
- - @if (!isCollapsed) { -
-
- - @if (item.enumerationAndChronology) { -
Unit
-
{{ item.enumerationAndChronology }}
- } - -
Requested by
-
- - {{ item.loan.patron.name }} - -
- -
Location
-
- {{ item.library.name }} - - @if (item.temporary_location?.name) { - {{ item.temporary_location.name }} - } @else { - {{ item.location.name }} - } +
{{ item.loan.creation_date | dateTranslate :'medium' }}
+
+ @if (item.loan.state === LoanState.PENDING) { + + } +
+ @if (!isCollapsed) { + -
- } + +
Pick-up location
+
+ + + @if (item.loan.pickup_location.pickup_name) { + {{ item.loan.pickup_location.pickup_name }} + } @else { + {{ item.loan.pickup_location.library_name }}: {{ item.loan.pickup_location.name }} + } +
+ + }
} diff --git a/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.ts b/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.ts index 1cac3d87b..b7cc3e234 100644 --- a/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.ts +++ b/projects/admin/src/app/circulation/main-request/requested-item/requested-item.component.ts @@ -67,7 +67,6 @@ export class RequestedItemComponent implements OnInit { getCallout() { return (this.callout !== null) ? `callout ${this.callout}` - : 'border rounded'; + : null; } - } diff --git a/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.html b/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.html index 5eaee360f..01d65f304 100644 --- a/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.html +++ b/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.html @@ -14,25 +14,42 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> +@defer (when items) { + + + + + @if (items.length > 0) { +
+ @for (item of items; track item) { + + } +
+ } @else { +
+ {{ 'no request to validate' | translate }} +
} - } @else { - {{ 'no request to validate' | translate }} - } +
+} @placeholder { +
Loading in progress
} diff --git a/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.ts b/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.ts index c0bc2cb0e..e31dd851c 100644 --- a/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.ts +++ b/projects/admin/src/app/circulation/main-request/requested-items-list/requested-items-list.component.ts @@ -28,11 +28,12 @@ export class RequestedItemsListComponent implements OnChanges { // COMPONENT ATTRIBUTES ==================================================== /** Item list */ @Input() items: any[]; - /** Is the item detail should be collapsed */ - @Input() isCollapsed: boolean; + /** event emit when a request is validated */ @Output() requestValidated = new EventEmitter(); + /** Is the item detail should be collapsed */ + isCollapsed: boolean = true; /** the know item barcode list */ private knownItemBarcodes: Array = null; @@ -68,5 +69,4 @@ export class RequestedItemsListComponent implements OnChanges { validateRequest(itemBarcode: string) { this.requestValidated.emit(itemBarcode); } - } diff --git a/projects/admin/src/app/circulation/patron/cancel-request-button.component.ts b/projects/admin/src/app/circulation/patron/cancel-request-button.component.ts index 35061e00c..ada05bbd7 100644 --- a/projects/admin/src/app/circulation/patron/cancel-request-button.component.ts +++ b/projects/admin/src/app/circulation/patron/cancel-request-button.component.ts @@ -24,22 +24,17 @@ import { MessageService } from 'primeng/api'; @Component({ selector: 'admin-cancel-request-button', template: ` - @if (canCancelRequest()) { - } @else { - - } ` }) export class CancelRequestButtonComponent { diff --git a/projects/admin/src/app/circulation/patron/card/card.component.html b/projects/admin/src/app/circulation/patron/card/card.component.html index 5f66fdb1b..fbc2e9d2d 100644 --- a/projects/admin/src/app/circulation/patron/card/card.component.html +++ b/projects/admin/src/app/circulation/patron/card/card.component.html @@ -15,11 +15,11 @@ along with this program. If not, see . --> @if (patron?.patron) { -
+
-
+
-
+
@@ -63,10 +63,10 @@

@if (patron.notes) { -
    +
      @for (note of patron.notes; track note) {
    • - {{ note.type | translate | ucfirst }} + {{ note.type | translate | ucfirst }}

    • } @@ -75,7 +75,7 @@

      }

-
+
@if (displayCirculationMessages) { @if (patron.circulation_information) { @@ -88,14 +88,12 @@

/> } } - @for (message of circulationMessages; track message) { - - } + }

diff --git a/projects/admin/src/app/circulation/patron/card/card.component.ts b/projects/admin/src/app/circulation/patron/card/card.component.ts index a0ee6920d..f08a6ab40 100644 --- a/projects/admin/src/app/circulation/patron/card/card.component.ts +++ b/projects/admin/src/app/circulation/patron/card/card.component.ts @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import { Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core'; import { DateTime } from 'luxon'; import { getSeverity } from '../../../utils/utils'; import { CirculationService } from '../../services/circulation.service'; @@ -24,7 +24,7 @@ import { CirculationService } from '../../services/circulation.service'; templateUrl: './card.component.html', styleUrls: ['./card.component.scss'] }) -export class CardComponent { +export class CardComponent implements OnInit { private circulationService: CirculationService = inject(CirculationService); @@ -42,40 +42,38 @@ export class CardComponent { /** event emitter when the close button are fired */ @Output() clearPatron = new EventEmitter(); - // GETTER & SETTER ========================================================== - /** Build the link used on the patron name */ - get patronLink(): string { + /** Link used on the patron name */ + patronLink: string; + /** it's the birthday of the patron */ + isBirthday: boolean = false; + /** Patron age */ + patronAge: number; + /** circulation messages about the loaded patron if exists */ + circulationMessages: {severity: string, detail: string}[] = []; + + ngOnInit(): void { if (this.patron) { - return (this.linkMode === 'detail') + this.patronLink = (this.linkMode === 'detail') ? '/records/patrons/detail/' + this.patron.pid : '/circulation/patron/' + this.barcode + '/loan'; } - } - /** Get the patron age */ - get patronAge(): number { if (this.patron && this.patron.birth_date) { - const birthDate = DateTime.fromISO(this.patron.birth_date); - return Math.floor(DateTime.now().diff(birthDate, 'years').years); + const today = DateTime.now().toFormat('M-dd'); + const birthDate = DateTime.fromISO(this.patron.birth_date).toFormat('M-dd'); + if (today === birthDate) { + this.isBirthday = true; + } } - } - /** Defined if it's the birthday of the patron */ - get isBirthday(): boolean { if (this.patron && this.patron.birth_date) { - const today = DateTime.fromISO(DateTime.now().toFormat('yyyy-M-d')); const birthDate = DateTime.fromISO(this.patron.birth_date); - return today.diff(birthDate, 'years').years % 1 === 0; + this.patronAge = Math.floor(DateTime.now().diff(birthDate, 'years').years); } - return false; - } - /** Get the circulation messages about the loaded patron if exists */ - get circulationMessages(): Array<{type: string, content: string}> { - return this.circulationService.messages(); + this.circulationMessages = this.circulationService.messages(); } - // COMPONENT FUNCTIONS ====================================================== /** Clear current patron */ clear(): void { if (this.patron) { @@ -91,5 +89,4 @@ export class CardComponent { getMessageSeverity(level: string): string { return getSeverity(level); } - } diff --git a/projects/admin/src/app/circulation/patron/change-password-form/change-password-form.component.html b/projects/admin/src/app/circulation/patron/change-password-form/change-password-form.component.html index 8e105c0bf..1063b7435 100644 --- a/projects/admin/src/app/circulation/patron/change-password-form/change-password-form.component.html +++ b/projects/admin/src/app/circulation/patron/change-password-form/change-password-form.component.html @@ -17,7 +17,7 @@ @if (form) {
-
+
. --> -
+
-
+
{{ record.metadata.document.title }} @@ -39,35 +39,35 @@
@if (!isCollapsed) { -
-
+
+ diff --git a/projects/admin/src/app/circulation/patron/ill-request/ill-request-item/ill-request-item.component.ts b/projects/admin/src/app/circulation/patron/ill-request/ill-request-item/ill-request-item.component.ts index effe50a4f..42d9d33a2 100644 --- a/projects/admin/src/app/circulation/patron/ill-request/ill-request-item/ill-request-item.component.ts +++ b/projects/admin/src/app/circulation/patron/ill-request/ill-request-item/ill-request-item.component.ts @@ -20,8 +20,7 @@ import { getTagSeverityFromStatus } from '@app/admin/utils/utils'; @Component({ selector: 'admin-ill-request-item', - templateUrl: './ill-request-item.component.html', - styleUrls: ['../../../circulation.scss'] + templateUrl: './ill-request-item.component.html' }) export class IllRequestItemComponent { diff --git a/projects/admin/src/app/circulation/patron/ill-request/ill-request.component.html b/projects/admin/src/app/circulation/patron/ill-request/ill-request.component.html index 1b0c09676..0aac66949 100644 --- a/projects/admin/src/app/circulation/patron/ill-request/ill-request.component.html +++ b/projects/admin/src/app/circulation/patron/ill-request/ill-request.component.html @@ -14,10 +14,10 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> +
Document
Pickup location
@@ -33,3 +33,34 @@ } } +--> + + +@if(illRequests$ | async; as illRequests) { + + + + + @if (illRequests.length > 0) { +
+ @for (record of illRequests; track record) { + + } +
+ } @else { +
+ No ill request. +
+ } +
+} @else { +
Loading in progress
+} diff --git a/projects/admin/src/app/circulation/patron/loan/circulation-settings/circulation-settings.component.ts b/projects/admin/src/app/circulation/patron/loan/circulation-settings/circulation-settings.component.ts index a267a1731..7b7794923 100644 --- a/projects/admin/src/app/circulation/patron/loan/circulation-settings/circulation-settings.component.ts +++ b/projects/admin/src/app/circulation/patron/loan/circulation-settings/circulation-settings.component.ts @@ -64,7 +64,6 @@ export class CirculationSettingsComponent implements OnInit { this.dialogRef = this.dialogService.open(FixedDateFormComponent, { header: this.translateService.instant('Choose a due date'), width: '30vw', - height: '600px' }); this.dialogRef.onClose.subscribe((result?: any) => { if (result && 'action' in result && result.action === 'submit') { diff --git a/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.html b/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.html index 49c5a129c..f77315d85 100644 --- a/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.html +++ b/projects/admin/src/app/circulation/patron/loan/fixed-date-form/fixed-date-form.component.html @@ -16,49 +16,53 @@ along with this program. If not, see . --> -
+
- @if (formGroup.controls.endDate.valid || !formGroup.controls.endDate.touched) { - - - {{ 'This date will override the circulation policy behavior' | translate }} - - } - @if (formGroup.controls.endDate.touched && formGroup.controls.endDate.hasError('required')) { - - - } - @if (formGroup.controls.endDate.touched && formGroup.controls.endDate.hasError('minimum-date')) { - - - } +
+ @if (formGroup.controls.endDate.valid || !formGroup.controls.endDate.touched) { + + + {{ 'This date will override the circulation policy behavior' | translate }} + + } + @if (formGroup.controls.endDate.touched && formGroup.controls.endDate.hasError('required')) { + + + } + @if (formGroup.controls.endDate.touched && formGroup.controls.endDate.hasError('minimum-date')) { + + + } +
+
+ + +
-
- - -
- {{ formGroup.controls.endDate['errorMessages'] | json }} -
+ } - @if ($any(patron).second_address) { -
-
Second address
- - @if ($any(patron).second_address.street) { -
-
Street
-
- {{ $any(patron).second_address.street }} -
-
- } - - @if ($any(patron).second_address.postal_code || $any(patron).second_address.city) { -
-
City
-
- @if ($any(patron).second_address.postal_code) { - {{ $any(patron).second_address.postal_code }} - } - @if ($any(patron).second_address.city) { - {{ $any(patron).second_address.city }} - } -
-
- } - - @if ($any(patron).second_address.country) { -
-
Country
-
- {{ 'country_' + $any(patron).second_address.country | translate }} -
-
+ @if ($any(patron).isLibrarian) { +

Librarian Information

+ + } + @if ($any(patron).patron) { +

Patron Information

+
- } - - @if ($any(patron).isLibrarian) { -
-
Librarian Information
- -
-
- Library -
-
- {{ $any(patron).library.pid | getRecord: 'libraries' : 'field' : 'name' | async }} -
-
-
- } - @if ($any(patron).patron) { -
-
Patron Information
- -
-
- - Role - Role - Roles - -
-
- @for (role of $any(patron).roles; track role; let last=$last) { - {{ role | translate }}{{ last ? '' : ', ' }} +
+
Patron's barcodes or cards number
+
+ + {{ $any(patron).patron.barcode | join: ', '}} + +
+
Type
+
+ {{ $any(patron).patron.type.pid | getRecord: 'patron_types' : 'field' : 'name' | async }} +
+
Account expiration
+
+ {{ $any(patron).patron.expiration_date | dateTranslate:'mediumDate' }} +
+ @if ($any(patron).libraries && $any(patron).libraries.length > 0) { +
Affiliation libraries
+
+
    + @for (library of $any(patron).libraries; track library) { +
  • {{ library.pid | getRecord: 'libraries' : 'field' : 'name' | async }}
  • } -
-
- -
-
Patron's barcodes or cards number
-
- - {{ $any(patron).patron.barcode | join: ', '}} - -
-
- -
-
Type
-
- {{ $any(patron).patron.type.pid | getRecord: 'patron_types' : 'field' : 'name' | async }} -
-
- -
-
Account expiration
-
- {{ $any(patron).patron.expiration_date | dateTranslate:'mediumDate' }} -
-
- @if ($any(patron).libraries && $any(patron).libraries.length > 0) { -
-
Affiliation libraries
-
-
    - @for (library of $any(patron).libraries; track library) { -
  • {{ library.pid | getRecord: 'libraries' : 'field' : 'name' | async }}
  • - } -
-
-
- } -
- } + + + } + + } - @if (canUpdate()) { + @if (canUpdate()) { +
+ - } - - +
+ } +} @placeholder { +
Loading in progress
} diff --git a/projects/admin/src/app/circulation/patron/profile/profile.component.ts b/projects/admin/src/app/circulation/patron/profile/profile.component.ts index 7f035d573..565b4eb4f 100644 --- a/projects/admin/src/app/circulation/patron/profile/profile.component.ts +++ b/projects/admin/src/app/circulation/patron/profile/profile.component.ts @@ -34,7 +34,7 @@ export class ProfileComponent implements OnInit, OnDestroy { private translateService: TranslateService = inject(TranslateService); /** Current patron */ - currentPatron$: any; + patron: any; /** Observable subscription */ private subscription = new Subscription(); @@ -42,12 +42,9 @@ export class ProfileComponent implements OnInit, OnDestroy { /** Patron permission */ private permissions: any; - /** - * Component initialization. - */ ngOnInit() { - this.currentPatron$ = this.patronService.currentPatron$; - this.subscription = this.currentPatron$.subscribe((patron: any) => { + this.subscription = this.patronService.currentPatron$.subscribe((patron: any) => { + this.patron = patron; if (patron && patron.pid) { this.recordPermission.getPermission('patrons', patron.pid).subscribe( perm => { diff --git a/projects/admin/src/app/circulation/services/circulation.service.ts b/projects/admin/src/app/circulation/services/circulation.service.ts index 7d9653f86..d8325c43b 100644 --- a/projects/admin/src/app/circulation/services/circulation.service.ts +++ b/projects/admin/src/app/circulation/services/circulation.service.ts @@ -21,7 +21,7 @@ import { Injectable, signal, WritableSignal } from '@angular/core'; }) export class CirculationService { - messages: WritableSignal<{type: string, content: string}[]> = signal([]); + messages: WritableSignal<{severity: string, detail: string}[]> = signal([]); statistics: WritableSignal<{[key: string]: number}> = signal({}); statisticsIncrease(type: string, increment: number = 1): void { @@ -45,7 +45,7 @@ export class CirculationService { this.statistics.set(stats); } - addCirculationMessage(message: {type: string, content: string}): void { + addCirculationMessage(message: {severity: string, detail: string}): void { this.messages.set([...this.messages(), message]); } diff --git a/projects/admin/src/app/record/detail-view/document-detail-view/item-request/item-request.component.ts b/projects/admin/src/app/record/detail-view/document-detail-view/item-request/item-request.component.ts index a4031a085..8d9d8f596 100644 --- a/projects/admin/src/app/record/detail-view/document-detail-view/item-request/item-request.component.ts +++ b/projects/admin/src/app/record/detail-view/document-detail-view/item-request/item-request.component.ts @@ -212,6 +212,7 @@ export class ItemRequestComponent implements OnInit { key: 'pickupPid', type: 'select', props: { + appendTo: 'body', label: this.translateService.instant('Pickup location'), required: true, placeholder: this.translateService.instant('Select…'), diff --git a/projects/admin/src/app/scss/styles.scss b/projects/admin/src/app/scss/styles.scss index c4c9e1c0b..7fee98ef2 100644 --- a/projects/admin/src/app/scss/styles.scss +++ b/projects/admin/src/app/scss/styles.scss @@ -52,3 +52,7 @@ background: transparent; } } + +ng-core-editor-field-password-generator { + @extend .w-full; +} diff --git a/projects/admin/src/app/service/loan.service.ts b/projects/admin/src/app/service/loan.service.ts index 8993720f1..8d3899537 100644 --- a/projects/admin/src/app/service/loan.service.ts +++ b/projects/admin/src/app/service/loan.service.ts @@ -152,11 +152,11 @@ export class LoanService { cancelRequestDialog(event: Event, accept?: Function, reject?: Function): void { const confirmation: Confirmation = { target: event.target as EventTarget, + icon: 'fa fa-exclamation-triangle', header: this.translateService.instant('Cancel request'), message: this.translateService.instant('Do you really want to cancel the request?'), acceptLabel: this.translateService.instant('Yes'), - rejectLabel: this.translateService.instant('No'), - dismissableMask: true, + rejectLabel: this.translateService.instant('No') }; if (accept) { confirmation.accept = accept; diff --git a/projects/shared/src/scss/styles.scss b/projects/shared/src/scss/styles.scss index ff7fd8a88..e73232ad2 100644 --- a/projects/shared/src/scss/styles.scss +++ b/projects/shared/src/scss/styles.scss @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +@import "node_modules/@rero/ng-core/assets/scss/variables"; @import "node_modules/@rero/ng-core/assets/scss/ng-core"; @import "../lib/component/documents/files/files.component.scss"; @import "../lib/view/contribution/contribution.component.scss";