-:host >>> .popover {
+.context-menu {
font-family: 'Lucida Console', Monaco, monospace;
max-width: 550px;
}
-:host >>> .popover-body {
+.context-menu .popover-body {
max-height: 400px;
overflow-y: auto;
overflow-x: auto;
}
-:host >>> .popover-body .menu-entry {
+.context-menu .popover-body .menu-entry {
white-space: nowrap;
}
-:host >>> .popover-body .menu-entry:hover {
- background-color: #f8f9fa; /* bootstrap color */
+.context-menu .popover-body .menu-entry:hover {
+ background-color: #f8f9fa;
}
-
<ng-template #menuTemplate>
<div *ngFor="let entry of menuEntries" class="menu-entry {{entryClasses}}">
- <a (click)="entryClicked(entry)">
- <span>{{entry.label}}</span>
- </a>
+ <a (click)="entryClicked(entry)"><span>{{entry.label}}</span></a>
</div>
</ng-template>
-
-<!--
-<div class="form-inline d-flex">
- <div class="flex-4">
- <span id='label-{{randId}}' class="text-left font-weight-bold">
- {{fieldLabel}}
- </span>
- </div>
- <input
- [attr.aria-labelledby]="'label-' + randId"
- class="form-control rounded-0 flex-5" type="text"
- (change)="valueChange()"
- [(ngModel)]="fieldValue"
- [attr.maxlength]="fieldLength" [attr.size]="fieldLength"
- [ngbPopover]="menuContent"
- #p="ngbPopover" triggers="manual"
- (contextmenu)="contextMenu($event, p)"
- />
-</div>
--->
-
-import {Component, Input, Output, OnInit, EventEmitter, Directive,
- ComponentFactoryResolver, ViewChild, TemplateRef} from '@angular/core';
+import {Component, Input, Output, OnInit, EventEmitter, Directive, ViewChild,
+ ViewEncapsulation, ComponentFactoryResolver, TemplateRef} from '@angular/core';
import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
/**
@Component({
selector: 'eg-context-menu',
templateUrl: './context-menu.component.html',
- styleUrls: ['context-menu.component.css']
+ styleUrls: ['context-menu.component.css'],
+ /* Our CSS affects the style of the popover, which may
+ * be beyond our reach for standard view encapsulation */
+ encapsulation: ViewEncapsulation.None
})
export class ContextMenuComponent implements OnInit {
menuComp: ContextMenuComponent;
triggers = 'contextmenu';
+ popoverClass = 'context-menu';
@Input() set egContextMenu(menuComp: ContextMenuComponent) {
this.menuComp = menuComp;
.sf-delimiter {
/* match angjs color */
- color: rgb(0, 0, 255);
+ color: rgb(0, 0, 255)!important;
/* snuggle up to my subfield code */
margin-right: -1rem;
}
.sf-code {
/* match angjs color */
- color: rgb(0, 0, 255);
+ color: rgb(0, 0, 255)!important;
}
+<eg-context-menu #contextMenu
+ [menuEntries]="contextMenuEntries"
+ (entrySelected)="contextMenuChange($event.value)">
+</eg-context-menu>
+
<ng-container *ngIf="bigText">
<div contenteditable
id='{{randId}}'
spellcheck="false"
class="d-inline-block p-1 pt-2 text-dark text-break {{moreClasses}}"
[attr.tabindex]="fieldText ? -1 : ''"
+ [egContextMenu]="contextMenu"
(keydown)="inputKeyDown($event)"
(focus)="focusBigText()"
(input)="bigTextValueChange()">
[maxlength]="maxLength || ''"
[disabled]="fieldText"
[attr.tabindex]="fieldText ? -1 : ''"
+ [egContextMenu]="contextMenu"
(keydown)="inputKeyDown($event)"
(focus)="$event.target.select()"
[ngModel]="getContent()"
import {filter} from 'rxjs/operators';
import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
import {MarcEditContext, FieldFocusRequest} from './editor-context';
+import {ContextMenuEntry} from '@eg/share/context-menu/context-menu.component';
+import {TagTableService} from './tagtable.service';
/**
* MARC Tag Editor Component
editInput: any; // <input/> or <div contenteditable/>
maxLength: number = null;
- constructor(private renderer: Renderer2) {
- this.randId = Math.floor(Math.random() * 100000);
- }
+ contextMenuEntries: ContextMenuEntry[];
+
+ constructor(
+ private renderer: Renderer2,
+ private tagTable: TagTableService) {}
ngOnInit() {
this.setupFieldType();
case 'sfc':
this.maxLength = 1;
this.watchForFocusRequests();
+ this.contextMenuEntries =
+ this.tagTable.getSubfieldCodes(this.field.tag);
break;
case 'sfv':
evt.preventDefault();
}
+
+
+ contextMenuChange(value: string) {
+ this.setContent(value);
+ }
}
recordChange: EventEmitter<MarcRecord>;
fieldFocusRequest: EventEmitter<FieldFocusRequest>;
-
- popOvers: NgbPopover[] = [];
+ recordType: 'biblio' | 'authority' = 'biblio';
private _record: MarcRecord;
set record(r: MarcRecord) {
this.fieldFocusRequest = new EventEmitter<FieldFocusRequest>();
}
- // NgbPopovers don't always close when we want them to,
- // specifcially when context-clicking to open other popovers.
- closePopovers() {
- // TODO
- this.popOvers.forEach(p => p.close());
- }
-
requestFieldFocus(req: FieldFocusRequest) {
// timeout allows for new components to be built before the
// focus request is emitted.
sources: ComboboxEntry[];
context: MarcEditContext;
+ @Input() recordType: 'biblio' | 'authority' = 'biblio';
+
@Input() set recordId(id: number) {
if (!id) { return; }
if (this.record && this.record.id === id) { return; }
ngOnInit() {
+ this.context.recordType = this.recordType;
+
this.store.getItem('cat.marcedit.flateditor').then(
useFlat => this.editorTab = useFlat ? 'flat' : 'rich');
<ng-container *ngIf="!dataLoaded">
- <eg-progress-inline></eg-progress-inline>
+ <div class="row mt-5">
+ <div class="offset-lg-3 col-lg-6">
+ <eg-progress-inline></eg-progress-inline>
+ </div>
+ </div>
</ng-container>
<ng-container *ngIf="dataLoaded">
if (!this.record) { return Promise.resolve(); }
return Promise.all([
- this.tagTable.loadTagTable({marcRecordType: this.record.recordType()}),
+ this.tagTable.loadTagTable({marcRecordType: this.context.recordType}),
this.tagTable.getFFPosTable(this.record.recordType()),
this.tagTable.getFFValueTable(this.record.recordType())
]).then(_ => this.dataLoaded = true);
selector = defaultTagTableSelector;
}
- // TODO load from local store cache
+ const cacheKey = 'FFValueTable_' + selector.marcRecordType;
- return this.fetchTagTable(selector);
+ this.tagMap = this.store.getLocalItem(cacheKey);
+
+ if (this.tagMap) {
+ return Promise.resolve(this.tagMap);
+ }
+
+ return this.fetchTagTable(selector).then(_ => {
+ this.store.setLocalItem(cacheKey, this.tagMap);
+ return this.tagMap;
+ });
}
fetchTagTable(selector?: TagTableSelector): Promise<any> {
+ this.tagMap = [];
return this.net.request(
'open-ils.cat',
'open-ils.cat.tag_table.all.retrieve.local',
getSubfieldCodes(tag: string): ValueLabelPair[] {
if (!tag || !this.tagMap[tag]) { return null; }
- return this.tagMap[tag].subfields
- .map(sf => ({
+ return this.tagMap[tag].subfields.map(sf => ({
value: sf.code,
label: `${sf.code}: ${sf.description}`
}))
background-color: #c9efe4;
color: black;
}
+
+/* context menu styling requires reaching up into the popup,
+ * which may not wo
+.context-menu {
+ font-family: 'Lucida Console', Monaco, monospace;
+ max-width: 550px;
+}
+
+.context-menu .popover-body {
+ max-height: 400px;
+ overflow-y: auto;
+ overflow-x: auto;
+}
+
+.context-menu .popover-body .menu-entry {
+ white-space: nowrap;
+}
+
+.context-menu .popover-body .menu-entry:hover {
+ background-color: #f8f9fa;
+}
+*/