]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.html
LP#1916403 Staff catalog search form labels
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / catalog / search-form.component.html
1 <ng-template #ccvmOption let-list="list">
2   <ng-container *ngFor="let ccv of list">
3   <option *ngIf="ccv.is_simple() === 't'" value="{{ccv.code()}}">
4     {{ccv.search_label() || ccv.value()}}
5     <ng-container *ngIf="ccv.opac_visible() === 'f'" i18n>(Hidden)</ng-container>
6   </option>
7   </ng-container>
8   <ng-container *ngFor="let ccv of list">
9   <option *ngIf="ccv.is_simple() === 'f'" value="{{ccv.code()}}">
10     {{ccv.search_label() || ccv.value()}}
11     <ng-container *ngIf="ccv.opac_visible() === 'f'" i18n>(Hidden)</ng-container>
12   </option>
13   </ng-container>
14 </ng-template>
15
16 <div id='staffcat-search-form'>
17
18   <div *ngIf="canBeHidden()" class="row pt-1 pr-2">
19     <div class="col-lg-12 d-flex">
20       <div class="flex-1"></div><!-- push right -->
21       <a (click)="toggleFormDisplay()" class="label-with-material-icon no-href">
22         <ng-container *ngIf="hideForm()" i18n>
23           Show Search Form <span class="material-icons" aria-hidden="true">unfold_more</span>
24         </ng-container>
25         <ng-container *ngIf="!hideForm()" i18n>
26           Hide Search Form <span class="material-icons" aria-hidden="true">unfold_less</span>
27         </ng-container>
28       </a>
29     </div>
30   </div>
31   
32   <div *ngIf="!hideForm()" class="row pt-3 pb-1 mb-1">
33   <div class="col-lg-8">
34     <ul ngbNav #searchTabs="ngbNav" [(activeId)]="searchTab" (navChange)="onNavChange($event)" [keyboard]="true" [roles]="false" role="tablist" class="nav-tabs">
35       <li role="presentation" [ngbNavItem]="'term'">
36         <a i18n ngbNavLink role="tab">Keyword Search</a>
37         <ng-template ngbNavContent>
38           <div class="row"
39             [ngClass]="{'mt-4': idx === 0, 'mt-1': idx > 0}"
40             *ngFor="let q of context.termSearch.query; let idx = index; trackBy:trackByIdx">
41             <div class="col-lg-2 pr-1">
42               <div *ngIf="idx === 0">
43                 <label i18n class="select-label" for="context-termSearch-format">Format</label>
44                 <select class="form-control" id="context-termSearch-format" [(ngModel)]="context.termSearch.format">
45                   <option i18n value=''>All Formats</option>
46                   <ng-container
47                     *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.search_format}">
48                   </ng-container> 
49                 </select>
50               </div>
51               <div *ngIf="idx > 0">
52                 <label i18n class="select-label" for="context-termSearch-joinOp-{{idx}}">Join with</label>
53                 <select class="form-control" id="context-termSearch-joinOp-{{idx}}"
54                   [(ngModel)]="context.termSearch.joinOp[idx]">
55                   <option i18n value='&&'>And</option>
56                   <option i18n value='||'>Or</option>
57                 </select>
58               </div>
59             </div>
60             <div class="col-lg-2 pl-0 pr-2">
61               <label i18n class="select-label" for="context-termSearch-fieldClass-{{idx}}">Catalog Field</label>
62               <select class="form-control" id="context-termSearch-fieldClass-{{idx}}"
63                 (change)="preventBogusCombos(idx)"
64                 [(ngModel)]="context.termSearch.fieldClass[idx]">
65                 <option i18n value='keyword'>Keyword</option>
66                 <option i18n value='title'>Title</option>
67                 <option i18n value='jtitle'>Journal Title</option>
68                 <option i18n value='author'>Author</option>
69                 <option i18n value='subject'>Subject</option>
70                 <option i18n value='series'>Series</option>
71                 <option i18n value='bookplate'
72                   *ngIf="showBookplate()">Digital Bookplate</option>
73               </select>
74             </div>
75             <div class="col-lg-2 pl-0 pr-2">
76               <label i18n class="select-label" for="context-termSearch-matchOp-{{idx}}">Matching</label>
77               <select class="form-control" id="context-termSearch-matchOp-{{idx}}"
78                 [(ngModel)]="context.termSearch.matchOp[idx]">
79                 <option i18n value='contains'>Contains</option>
80                 <option i18n value='nocontains'>Does not contain</option>
81                 <option i18n value='phrase'>Contains phrase</option>
82                 <option [disabled]="context.termSearch.fieldClass[idx]==='keyword'"
83                   i18n value='exact'>Matches exactly</option>
84                 <option [disabled]="context.termSearch.fieldClass[idx]==='keyword'"
85                   i18n value='starts'>Starts with</option>
86               </select>
87             </div>
88             <div class="col-lg-4 pl-0 pr-2">
89               <div class="form-group">
90                 <div *ngIf="idx === 0">
91                   <label i18n class="input-label" for='first-query-input'>Search Terms</label>
92                   <input type="text" class="form-control"
93                     id='first-query-input'
94                     [(ngModel)]="context.termSearch.query[idx]"
95                     (keyup.enter)="searchByForm()"
96                     placeholder="Query..."/>
97                 </div>
98                 <div *ngIf="idx > 0">
99                   <label i18n class="input-label" for='context-termSearch-query-{{idx}}'>Search Terms</label>
100                   <input type="text" class="form-control"
101                     [(ngModel)]="context.termSearch.query[idx]"
102                     (keyup.enter)="searchByForm()"
103                     placeholder="Query..."/>
104                 </div>
105               </div>
106             </div>
107             <div class="col-lg-2 pl-0 pr-1">
108               <button class="btn btn-sm material-icon-button"
109                 (click)="addSearchRow(idx + 1)"
110                 i18n-title title="Add Search Row">
111                 <span class="material-icons">add_circle_outline</span>
112               </button>
113               <button class="btn btn-sm material-icon-button"
114                 [disabled]="context.termSearch.query.length < 2"
115                 (click)="delSearchRow(idx)"
116                 i18n-title title="Remove Search Row">
117                 <span class="material-icons">remove_circle_outline</span>
118               </button>
119               <button *ngIf="idx === 0"
120                 class="btn btn-sm material-icon-button" 
121                 type="button" (click)="toggleFilters()" 
122                 title="Toggle Search Filters" i18n-title>
123                 <span class="material-icons">more_vert</span>
124               </button>
125             </div>
126           </div>
127           <div class="row">
128             <div class="col-lg-12 form-inline">
129               <div class="form-inline-group">
130                 <label i18n class="select-label" for="context-sort">Sort Results</label>
131                 <select class="form-control mr-2" id="context-sort" [(ngModel)]="context.sort">
132                   <option value='' i18n>Sort by Relevance</option>
133                   <optgroup label="Sort by Title" i18n-label>
134                     <option value='titlesort' i18n>Title: A to Z</option>
135                     <option value='titlesort.descending' i18n>Title: Z to A</option>
136                   </optgroup>
137                   <optgroup label="Sort by Author" i18n-label>
138                     <option value='authorsort' i18n>Author: A to Z</option>
139                     <option value='authorsort.descending' i18n>Author: Z to A</option>
140                   </optgroup>
141                   <optgroup label="Sort by Publication Date" i18n-label>
142                     <option value='pubdate.descending' i18n>Date: Newest to Oldest</option>
143                     <option value='pubdate' i18n>Date: Oldest to Newest</option>
144                   </optgroup>
145                   <optgroup label="Sort by Popularity" i18n-label>
146                     <option value='popularity' i18n>Most Popular</option>
147                     <option value='poprel' i18n>Popularity Adjusted Relevance</option>
148                   </optgroup>
149                 </select>
150               </div>
151                 <div class="checkbox pl-2 ml-2 pt-2">
152                   <label for="context-termSearch-available">
153                     <input type="checkbox" [(ngModel)]="context.termSearch.available" id="context-termSearch-available" />
154                     <span class="pl-1" i18n>Limit to Available</span>
155                   </label>
156                 </div>
157                 <div class="checkbox pl-3 pt-2">
158                   <label for="context-termSearch-groupByMetarecord">
159                     <input type="checkbox" id="context-termSearch-groupByMetarecord"
160                       [(ngModel)]="context.termSearch.groupByMetarecord"/>
161                     <span class="pl-1" i18n>Group Formats/Editions</span>
162                   </label>
163                 </div>
164                 <div class="checkbox pl-3 pt-2">
165                   <label for="context-global">
166                     <input type="checkbox" id="context-global" [(ngModel)]="context.global"/>
167                     <span class="pl-1" i18n>Results from All Libraries</span>
168                   </label>
169                 </div>
170                 <div class="checkbox pl-3 pt-2" *ngIf="showExcludeElectronic()">
171                   <label for="context-termSearch-excludeElectronic">
172                     <input type="checkbox" id="context-termSearch-excludeElectronic"
173                       [(ngModel)]="context.termSearch.excludeElectronic"/>
174                     <span class="pl-1" i18n>Exclude Electronic Resources</span>
175                   </label>
176                 </div>
177               </div>
178           </div>
179           <div class="row" *ngIf="showFilters()">
180             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('item_type')">
181               <label i18n class="select-label" for="context-termSearch-ccvmFilters-item_type">Item Type</label>
182               <select class="form-control"  multiple="true" id="context-termSearch-ccvmFilters-item_type"
183                 [(ngModel)]="context.termSearch.ccvmFilters.item_type">
184                 <option value='' i18n>All Item Types</option>
185                 <ng-container
186                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.item_type}">
187                 </ng-container> 
188               </select>
189             </div>
190             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('item_form')">
191               <label i18n class="select-label" for="context-termSearch-ccvmFilters-item_form">Form</label>
192               <select class="form-control" multiple="true" id="context-termSearch-ccvmFilters-item_form"
193                 [(ngModel)]="context.termSearch.ccvmFilters.item_form">
194                 <option value='' i18n>All Item Forms</option>
195                 <ng-container
196                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.item_form}">
197                 </ng-container> 
198               </select>
199             </div>
200             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('item_lang')">
201               <label i18n class="select-label" for="context-termSearch-ccvmFilters-item_lang">Language</label>
202               <select class="form-control" id="context-termSearch-ccvmFilters-item_lang"
203                 [(ngModel)]="context.termSearch.ccvmFilters.item_lang" multiple="true">
204                 <option value='' i18n>All Languages</option>
205                 <ng-container
206                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.item_lang}">
207                 </ng-container> 
208               </select>
209             </div>
210             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('audience')">
211               <label i18n class="select-label" for="context-termSearch-ccvmFilters-audience">Audience</label>
212               <select class="form-control" id="context-termSearch-ccvmFilters-audience"
213                 [(ngModel)]="context.termSearch.ccvmFilters.audience" multiple="true">
214                 <option value='' i18n>All Audiences</option>
215                 <ng-container
216                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.audience}">
217                 </ng-container> 
218               </select>
219             </div>
220             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('vr_format')">
221               <label i18n class="select-label" for="context-termSearch-ccvmFilters-vr_format">Video Format</label>
222               <select class="form-control" id="context-termSearch-ccvmFilters-vr_format"
223                 [(ngModel)]="context.termSearch.ccvmFilters.vr_format" multiple="true">
224                 <option value='' i18n>All Video Formats</option>
225                 <ng-container
226                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.vr_format}">
227                 </ng-container> 
228               </select>
229             </div>
230             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('bib_level')">
231               <label i18n class="select-label" for="context-termSearch-ccvmFilters-bib_level">Bibliographic Level</label>
232               <select class="form-control" id="context-termSearch-ccvmFilters-bib_level"
233                 [(ngModel)]="context.termSearch.ccvmFilters.bib_level" multiple="true">
234                 <option value='' i18n>All Bib Levels</option>
235                 <ng-container
236                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.bib_level}">
237                 </ng-container> 
238               </select>
239             </div>
240             <div class="col-lg-3 mt-3" *ngIf="searchFilters().includes('lit_form')">
241               <label i18n class="select-label" for="context-termSearch-ccvmFilters-lit_form">Literary Form</label>
242               <select class="form-control" id="context-termSearch-ccvmFilters-lit_form"
243                 [(ngModel)]="context.termSearch.ccvmFilters.lit_form" multiple="true">
244                 <option value='' i18n>All Literary Forms</option>
245                 <ng-container
246                   *ngTemplateOutlet="ccvmOption;context:{list:ccvmMap.lit_form}">
247                 </ng-container> 
248               </select>
249             </div>
250             <div class="col-lg-3 mt-3">
251               <label i18n class="select-label" for="context-termSearch-copyLocations">Shelving Location</label>
252               <select class="form-control" id="context-termSearch-copyLocations"
253                 [(ngModel)]="context.termSearch.copyLocations" multiple="true">
254                 <option value='' i18n>All Shelving Locations</option>
255                 <option *ngFor="let loc of copyLocations" value="{{loc.id()}}" i18n>
256                   {{loc.name()}} ({{orgName(loc.owning_lib())}})
257                 </option>
258               </select>
259             </div>
260           </div>
261           <div class="row mt-3" *ngIf="showFilters()">
262             <div class="col-lg-12">
263               <div class="form-inline">
264                 <label for="pub-date1-input" i18n>Publication Year is</label>
265                 <label class="sr-only" for="pub-date-operator-select" i18n>compare publication dates using...</label>
266                 <select id="pub-date-operator-select" class="form-control ml-2" [(ngModel)]="context.termSearch.dateOp">
267                   <option value='is' i18n>Is</option>
268                   <option value='before' i18n>Before</option>
269                   <option value='after' i18n>After</option>
270                   <option value='between' i18n>Between</option>
271                 </select>
272                 <label i18n class="sr-only" for="context-termSearch-date1">Year, or beginning of year range</label>
273                 <input class="form-control ml-2" type="number" id="context-termSearch-date1"
274                   [(ngModel)]="context.termSearch.date1"/>
275                 <label i18n class="sr-only" for="context-termSearch-date2">End of year range</label>
276                   <input class="form-control ml-2" type="number"
277                   *ngIf="context.termSearch.dateOp === 'between'"
278                   [(ngModel)]="context.termSearch.date2"/>
279               </div>
280             </div>
281           </div>
282         </ng-template>
283       </li>
284       <li role="presentation" [ngbNavItem]="'ident'">
285         <a i18n ngbNavLink role="tab">Numeric Search</a>
286         <ng-template ngbNavContent>
287           <div class="row mt-4">
288             <div class="col-lg-12">
289               <div class="form-inline">
290                 <label for="ident-type" i18n>Query Type</label>
291                 <select class="form-control ml-2" name="ident-type"
292                   [(ngModel)]="context.identSearch.queryType">
293                   <option i18n value="identifier|isbn">ISBN</option>
294                   <option i18n value="identifier|upc">UPC</option>
295                   <option i18n value="identifier|issn">ISSN</option>
296                   <option i18n value="identifier|lccn">LCCN</option>
297                   <option i18n value="identifier|tcn">TCN</option>
298                   <option i18n value="item_barcode">Item Barcode</option>
299                 </select>
300                 <label for="ident-value" class="ml-2" i18n>Value</label>
301                 <input name="ident-value" id='ident-query-input' 
302                   type="text" class="form-control ml-2"
303                   [(ngModel)]="context.identSearch.value"
304                   (keyup.enter)="searchByForm()"
305                   placeholder="Numeric Query..."/>
306               </div>
307             </div>
308           </div>
309         </ng-template>
310       </li>
311       <li role="presentation" [ngbNavItem]="'marc'">
312         <a i18n ngbNavLink role="tab">MARC Search</a>
313         <ng-template ngbNavContent>
314           <div class="row mt-4">
315             <div class="col-lg-12">
316               <div class="form-inline mt-2" 
317                 *ngFor="let q of context.marcSearch.values; let idx = index; trackBy:trackByIdx">
318                 <label for="marc-tag-{{idx}}" i18n>Tag</label>
319                 <input class="form-control ml-2" size="3" type="text" 
320                   name="marc-tag-{{idx}}" id="{{ idx === 0 ? 'first-marc-tag' : '' }}"
321                   [(ngModel)]="context.marcSearch.tags[idx]"
322                   (keyup.enter)="searchByForm()"/>
323                 <label for="marc-subfield-{{idx}}" class="ml-2" i18n>Subfield</label>
324                 <input class="form-control ml-2" size="1" type="text" 
325                   name="marc-subfield-{{idx}}"
326                   [(ngModel)]="context.marcSearch.subfields[idx]"
327                   (keyup.enter)="searchByForm()"/>
328                 <label for="marc-value-{{idx}}" class="ml-2" i18n>Value</label>
329                 <input class="form-control ml-2" type="text" name="marc-value-{{idx}}"
330                   [(ngModel)]="context.marcSearch.values[idx]" 
331                   (keyup.enter)="searchByForm()"/>
332                 <button class="btn btn-sm material-icon-button ml-2"
333                   (click)="addMarcSearchRow(idx + 1)">
334                   <span class="material-icons">add_circle_outline</span>
335                 </button>
336                 <button class="btn btn-sm material-icon-button ml-2"
337                   [disabled]="context.marcSearch.values.length < 2"
338                   (click)="delMarcSearchRow(idx)">
339                   <span class="material-icons">remove_circle_outline</span>
340                 </button>
341               </div>
342             </div>
343           </div>
344           <div class="row mt-2">
345             <div class="checkbox pl-3">
346               <label>
347                 <input type="checkbox" [(ngModel)]="context.global"/>
348                 <span class="pl-1" i18n>Results from All Libraries</span>
349               </label>
350             </div>
351           </div>
352         </ng-template>
353       </li>
354       <li role="presentation" [ngbNavItem]="'browse'">
355         <a i18n ngbNavLink role="tab">Browse</a>
356         <ng-template ngbNavContent>
357           <div class="row mt-4">
358             <div class="col-lg-12 form-inline">
359               <label for="field-class" i18n>Browse for</label>
360               <select class="form-control ml-2" name="field-class"
361                 [(ngModel)]="context.browseSearch.fieldClass">
362                 <option i18n value='title'>Title</option>
363                 <option i18n value='author'>Author</option>
364                 <option i18n value='subject'>Subject</option>
365                 <option i18n value='series'>Series</option>
366               </select>
367               <label for="query" class="ml-2"> starting with </label>
368               <input type="text" class="form-control ml-2" 
369                 id='browse-term-input' name="query"
370                 [(ngModel)]="context.browseSearch.value"
371                 (keyup.enter)="searchByForm()"
372                 placeholder="Browse for..."/>
373             </div>
374           </div>
375         </ng-template>
376       </li>
377       <li role="presentation" [ngbNavItem]="'cnbrowse'">
378         <a i18n ngbNavLink role="tab">Shelf Browse</a>
379         <ng-template ngbNavContent>
380           <div class="row mt-4">
381             <div class="col-lg-12 form-inline">
382               <label for="cnbrowse-term-input" i18n>
383                 Browse Call Numbers starting with 
384               </label>
385               <input type="text" class="form-control ml-2" 
386                 id='cnbrowse-term-input' name="query"
387                 [(ngModel)]="context.cnBrowseSearch.value"
388                 (keyup.enter)="searchByForm()"
389                 placeholder="Browse Call Numbers..."/>
390             </div>
391           </div>
392         </ng-template>
393       </li>      
394     </ul>
395
396     <div [ngbNavOutlet]="searchTabs" class="mt-2"></div>
397
398   </div>
399   <div class="col-lg-4">
400     <div class="row">
401       <div class="col-lg-12">
402         <div class="card">
403           <div class="card-body">
404             <div class="float-right d-flex">
405               <eg-org-select 
406                 (onChange)="orgOnChange($event)"
407                 [initialOrg]="context.searchOrg"
408                 [placeholder]="'Library'" >
409               </eg-org-select>
410               <button class="btn btn-success mr-1 ml-1" type="button"
411                 [disabled]="searchIsActive()"
412                 (click)="context.pager.offset=0;searchByForm()" i18n>
413                 Search
414               </button>
415               <button class="btn btn-warning mr-1" type="button"
416                 [disabled]="searchIsActive()"
417                 (click)="context.reset()" i18n>
418                 Reset
419               </button>
420             </div>
421           </div>
422         </div>
423       </div>
424     </div>
425     <div class="row mt-1">
426       <div class="col-lg-12">
427         <eg-catalog-search-templates [searchTab]="searchTab">
428         </eg-catalog-search-templates>
429       </div>
430     </div>
431     <div class="row mt-1">
432       <div class="col-lg-12">
433         <eg-catalog-basket-actions></eg-catalog-basket-actions>
434       </div>
435     </div>
436   </div>
437   </div>
438   <div class="row mb-3 pb-3">
439     <ng-container *ngIf="context.result.global_summary as gs">
440       <ng-container *ngIf="gs.suggestions as sugg">
441         <div *ngIf="sugg.one_class_one_term as ocot" class="col-lg-12 d-flex align-content-center">
442           <span class="font-weight-bold font-italic mr-1" i18n>Did you mean:</span>
443           <span *ngFor="let s of ocot.suggestions; first as isFirst">
444             <span *ngIf="!isFirst" i18n>&nbsp; or &nbsp;</span>
445             <a routerLink="/staff/catalog/search" queryParamsHandling="merge"
446              [queryParams]="{query : s.suggestion, fieldClass : ocot.class}">
447                {{s.suggestion}}
448             </a>
449           </span>
450         </div>
451       </ng-container>
452     </ng-container>
453   </div>
454 </div>
455