<div class="modal-header">
<h4 class="modal-title">
<ng-container *ngIf="mode == 'create'">
- <span i18n>Adding tags for {{copies.length}} item(s).</span>
+ <span i18n>Adding tags for {{copyIds.length}} item(s).</span>
</ng-container>
<ng-container *ngIf="mode == 'manage'">
- <span i18n>Managing tags for item {{copies[0].barcode()}}</span>
+ <span i18n>Managing tags for item {{copy.barcode()}}</span>
</ng-container>
<span i18n></span>
</h4>
</button>
</div>
<div class="modal-body p-4 form-validated">
- <div class="row mt-2 p-2" *ngFor="let tag of newTags">
- <div class="col-lg-4">
- {{tag.tag_type()}}
- </div>
- <div class="col-lg-5">
- {{tag.label()}}
- </div>
- <div class="col-lg-3">
- <button class="btn btn-outline-danger" (click)="removeTag(tag)" i18n>
- Remove
- </button>
+
+ <ng-container *ngIf="mode == 'manage' && copy.tags().length">
+ <h4 i18n>Existing Tags</h4>
+ <div class="row mt-2 p-2" *ngFor="let map of copy.tags()">
+ <div class="col-lg-4">{{map.tag().tag_type().label()}}</div>
+ <div class="col-lg-5">{{map.tag().label()}}</div>
+ <div class="col-lg-3">
+ <button class="btn btn-outline-danger" (click)="removeTag(map.tag())" i18n>
+ Remove
+ </button>
+ </div>
</div>
+ <hr/>
+ </ng-container>
+
+ <h4 i18n>New Tags</h4>
+ <div class="row mt-2 p-2" *ngFor="let tag of newTags">
+ <ng-container *ngIf="!tag.isdeleted()">
+ <div class="col-lg-4">{{tagTypeMap[tag.tag_type()].label()}}</div>
+ <div class="col-lg-5">{{tag.label()}}</div>
+ <div class="col-lg-3">
+ <button class="btn btn-outline-danger" (click)="removeTag(tag)" i18n>
+ Remove
+ </button>
+ </div>
+ </ng-container>
</div>
<div class="row mt-2 p-2 rounded border border-success">
</div>
</div>
</div>
- <ng-container *ngIf="mode == 'manage'">
- <!-- in manage mode list all of the tags linked to the copy -->
- <!--
- <div class="row mt-2"
- *ngFor="let tag of copy.copy_tags()">
- <div class="col-lg-12 pb-2"><hr/></div>
- <div class="col-lg-4">
- <eg-combobox [entries]="tagTypes" [startId]="tag.tag_type()"
- i18n-placeholder placeholder="Tag Type..."
- [required]="true"
- (onChange)="tag.tag_type($event ? $event.id : null); tag.ischanged(true)">
- </eg-combobox>
- <div class="pl-2 pt-2" i18n>
- Added: {{tag.create_time() | date:'shortDate'}}
- </div>
- </div>
- <div class="col-lg-5">
- <textarea class="form-control" rows="2"
- i18n-placeholder placeholder="Tag Note..."
- (ngModelChange)="tag.note($event); tag.ischanged(true)"
- [ngModel]="tag.note()">
- </textarea>
- </div>
- <div class="col-lg-3">
- <div class="d-flex flex-column">
- <div class="form-check">
- <input class="form-check-input" type="checkbox"
- [ngModel]="tag.temp() == 't'"
- (ngModelChange)="tag.temp($event ? 't' : 'f'); tag.ischanged(true)"
- id="tag-temporary-{{tag.id()}}">
- <label class="form-check-label" for="tag-temporary-{{tag.id()}}" i18n>
- Temporary?
- </label>
- </div>
- <div class="form-check pt-2">
- <input class="form-check-input" type="checkbox"
- [ngModel]="tag.ack_time() != null"
- (ngModelChange)="tag.ack_time($event ? 'now' : null); tag.ischanged(true)"
- id="tag-temporary-{{tag.id()}}">
- <label class="form-check-label" for="tag-temporary-{{tag.id()}}" i18n>
- Clear?
- </label>
- </div>
- </div>
- </div>
- </div>
- -->
- </ng-container>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="close()" i18n>Cancel</button>
export class CopyTagsDialogComponent
extends DialogComponent implements OnInit {
- static autoId = -1;
-
- @Input() copyIds: number[] = [];
-
// If there are multiple copyIds, only new tags may be applied.
// If there is only one copyId, then tags may be applied or removed.
+ @Input() copyIds: number[] = [];
+
mode: string; // create | manage
// If true, no attempt is made to save the new tags to the
curTag: ComboboxEntry = null;
curTagType: ComboboxEntry = null;
newTags: IdlObject[] = [];
+ deletedMaps: IdlObject[] = [];
tagMap: {[id: number]: IdlObject} = {};
+ tagTypeMap: {[id: number]: IdlObject} = {};
tagDataSource: (term: string) => Observable<ComboboxEntry>;
this.copy = null;
this.copies = [];
this.newTags = [];
+ this.deletedMaps = [];
if (this.copyIds.length === 0 && !this.inPlaceMode) {
return throwError('copy ID required');
// In manage mode, we can only manage a single copy.
// But in create mode, we can add tags to multiple copies.
- if (this.copyIds.length === 1) {
+ if (this.copyIds.length === 1 && !this.inPlaceMode) {
this.mode = 'manage';
} else {
this.mode = 'create';
}
// Observify data loading
- const obs = from(
- this.getTagTypes()
- .then(_ => this.getCopies())
- );
+ const obs = from(this.getTagTypes().then(_ => this.getCopies()));
// Return open() observable to caller
return obs.pipe(switchMap(_ => super.open(args)));
return this.pcrud.search('cctt',
{owner: this.org.ancestors(this.auth.user().ws_ou(), true)},
{order_by: {cctt: 'label'}}
- ).pipe(tap(tag =>
- this.tagTypes.push({id: tag.code(), label: tag.label()})
- )).toPromise();
+ ).pipe(tap(tag => {
+ this.tagTypeMap[tag.code()] = tag;
+ this.tagTypes.push({id: tag.code(), label: tag.label()});
+ })).toPromise();
}
getCopies(): Promise<any> {
if (this.inPlaceMode) { return Promise.resolve(); }
return this.pcrud.search('acp', {id: this.copyIds},
- {flesh: 1, flesh_fields: {acp: ['tags']}}, {atomic: true})
+ {flesh: 3, flesh_fields: {
+ acp: ['tags'], acptcm: ['tag'], acpt: ['tag_type']}},
+ {atomic: true}
+ )
.toPromise().then(copies => {
this.copies = copies;
if (copies.length === 1) {
removeTag(tag: IdlObject) {
this.newTags = this.newTags.filter(t => t.id() !== tag.id());
- // TODO: delete existing maps where needed.
+ if (tag.isnew() || this.mode === 'create') { return; }
+
+ const existing = this.copy.tags().filter(m => m.tag().id() === tag.id())[0];
+ if (!existing) { return; }
+
+ existing.isdeleted(true);
+ this.deletedMaps.push(existing);
+ this.copy.tags(this.copy.tags().filter(m => m.tag().id() !== tag.id()));
+ this.copy.ischanged(true);
}
addNew() {
if (this.curTag.freetext) {
// Create a new tag w/ the provided tag text.
tag = this.idl.create('acpt');
- tag.id(CopyTagsDialogComponent.autoId--);
tag.isnew(true);
tag.tag_type(this.curTagType.id);
tag.label(this.curTag.label);
return promise;
}
+ deleteMaps(): Promise<any> {
+ if (this.deletedMaps.length === 0) { return Promise.resolve(); }
+ return this.pcrud.remove(this.deletedMaps).toPromise();
+ }
+
applyChanges() {
if (this.inPlaceMode) {
return;
}
- // Create the tags then map them to our copies
-
- let promise = this.createNewTags();
+ let promise = this.deleteMaps().then(_ => this.createNewTags());
this.newTags.forEach(tag => {
this.copies.forEach(copy => {
if (copy.tags() && copy.tags().filter(
- t => t.tag_type() === tag.id()).length > 0) {
+ map => map.tag().id() === tag.id()).length > 0) {
return; // map already exists
}
this.close(this.newTags.length > 0);
});
}
-
- /*
- applyChanges() {
- const tags = this.copy.copy_tags().filter(a => a.ischanged());
- if (tags.length === 0) { return; }
- this.pcrud.update(tags).toPromise().then(
- ok => this.successMsg.current().then(msg => this.toast.success(msg)),
- err => this.errorMsg.current().then(msg => this.toast.danger(msg))
- );
- }
- */
}