LP2000482 Angular 15 and Bootstrap 5 upgrade
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / booking / create-reservation.component.html
1 <eg-staff-banner bannerText="Create Reservation" i18n-bannerText>
2 </eg-staff-banner>
3 <eg-title i18n-prefix i18n-suffix prefix="Booking" suffix="Create Reservation"></eg-title>
4 <form [formGroup]="criteria" class="row">
5   <div class="col-sm-6">
6     <div class="row">
7       <div class="col">
8         <div class="input-group">
9           <label class="form-label input-group-text" for="ideal-reservation-type" i18n>Reservation type</label>
10           <select class="form-select" id="ideal-reservation-type" formControlName="reservationType">
11             <option *ngFor="let type of reservationTypes" [ngValue]="type" i18n>{{type.name}}</option>
12           </select>
13         </div>
14       </div>
15       <div class="col">
16         <div class="input-group">
17           <label class="form-label input-group-text" for="ideal-reservation-date" i18n>Reservation date</label>
18           <eg-date-select *ngIf="!multiday" #dateLimiter domId="ideal-reservation-date" formControlName="idealDate"></eg-date-select>
19           <eg-daterange-select *ngIf="multiday" formControlName="idealDateRange"></eg-daterange-select>
20         </div>
21       </div>
22     </div>
23   </div>
24   <div class="card col-sm-6">
25     <h2 class="card-header" i18n>Reservation details</h2>
26     <ul ngbNav #details="ngbNav" [(activeId)]="detailsTab" [keyboard]="true" [roles]="false" role="tablist" class="nav-tabs">
27       <li role="presentation" [ngbNavItem]="'select-resource-type'">
28         <a ngbNavLink role="tab">
29           <span class="material-icons">dns</span>
30           <ng-container i18n>Choose resource by type</ng-container>
31         </a>
32         <ng-template ngbNavContent>
33           <div ngbPanelContent class="row">
34             <div class="col">
35               <div class="input-group">
36                 <label class="form-label input-group-text" for="ideal-resource-type" i18n>Search by resource type</label>
37                 <eg-combobox
38                   formControlName="resourceType"
39                   domId="ideal-resource-type"
40                   idlClass="brt"
41                   [asyncSupportsEmptyTermClick]="true">
42                 </eg-combobox>
43               </div>
44               <div class="col">
45                 <eg-org-family-select [hideAncestorSelector]="true" labelText="Owning library" i18n-labelText formControlName="owningLibrary">
46                 </eg-org-family-select>
47               </div>
48             </div>
49           </div>
50         </ng-template>
51       </li>
52
53       <li role="presentation" [ngbNavItem]="'select-resource'">
54         <a ngbNavLink role="tab">
55           <span class="material-icons">assignment</span>
56           <ng-container i18n>Choose resource by barcode</ng-container>
57         </a>
58         <ng-template ngbNavContent>
59           <div ngbPanelContent class="row">
60             <div class="col">
61               <div class="input-group">
62                 <label class="form-label input-group-text" for="ideal-resource-barcode" i18n>Search by resource barcode</label>
63                 <input type="text" id="ideal-resource-barcode" class="form-control" formControlName="resourceBarcode">
64               </div>
65             </div>
66           </div>
67         </ng-template>
68       </li>
69
70       <li role="presentation" [ngbNavItem]="'attributes'" [disabled]="0 === attributes.length">
71         <a ngbNavLink role="tab">
72           <span class="material-icons">filter_list</span>
73           <ng-container i18n>Limit by attributes</ng-container>
74         </a>
75         <ng-template ngbNavContent>
76           <ul class="list-group list-group-flush" formArrayName="selectedAttributes">
77             <li *ngFor="let attribute of attributes; let i = index" class="list-group-item">
78               <span class="input-group">
79                 <label class="form-label input-group-text" for="attribute-{{attribute.id()}}" i18n>{{attribute.name()}}</label>
80                 <eg-combobox [formControlName]="i">
81                   <eg-combobox-entry *ngFor="let value of attribute.valid_values()"
82                     [entryId]="value.id()" [entryLabel]="value.valid_value()">
83                   </eg-combobox-entry>
84                 </eg-combobox>
85               </span>
86             </li>
87           </ul>
88         </ng-template>
89       </li>
90
91       <li role="presentation" [ngbNavItem]="'display-settings'">
92         <a ngbNavLink role="tab">
93           <span class="material-icons">settings</span>
94           <ng-container i18n>Schedule settings</ng-container>
95         </a>
96         <ng-template ngbNavContent>
97           <ul class="list-group list-group-flush">
98             <li class="list-group-item">
99               <span class="input-group">
100                   <label class="form-label input-group-text" for="start-time" i18n>Start time</label>
101                 <ngb-timepicker formControlName="startOfDay" [minuteStep]="minuteStep()" [meridian]="true"></ngb-timepicker>
102               </span>
103             </li>
104             <li class="list-group-item">
105               <span class="input-group">
106                   <label class="form-label input-group-text" for="end-time" i18n>End time</label>
107                 <ngb-timepicker formControlName="endOfDay" [minuteStep]="minuteStep()" [meridian]="true"></ngb-timepicker>
108               </span>
109             </li>
110             <li *ngIf="criteria.errors && criteria.errors.startOfDayNotBeforeEndOfDay" class="list-group-item">
111               <div role="alert" class="alert alert-danger">
112                 <span class="material-icons" aria-hidden="true">error</span>
113                 <span i18n>Start time must be before end time</span>
114               </div>
115             </li>
116             <li class="list-group-item">
117               <span class="input-group">
118                   <label class="form-label input-group-text" for="granularity" i18n>Granularity</label>
119                 <eg-combobox (onChange)="changeGranularity($event)" [startId]="granularity ? granularity : 30">
120                   <eg-combobox-entry [entryId]="15" entryLabel="15 minutes"
121                     i18n-entryLabel></eg-combobox-entry>
122                   <eg-combobox-entry [entryId]="30" entryLabel="30 minutes"
123                     i18n-entryLabel></eg-combobox-entry>
124                   <eg-combobox-entry [entryId]="60" entryLabel="60 minutes"
125                     i18n-entryLabel></eg-combobox-entry>
126                 </eg-combobox>
127               </span>
128             </li>
129           </ul>
130         </ng-template>
131       </li>
132     </ul>
133
134     <div [ngbNavOutlet]="details" class="mt-2"></div>
135   </div>
136 </form>
137
138 <ng-container *ngIf="resources.length">
139   <hr>
140   <div class="row" *ngIf="idealDate && !multiday">
141     <button class="btn btn-info col-sm-2 offset-sm-3" (click)="addDays(-1)">
142         <span class="material-icons mat-icon-in-button">keyboard_arrow_left</span>
143         <span i18n>Previous day</span>
144     </button>
145     <h2 class="col-sm-2 text-center" i18n>{{idealDate | formatValue:'timestamp'}}</h2>
146     <button class="btn btn-info col-sm-2" (click)="addDays(1)">
147       <span i18n>Next day</span>
148       <span class="material-icons mat-icon-in-button">keyboard_arrow_right</span>
149     </button>
150   </div>
151   <eg-grid #scheduleGrid
152     [cellTextGenerator]="cellTextGenerator"
153     [sortable]="false"
154     (onRowActivate)="openTheDialog([$event])"
155     [dataSource]="scheduleSource"
156     [rowFlairIsEnabled]="true"
157     [rowFlairCallback]="resourceAvailabilityIcon"
158     [disablePaging]="true"
159     persistKey="disabled">
160     <eg-grid-toolbar-button label="Create Reservation" i18n-label (onClick)="openTheDialog($event)"></eg-grid-toolbar-button>
161     <eg-grid-toolbar-action label="Create Reservation" i18n-label (onClick)="openTheDialog($event)"></eg-grid-toolbar-action>
162     <eg-grid-column path="time" [index]="true" name="Time" i18n-name [cellTemplate]="timeTemplate" ></eg-grid-column>
163     <eg-grid-column *ngFor="let resource of resources" path="{{resource.barcode()}}" [cellTemplate]="reservationsTemplate" [name]="resource.barcode()" [disableTooltip]="true"></eg-grid-column>
164   </eg-grid>
165 </ng-container>
166 <div class="text-sm-center" *ngIf="this.resourceType.value && !resources.length" i18n>
167   There are no bookable resource that match your criteria.
168   Would you like to create <a [routerLink]="['/staff', 'admin', 'booking', 'splash']">some new resources</a>?
169 </div>
170
171 <eg-create-reservation-dialog #createDialog
172   (reservationRequestCompleted)="fetchData()"
173   [patronId]="patronId"
174   [targetResourceBarcode]="resourceBarcode"
175   [targetResource]="resourceId"
176   [targetResourceType]="resourceType.value"
177   [attributes]="flattenedSelectedAttributes"
178   [resources]="resources">
179 </eg-create-reservation-dialog>
180
181 <ng-template #reservationsTemplate let-row="row" let-col="col">
182   <ng-container *ngIf="row.patrons && row.patrons[col.name]">
183     <ul class="list-unstyled">
184       <li *ngFor="let reservation of row.patrons[col.name]">
185         <button class="btn btn-info" (click)="openReservationViewer(reservation['reservationId'])">
186           {{reservation['patronLabel']}}
187         </button>
188       </li>
189     </ul>
190   </ng-container>
191 </ng-template>
192 <ng-template #timeTemplate let-row="row" let-col="col">
193   <ng-container *ngIf="!multiday">
194     {{row['time'].format('LT')}}
195   </ng-container>
196   <ng-container *ngIf="multiday">
197     {{row['time'] | formatValue:'timestamp'}}
198   </ng-container>
199 </ng-template>
200 <eg-fm-record-editor #viewReservation
201   idlClass="bresv"
202   datetimeFields="start_time,end_time"
203   hiddenFields="xact_start,xact_finish,cancel_time,booking_interval">
204 </eg-fm-record-editor>
205 <eg-no-timezone-set-dialog #noTimezoneSetDialog>
206 </eg-no-timezone-set-dialog>