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