<ng-template #menuTemplate>
<!-- apply (click) to div so user can click anywhere in the row -->
<div *ngFor="let entry of menuEntries; first as isFirst"
- (click)="entryClicked(entry)" class="menu-entry {{entryClasses}}">
- <a>{{entry.label}}</a>
+ class="menu-entry {{entryClasses}}">
+ <button (click)="entryClicked(entry)" class="btn p-0 m-0">
+ {{entry.label}}
+ </button>
</div>
</ng-template>
// Only broadcast entry selection to my listeners if I'm
// hosting the menu where the selection occurred.
- if (this.menu && this.menu.id === this.menuService.activeMenu.id) {
+ if (this.activeMenuIsMe()) {
this.menuItemSelected.emit(entry);
+
+ // Item selection via keyboard fails to close the menu.
+ // Force it closed.
+ this.cleanup();
}
});
}
- open() {
+ activeMenuIsMe(): boolean {
+ return (
+ this.menu &&
+ this.menuService.activeMenu &&
+ this.menu.id === this.menuService.activeMenu.id
+ );
+ }
- // In certain scenarios (e.g. right-clicking on another context
- // menu) an open popover will stay open. Force it closed here.
+ // Close the active menu
+ cleanup() {
if (ContextMenuDirective.activeDirective) {
ContextMenuDirective.activeDirective.close();
ContextMenuDirective.activeDirective = null;
this.menuService.activeMenu = null;
}
+ }
+
+ open() {
+
+ // In certain scenarios (e.g. right-clicking on another context
+ // menu) an open popover will stay open. Force it closed here.
+ this.cleanup();
if (!this.menuEntries ||
this.menuEntries.length === 0) {
this.maxLength = fieldMeta.length || 1;
}
});
-
- // Fixed field options change when the record type changes.
- this.context.recordChange.subscribe(_ => this.applyFFOptions());
}
// These are served dynamically to handle cases where a tag or
contextMenuChange(value: string) {
this.setContent(value, true);
+
+ // Context menus can steal focus.
+ this.context.requestFieldFocus(this.context.lastFocused);
}
}
import {Component, Input, Output, OnInit, AfterViewInit, EventEmitter,
OnDestroy} from '@angular/core';
+import {filter} from 'rxjs/operators';
import {IdlService} from '@eg/core/idl.service';
import {OrgService} from '@eg/core/org.service';
import {TagTableService} from './tagtable.service';
ngOnInit() {
this.init().then(_ =>
this.context.recordChange.subscribe(__ => this.init()));
+
+ // Changing the Type fixed field means loading new meta-metadata.
+ this.record.fixedFieldChange.pipe(filter(code => code === 'Type'))
+ .subscribe(_ => this.init());
}
init(): Promise<any> {
this.tagTable.loadTagTable({marcRecordType: this.context.recordType}),
this.tagTable.getFfPosTable(this.record.recordType()),
this.tagTable.getFfValueTable(this.record.recordType())
- ]).then(_ => this.dataLoaded = true);
+ ]).then(_ =>
+ // setTimeout forces all of our sub-components to rerender
+ // themselves each time init() is called. Without this,
+ // changing the record Type would only re-render the fixed
+ // fields editor when data had to be fetched from the
+ // network. (Sometimes the data is cached).
+ setTimeout(() => this.dataLoaded = true)
+ );
}
undoCount(): number {
selector = defaultTagTableSelector;
}
- const cacheKey = 'FFValueTable_' + selector.marcRecordType;
+ const cacheKey =
+ `current_tag_table_${selector.marcFormat}_${selector.marcRecordType}`;
this.tagMap = this.store.getLocalItem(cacheKey);