]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/cat/volcopy/copy-attrs.component.html
LP1888723 Angular Holdings Maintenance / Item Attributes Editor
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / cat / volcopy / copy-attrs.component.html
1
2
3 <!-- We ask this question a lot.  Here's a handy template -->
4 <ng-template #yesNoSelect let-field="field">
5   <eg-combobox domId="{{field}}-input" 
6     [required]="true" [ngModel]="values['field']" 
7     (ngModelChange)="values[field] = $event ? $event.id : null">
8     <eg-combobox-entry entryId="t" entryLabel="Yes" i18n-entryLabel>
9     </eg-combobox-entry>
10     <eg-combobox-entry entryId="f" entryLabel="No" i18n-entryLabel>
11     </eg-combobox-entry>
12   </eg-combobox>
13 </ng-template>
14
15 <!-- this one is also repeated a lot -->
16 <ng-template #batchAttr let-field="field" let-required="required"
17   let-label="label" let-template="template" let-displayAs="displayAs">
18   <eg-batch-item-attr 
19     [name]="field" 
20     [label]="label || copyFieldLabel(field)"
21     [valueRequired]="required"
22     [displayAs]="displayAs"
23     [editInputDomId]="field + '-input'"
24     [editTemplate]="template"
25     [labelCounts]="itemAttrCounts(field)"
26     (valueCleared)="applyCopyValue(field, null)"
27     (changesSaved)="applyCopyValue(field, undefined, $event)">
28   </eg-batch-item-attr>
29 </ng-template>
30
31 <!-- Copy Templates -->
32 <div class="row border rounded border-dark pt-2 pb-2 bg-faint">
33   <div class="col-lg-1 font-weight-bold" i18n>Templates:</div>
34   <div class="col-lg-4">
35     <eg-combobox #copyTemplateCbox domId="template-select" 
36       [allowFreeText]="true" [entries]="volcopy.templateNames">
37     </eg-combobox>
38   </div>
39   <div class="col-lg-7 d-flex">
40     <button class="btn btn-outline-dark mr-2" (click)="applyTemplate()" i18n>Apply</button>
41     <button class="btn btn-outline-dark mr-2" (click)="saveTemplate()" i18n>Save</button>
42
43     <!-- 
44       The typical approach of wrapping a file input in a <label> results
45       in button-ish things that have slightly different dimensions.
46       Instead have a button activate a hidden file input.
47     -->
48     <button class="btn btn-outline-dark mr-2" (click)="templateFile.click()">
49       <input type="file" class="d-none" #templateFile
50         (change)="importTemplate($event)" id="template-file-upload"/>
51       <span i18n>Import</span>
52     </button>
53
54     <a (click)="exportTemplate($event)"
55       download="export_copy_template.json" [href]="exportTemplateUrl()">
56       <button class="btn btn-outline-dark mr-2" i18n>Export</button>
57     </a>
58     
59     <div class="flex-1"> </div>
60     <button class="btn btn-outline-danger mr-2" 
61       (click)="deleteTemplate()" i18n>Delete Template</button>
62   </div>
63 </div>
64
65
66 <div class="row d-flex">
67
68   <!-- COLUMN 1 -->
69   <div class="flex-1 p-1">
70     <div class="p-1"><h4 class="font-weight-bold" i18n>Identification</h4></div>
71
72
73     <div class="mb-1" *ngIf="displayAttr('status')">
74
75       <ng-container *ngIf="statusEditable(); else noEditStat">
76         <ng-template #statusTemplate>
77           <eg-combobox domId="status-input"
78             (ngModelChange)="values['status'] = $event ? $event.id : null"
79             [ngModel]="values['status']">
80             <eg-combobox-entry 
81               *ngFor="let stat of volcopy.commonData.acp_status"
82               [entryId]="stat.id()" [entryLabel]="stat.name()">
83             </eg-combobox-entry>
84           </eg-combobox>
85         </ng-template>
86         <ng-container *ngTemplateOutlet="batchAttr;
87           context:{field:'status',template:statusTemplate}">
88         </ng-container>
89       </ng-container>
90
91       <ng-template #noEditStat>
92         <eg-batch-item-attr label="Status" i18n-label [readOnly]="true"
93           [labelCounts]="itemAttrCounts('status')">
94         </eg-batch-item-attr>
95       </ng-template>
96     </div>
97
98     <div class="mb-1" *ngIf="displayAttr('barcode')">
99       <eg-batch-item-attr label="Barcode" i18n-label
100         [readOnly]="true" [labelCounts]="itemAttrCounts('barcode')">
101       </eg-batch-item-attr>
102     </div>
103
104     <div class="mb-1" *ngIf="displayAttr('create_date')">
105       <eg-batch-item-attr label="Creation Date" i18n-label [readOnly]="true"
106         [labelCounts]="itemAttrCounts('create_date')">
107       </eg-batch-item-attr>
108     </div>
109
110     <div class="mb-1" *ngIf="displayAttr('active_date')">
111       <eg-batch-item-attr label="Active Date" i18n-label [readOnly]="true"
112         [labelCounts]="itemAttrCounts('active_date')">
113       </eg-batch-item-attr>
114     </div>
115
116     <div class="mb-1" *ngIf="displayAttr('creator')">
117       <eg-batch-item-attr label="Creator" i18n-label [readOnly]="true"
118         [labelCounts]="itemAttrCounts('creator')">
119       </eg-batch-item-attr>
120     </div>
121
122     <div class="mb-1" *ngIf="displayAttr('edit_date')">
123       <eg-batch-item-attr label="Last Edit Date" i18n-label [readOnly]="true"
124         [labelCounts]="itemAttrCounts('edit_date')">
125       </eg-batch-item-attr>
126     </div>
127
128     <div class="mb-1" *ngIf="displayAttr('editor')">
129       <eg-batch-item-attr label="Last Editor" i18n-label [readOnly]="true"
130         [labelCounts]="itemAttrCounts('editor')">
131       </eg-batch-item-attr>
132     </div>
133
134   </div>
135
136   <!-- COLUMN 2 -->
137   <div class="flex-1 p-1">
138     <div class="p-1"><h4 class="font-weight-bold" i18n>Location</h4></div>
139
140     <div *ngIf="displayAttr('location')">
141       <ng-template #locationTemplate>
142         <eg-item-location-select (valueChange)="values['location'] = $event"
143           domId='location-input' [required]="true" permFilter="UPDATE_COPY">
144         </eg-item-location-select>
145       </ng-template>
146       <ng-container *ngTemplateOutlet="batchAttr;
147         context:{field:'location',required:true,template:locationTemplate}">
148       </ng-container>
149     </div>
150
151     <div *ngIf="displayAttr('circ_lib')">
152       <ng-template #circLibTemplate>
153         <eg-org-select 
154           domId="circ_lib-input"
155           (onChange)="values['circ_lib'] = $event ? $event.id() : null"
156           [hideOrgs]="volcopy.hideVolOrgs"
157           [limitPerms]="['UPDATE_COPY']">
158         </eg-org-select>
159       </ng-template>
160       <ng-container *ngTemplateOutlet="batchAttr;
161         context:{field:'circ_lib',required:true,template:circLibTemplate}">
162       </ng-container>
163     </div>
164
165     <div *ngIf="displayAttr('owning_lib')">
166       <eg-string #olLabel text="Owning Library" i18n-text></eg-string>
167       <ng-template #owningLibTemplate>
168         <eg-org-select 
169           domId="owning_lib-input"
170           (onChange)="values['owning_lib'] = $event ? $event.id() : null"
171           [hideOrgs]="volcopy.hideVolOrgs"
172           [limitPerms]="['UPDATE_COPY']">
173         </eg-org-select>
174       </ng-template>
175       <ng-container *ngTemplateOutlet="batchAttr;
176         context:{field:'owning_lib',required:true,template:owningLibTemplate,label:olLabel.text}">
177       </ng-container>
178     </div>
179
180     <div *ngIf="displayAttr('copy_number')">
181       <ng-template #copyNumberTemplate>
182         <input type="number" class="form-control"
183           id="copy_number-input" [(ngModel)]="values['copy_number']"/>
184       </ng-template>
185       <ng-container *ngTemplateOutlet="batchAttr;
186         context:{field:'copy_number',template:copyNumberTemplate}">
187       </ng-container>
188     </div>
189   </div>
190
191   <!-- COLUMN 3 -->
192
193   <div class="flex-1 p-1">
194     <div class="p-1"><h4 class="font-weight-bold" i18n>Circulation</h4></div>
195
196     <div *ngIf="displayAttr('circulate')">
197       <ng-template #circulateTemplate>
198         <ng-container *ngTemplateOutlet="yesNoSelect;context:{field:'circulate'}">
199         </ng-container>
200       </ng-template>
201       <ng-container *ngTemplateOutlet="batchAttr;
202         context:{field:'circulate',required:true,template:circulateTemplate,displayAs:'bool'}">
203       </ng-container>
204     </div>
205
206     <div *ngIf="displayAttr('holdable')">
207       <ng-template #holdableTemplate>
208         <ng-container *ngTemplateOutlet="yesNoSelect;context:{field:'holdable'}">
209         </ng-container>
210       </ng-template>
211       <ng-container *ngTemplateOutlet="batchAttr;
212         context:{field:'holdable',required:true,template:holdableTemplate,displayAs:'bool'}">
213       </ng-container>
214     </div>
215
216     <div *ngIf="displayAttr('age_protect')">
217       <ng-template #ageProtectTemplate>
218         <eg-combobox domId="age_protect-input"
219           (ngModelChange)="values['age_protect'] = $event ? $event.id : null"
220           [ngModel]="values['age_protect']">
221           <eg-combobox-entry 
222             *ngFor="let rule of volcopy.commonData.acp_age_protect"
223             [entryId]="rule.id()" [entryLabel]="rule.name()">
224           </eg-combobox-entry>
225         </eg-combobox>
226       </ng-template>
227       <ng-container *ngTemplateOutlet="batchAttr;
228         context:{field:'age_protect',template:ageProtectTemplate}">
229       </ng-container>
230     </div>
231
232     <div *ngIf="displayAttr('floating')">
233       <ng-template #floatingTemplate>
234         <eg-combobox domId="floating-input"
235           (ngModelChange)="values['floating'] = $event ? $event.id : null"
236           [ngModel]="values['floating']">
237           <eg-combobox-entry 
238             *ngFor="let grp of volcopy.commonData.acp_floating_group"
239             [entryId]="grp.id()" [entryLabel]="grp.name()">
240           </eg-combobox-entry>
241         </eg-combobox>
242       </ng-template>
243       <ng-container *ngTemplateOutlet="batchAttr;
244         context:{field:'floating',template:floatingTemplate}">
245       </ng-container>
246     </div>
247
248     <div *ngIf="displayAttr('loan_duration')">
249       <eg-string #loanDurationShort i18n-text text="Short"></eg-string>
250       <eg-string #loanDurationNormal i18n-text text="Normal"></eg-string>
251       <eg-string #loanDurationLong i18n-text text="Long"></eg-string>
252
253       <ng-template #loanDurationTemplate>
254         <select class="form-control" 
255           id="loan_duration-input" [(ngModel)]="values['loan_duration']">
256           <option value="1" i18n>{{loanDurationShort.text}}</option>
257           <option value="2" i18n>{{loanDurationNormal.text}}</option>
258           <option value="3" i18n>{{loanDurationLong.text}}</option>
259         </select>
260       </ng-template>
261       <ng-container *ngTemplateOutlet="batchAttr;
262         context:{field:'loan_duration',required:true,template:loanDurationTemplate}">
263       </ng-container>
264     </div>
265
266     <div *ngIf="displayAttr('fine_level')">
267       <eg-string #fineLevelLow i18n-text text="Low"></eg-string>
268       <eg-string #fineLevelNormal i18n-text text="Normal"></eg-string>
269       <eg-string #fineLevelHigh i18n-text text="High"></eg-string>
270
271       <ng-template #fineLevelTemplate>
272         <select class="form-control" 
273           id="fine_level-input" [(ngModel)]="values['fine_level']">
274           <option value="1" i18n>{{fineLevelLow.text}}</option>
275           <option value="2" i18n>{{fineLevelNormal.text}}</option>
276           <option value="3" i18n>{{fineLevelHigh.text}}</option>
277         </select>
278       </ng-template>
279       <ng-container *ngTemplateOutlet="batchAttr;
280         context:{field:'fine_level',required:true,template:fineLevelTemplate}">
281       </ng-container>
282     </div>
283
284     <div *ngIf="displayAttr('circ_as_type')">
285       <ng-template #circAsTypeTemplate>
286         <eg-combobox domId="circ_as_type-input"
287           (ngModelChange)="values['circ_as_type'] = $event ? $event.id : null"
288           [ngModel]="values['circ_as_type']">
289           <eg-combobox-entry *ngFor="let map of volcopy.commonData.acp_item_type_map"
290             [entryId]="map.code()" [entryLabel]="map.value()">
291           </eg-combobox-entry>
292         </eg-combobox>
293       </ng-template>
294       <ng-container *ngTemplateOutlet="batchAttr;
295         context:{field:'circ_as_type',template:circAsTypeTemplate}">
296       </ng-container>
297     </div>
298
299     <div *ngIf="displayAttr('circ_modifier')">
300       <ng-template #circModifierTemplate>
301         <select class="form-control" id='circ_modifier-input' 
302           [(ngModel)]="values['circ_modifier']">
303           <option [value]="null" i18n>&lt;Unset&gt;</option>
304           <option *ngFor="let mod of volcopy.commonData.acp_circ_modifier"
305             value="{{mod.code()}}">{{mod.name()}}</option>
306         </select>
307       </ng-template>
308       <ng-container *ngTemplateOutlet="batchAttr;
309         context:{field:'circ_modifier',template:circModifierTemplate}">
310       </ng-container>
311     </div>
312
313   </div>
314
315   <!-- COLUMN 4 -->
316
317   <div class="flex-1 p-1">
318     <div class="p-1"><h4 class="font-weight-bold" i18n>Miscellaneous</h4></div>
319
320     <!-- Adding this for sites that still use alert messages (we do)
321     <div>
322       <ng-template #alertMessageTemplate>
323         <textarea rows="3" class="form-control" id="alert-message-input"
324           [(ngModel)]="values['alert_message']">
325         </textarea>
326       </ng-template>
327       <eg-batch-item-attr label="Alert Message" i18n-label
328         editInputDomId="alert-message-input"
329         [editTemplate]="alertMessageTemplate"
330         [labelCounts]="itemAttrCounts('alert_message')"
331         (changesSaved)="applyCopyValue('alert_message')">
332       </eg-batch-item-attr>
333     </div>
334     -->
335
336     <div class="border rounded m-1" *ngIf="displayAttr('copy_alerts')">
337       <eg-copy-alerts-dialog #copyAlertsDialog></eg-copy-alerts-dialog>
338       <div class="batch-header font-weight-bold p-2" i18n>Add Item Alerts</div>
339       <div class="p-1">
340         <button class="btn btn-outline-dark" (click)="openCopyAlerts()" i18n>
341           Item Alerts
342         </button>
343       </div>
344     </div>
345
346     <div *ngIf="displayAttr('deposit')">
347       <ng-template #depositTemplate>
348         <ng-container *ngTemplateOutlet="yesNoSelect;context:{field:'deposit'}">
349         </ng-container>
350       </ng-template>
351       <ng-container *ngTemplateOutlet="batchAttr;
352         context:{field:'deposit',required:true,template:depositTemplate,displayAs:'bool'}">
353       </ng-container>
354     </div>
355
356     <div *ngIf="displayAttr('deposit_amount')">
357       <ng-template #depositAmountTemplate>
358         <input type="number" class="form-control" 
359           id="deposit_amount-input" [(ngModel)]="values['deposit_amount']"/>
360       </ng-template>
361       <ng-container *ngTemplateOutlet="batchAttr;
362         context:{field:'deposit_amount',required:true,template:depositAmountTemplate,displayAs:'currency'}">
363       </ng-container>
364     </div>
365
366     <div *ngIf="displayAttr('price')">
367       <ng-template #priceTemplate>
368         <input type="number" class="form-control" 
369           id="price-input" [(ngModel)]="values['price']"/>
370       </ng-template>
371       <ng-container *ngTemplateOutlet="batchAttr;
372         context:{field:'price',template:priceTemplate,displayAs:'currency'}">
373       </ng-container>
374     </div>
375
376     <div *ngIf="displayAttr('opac_visible')">
377       <ng-template #opacVisibleTemplate>
378         <ng-container *ngTemplateOutlet="yesNoSelect;context:{field:'opac_visible'}">
379         </ng-container>
380       </ng-template>
381       <ng-container *ngTemplateOutlet="batchAttr;
382         context:{field:'opac_visible',required:true,template:opacVisibleTemplate,displayAs:'bool'}">
383       </ng-container>
384     </div>
385
386     <div *ngIf="displayAttr('ref')">
387       <ng-template #refTemplate>
388         <ng-container *ngTemplateOutlet="yesNoSelect;context:{field:'ref'}">
389         </ng-container>
390       </ng-template>
391       <ng-container *ngTemplateOutlet="batchAttr;
392         context:{field:'ref',required:true,template:refTemplate,displayAs:'bool'}">
393       </ng-container>
394     </div>
395
396     <div *ngIf="displayAttr('cost')">
397       <ng-template #costTemplate>
398         <input type="number" class="form-control" 
399           id="cost-input" [(ngModel)]="values['cost']"/>
400       </ng-template>
401       <ng-container *ngTemplateOutlet="batchAttr;
402         context:{field:'cost',template:costTemplate,displayAs:'currency'}">
403       </ng-container>
404     </div>
405
406     <div *ngIf="displayAttr('mint_condition')">
407       <eg-string #mintConditionYes i18n-text text="Good"></eg-string>
408       <eg-string #mintConditionNo i18n-text text="Damaged"></eg-string>
409
410       <ng-template #mintConditionTemplate>
411         <select class="form-control" 
412           id="mint_condition-input" [(ngModel)]="values['mint_condition']">
413           <option value="t" i18n>{{mintConditionYes.text}}</option>
414           <option value="f" i18n>{{mintConditionNo.text}}</option>
415         </select>
416       </ng-template>
417       <ng-container *ngTemplateOutlet="batchAttr;
418         context:{field:'mint_condition',template:mintConditionTemplate}">
419       </ng-container>
420     </div>
421
422   </div>
423
424   <!-- COLUMN 5 -->
425   <div class="flex-1 p-1">
426     <div class="p-1"><h4 class="font-weight-bold" i18n>Statistics</h4></div>
427
428     <div class="border rounded m-1" *ngIf="displayAttr('copy_tags')">
429       <eg-copy-tags-dialog #copyTagsDialog></eg-copy-tags-dialog>
430       <div class="batch-header font-weight-bold p-2" i18n>Add Item Tags</div>
431       <div class="p-1">
432         <button class="btn btn-outline-dark" (click)="openCopyTags()" i18n>
433           Item Tags
434         </button>
435       </div>
436     </div>
437
438     <div class="border rounded m-1" *ngIf="displayAttr('statcat_filter')">
439       <div class="batch-header font-weight-bold p-2" i18n>Stat Cat Filter</div>
440       <div class="p-1">
441         <eg-org-select
442           domId="statcat_filter-select"
443           placeholder="Stat Cat Filter..." i18n-placeholder
444           [initialOrgId]="statCatFilter"
445           (onChange)="statCatFilter = $event ? $event.id() : null">
446         </eg-org-select>
447       </div>
448     </div>
449
450     <ng-container *ngIf="displayAttr('statcats')">
451       <div *ngFor="let cat of statCats()">
452         <ng-template #statCatTemplate>
453           <eg-combobox domId="stat-cat-input-{{cat.id()}}"
454             (ngModelChange)="statCatValues[cat.id()] = $event ? $event.id : null"
455             [ngModel]="statCatValues[cat.id()]">
456             <eg-combobox-entry *ngFor="let entry of cat.entries()"
457               [entryId]="entry.id()" [entryLabel]="entry.value()">
458             </eg-combobox-entry>
459           </eg-combobox>
460         </ng-template>
461         <eg-batch-item-attr label="{{cat.name()}} ({{orgSn(cat.owner())}})" i18n-label
462           name="stat_cat_{{cat.id()}}" editInputDomId="stat-cat-input-{{cat.id()}}"
463           [editTemplate]="statCatTemplate"
464           [labelCounts]="statCatCounts(cat.id())"
465           (valueCleared)="statCatChanged(cat.id(), true)"
466           (changesSaved)="statCatChanged(cat.id())">
467         </eg-batch-item-attr>
468       </div>
469     </ng-container>
470   </div>
471 </div>
472
473