1 <eg-staff-banner bannerText="Create Reservation" i18n-bannerText>
3 <eg-title i18n-prefix i18n-suffix prefix="Booking" suffix="Create Reservation"></eg-title>
4 <form [formGroup]="criteria" class="row">
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>
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>
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" aria-hidden="true">dns</span>
30 <ng-container i18n>Choose resource by type</ng-container>
32 <ng-template ngbNavContent>
33 <div ngbPanelContent class="row">
35 <div class="input-group">
36 <label class="form-label input-group-text" for="ideal-resource-type" i18n>Search by resource type</label>
38 formControlName="resourceType"
39 domId="ideal-resource-type"
41 [asyncSupportsEmptyTermClick]="true">
45 <div class="input-group">
46 <label class="form-label input-group-text" for="owningLibrary" i18n>Owning library</label>
48 [hideAncestorSelector]="true"
50 ariaLabel="Owning library" i18n-ariaLabel
51 formControlName="owningLibrary">
52 </eg-org-family-select>
60 <li role="presentation" [ngbNavItem]="'select-resource'">
61 <a ngbNavLink role="tab">
62 <span class="material-icons" aria-hidden="true">assignment</span>
63 <ng-container i18n>Choose resource by barcode</ng-container>
65 <ng-template ngbNavContent>
66 <div ngbPanelContent class="row">
68 <div class="input-group">
69 <label class="form-label input-group-text" for="ideal-resource-barcode" i18n>Search by resource barcode</label>
70 <input type="text" id="ideal-resource-barcode" class="form-control" formControlName="resourceBarcode">
77 <li role="presentation" [ngbNavItem]="'attributes'" [disabled]="0 === attributes.length">
78 <a ngbNavLink role="tab">
79 <span class="material-icons" aria-hidden="true">filter_list</span>
80 <ng-container i18n>Limit by attributes</ng-container>
82 <ng-template ngbNavContent>
83 <ul class="list-group list-group-flush" formArrayName="selectedAttributes">
84 <li *ngFor="let attribute of attributes; let i = index" class="list-group-item">
85 <span class="input-group">
86 <label class="form-label input-group-text" for="attribute-{{attribute.id()}}" i18n>{{attribute.name()}}</label>
87 <eg-combobox [formControlName]="i">
88 <eg-combobox-entry *ngFor="let value of attribute.valid_values()"
89 [entryId]="value.id()" [entryLabel]="value.valid_value()">
98 <li role="presentation" [ngbNavItem]="'display-settings'">
99 <a ngbNavLink role="tab">
100 <span class="material-icons" aria-hidden="true">settings</span>
101 <ng-container i18n>Schedule settings</ng-container>
103 <ng-template ngbNavContent>
104 <ul class="list-group list-group-flush">
105 <li class="list-group-item">
106 <span class="input-group">
107 <label class="form-label input-group-text" for="start-time" i18n>Start time</label>
108 <ngb-timepicker formControlName="startOfDay" [minuteStep]="minuteStep()" [meridian]="true"></ngb-timepicker>
111 <li class="list-group-item">
112 <span class="input-group">
113 <label class="form-label input-group-text" for="end-time" i18n>End time</label>
114 <ngb-timepicker formControlName="endOfDay" [minuteStep]="minuteStep()" [meridian]="true"></ngb-timepicker>
117 <li *ngIf="criteria.errors && criteria.errors.startOfDayNotBeforeEndOfDay" class="list-group-item">
118 <div role="alert" class="alert alert-danger">
119 <span class="material-icons" aria-hidden="true">error</span>
120 <span i18n>Start time must be before end time</span>
123 <li class="list-group-item">
124 <span class="input-group">
125 <label class="form-label input-group-text" for="granularity" i18n>Granularity</label>
126 <eg-combobox (onChange)="changeGranularity($event)" [startId]="granularity ? granularity : 30">
127 <eg-combobox-entry [entryId]="15" entryLabel="15 minutes"
128 i18n-entryLabel></eg-combobox-entry>
129 <eg-combobox-entry [entryId]="30" entryLabel="30 minutes"
130 i18n-entryLabel></eg-combobox-entry>
131 <eg-combobox-entry [entryId]="60" entryLabel="60 minutes"
132 i18n-entryLabel></eg-combobox-entry>
141 <div [ngbNavOutlet]="details" class="mt-2"></div>
145 <ng-container *ngIf="resources.length">
147 <div class="row" *ngIf="idealDate && !multiday">
148 <button type="button" class="btn btn-info col-sm-2 offset-sm-3" (click)="addDays(-1)">
149 <span class="material-icons mat-icon-in-button" aria-hidden="true">keyboard_arrow_left</span>
150 <span i18n>Previous day</span>
152 <h2 class="col-sm-2 text-center" i18n>{{idealDate | formatValue:'timestamp'}}</h2>
153 <button type="button" class="btn btn-info col-sm-2" (click)="addDays(1)">
154 <span i18n>Next day</span>
155 <span class="material-icons mat-icon-in-button" aria-hidden="true">keyboard_arrow_right</span>
158 <eg-grid #scheduleGrid
159 [cellTextGenerator]="cellTextGenerator"
161 (onRowActivate)="openTheDialog([$event])"
162 [dataSource]="scheduleSource"
163 [rowFlairIsEnabled]="true"
164 [rowFlairCallback]="resourceAvailabilityIcon"
165 [disablePaging]="true"
166 persistKey="disabled">
167 <eg-grid-toolbar-button label="Create Reservation" i18n-label (onClick)="openTheDialog($event)"></eg-grid-toolbar-button>
168 <eg-grid-toolbar-action label="Create Reservation" i18n-label (onClick)="openTheDialog($event)"></eg-grid-toolbar-action>
169 <eg-grid-column path="time" [index]="true" name="Time" i18n-name [cellTemplate]="timeTemplate" ></eg-grid-column>
170 <eg-grid-column *ngFor="let resource of resources" path="{{resource.barcode()}}" [cellTemplate]="reservationsTemplate" [name]="resource.barcode()" [disableTooltip]="true"></eg-grid-column>
173 <div class="text-sm-center" *ngIf="this.resourceType.value && !resources.length" i18n>
174 There are no bookable resources that match your criteria.
175 Would you like to create <a [routerLink]="['/staff', 'admin', 'booking', 'splash']">some new resources</a>?
178 <eg-create-reservation-dialog #createDialog
179 (reservationRequestCompleted)="fetchData()"
180 [patronId]="patronId"
181 [targetResourceBarcode]="resourceBarcode"
182 [targetResource]="resourceId"
183 [targetResourceType]="resourceType.value"
184 [attributes]="flattenedSelectedAttributes"
185 [resources]="resources">
186 </eg-create-reservation-dialog>
188 <ng-template #reservationsTemplate let-row="row" let-col="col">
189 <ng-container *ngIf="row.patrons && row.patrons[col.name]">
190 <ul class="list-unstyled">
191 <li *ngFor="let reservation of row.patrons[col.name]">
192 <button type="button" class="btn btn-info" (click)="openReservationViewer(reservation['reservationId'])">
193 {{reservation['patronLabel']}}
199 <ng-template #timeTemplate let-row="row" let-col="col">
200 <ng-container *ngIf="!multiday">
201 {{row['time'].format('LT')}}
203 <ng-container *ngIf="multiday">
204 {{row['time'] | formatValue:'timestamp'}}
207 <eg-fm-record-editor #viewReservation
209 datetimeFields="start_time,end_time"
210 hiddenFields="xact_start,xact_finish,cancel_time,booking_interval">
211 </eg-fm-record-editor>
212 <eg-no-timezone-set-dialog #noTimezoneSetDialog>
213 </eg-no-timezone-set-dialog>