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