<div class="modal-body">
<form role="form">
<div class="form-group row" *ngFor="let field of fields">
- <div class="col-lg-3">
+ <div class="col-lg-3 offset-lg-1">
<label for="rec-{{field.name}}">{{field.label}}</label>
</div>
- <div class="col-lg-9">
+ <div class="col-lg-7">
<!-- TODO custom field templates -->
<span *ngIf="field.datatype == 'id' && !pkeyIsEditable">
{{record[field.name]()}}
<input *ngIf="field.datatype == 'id' && pkeyIsEditable"
class="form-control"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
<input *ngIf="field.datatype == 'text'"
class="form-control"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
<input *ngIf="field.datatype == 'int'"
class="form-control"
type="number"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
<input *ngIf="field.datatype == 'float'"
class="form-control"
type="number" step="0.1"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
<input *ngIf="field.readOnly"
class="form-control"
type="number" step="0.1"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]() | currency"/>
<input *ngIf="!field.readOnly"
class="form-control"
type="number" step="0.1"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
<input *ngIf="field.datatype == 'bool'"
class="form-check-input"
type="checkbox"
- name="{{field.name}}"
+ [name]="field.name"
[readonly]="field.readOnly"
[ngModel]="record[field.name]()"
(ngModelChange)="record[field.name]($event)"/>
[ngClass]="{nullable : !field.isRequired()}">
<select
class="form-control"
- name="{{field.name}}"
+ [name]="field.name"
[disabled]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
</select>
</span>
+ <eg-org-select *ngIf="field.datatype == 'org_unit'"
+ [placeholder]="field.label"
+ [applyDefault]="field.orgDefaultAllowed"
+ [initialOrgId]="record[field.name]()"
+ (onChange)="record[field.name]($event)">
+ </eg-org-select>
+
</div>
</div>
</form>
import {Component, OnInit, Input, Output, ViewChild, EventEmitter} from '@angular/core';
-import {EgStoreService} from '@eg/core/store.service';
-import {EgOrgService} from '@eg/core/org.service';
import {EgIdlService, EgIdlObject} from '@eg/core/idl.service';
+import {EgAuthService} from '@eg/core/auth.service';
import {EgPcrudService} from '@eg/core/pcrud.service';
import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
if (id) this.recId = id;
}
+ // IDL record we are editing
+ // TODO: allow this to be provided by the caller?
+ record: EgIdlObject;
+
// TODO
// customFieldTemplates
// IDL info for the the selected IDL class
idlDef: any;
- // IDL record we are editing
- // TODO: allow this to be provided by the caller?
- record: EgIdlObject;
-
// Can we edit the primary key?
pkeyIsEditable: boolean = false;
constructor(
private modal: NgbModal, // required for passing to parent
private idl: EgIdlService,
- private store: EgStoreService,
- private org: EgOrgService,
- private pcrud: EgPcrudService
- ) {
+ private auth: EgAuthService,
+ private pcrud: EgPcrudService) {
super(modal)
}
this.record = rec;
this.convertDatatypesToJs();
- return this.applyFields();
+ return this.getFieldList();
});
}
// create a new record from scratch
this.pkeyIsEditable = !('pkey_sequence' in this.idlDef);
this.record = this.idl.create(this.idlClass);
- return this.applyFields();
+ return this.getFieldList();
}
// Modifies the FM record in place, replacing IDL-compatible values
});
}
- private applyFields(): Promise<any> {
+ private getFieldList(): Promise<any> {
this.fields = this.idlDef.fields.filter(f =>
f.virtual != 'true' &&
this.flattenLinkedValues(field.class, list);
})
);
+ } else if (field.datatype == 'org_unit') {
+ field.orgDefaultAllowed =
+ this.orgDefaultAllowed.includes(field.name);
}
- // TODO org unit
// TODO custom field templates
});
export class EgOrgSelectComponent implements OnInit {
selected: OrgDisplay;
- startOrg: EgIdlObject;
hidden: number[] = [];
disabled: number[] = [];
click$ = new Subject<string>();
+ startOrg: EgIdlObject;
@ViewChild('instance') instance: NgbTypeahead;
- // Read-only properties optionally provided by the calling component.
- @Input() placeholder: string;
+ // Placeholder text for selector input
+ @Input() placeholder: string = '';
@Input() stickySetting: string;
+
+ // Org unit field displayed in the selector
@Input() displayField: string = 'shortname';
- @Input() set initialOrg(org: EgIdlObject) {
- if (org) this.startOrg = org;
- }
+ // Apply a default org unit value when none is set.
+ // First tries workstation org unit, then user home org unit.
+ @Input() applyDefault: boolean = false;
+
+ // List of org unit IDs to exclude from the selector
@Input() set hideOrgs(ids: number[]) {
if (ids) this.hidden = ids;
}
+ // List of org unit IDs to disable in the selector
@Input() set disableOrgs(ids: number[]) {
if (ids) this.disabled = ids;
}
- /** Emitted when the org unit value is changed via the selector.
- * Does not fire on initialOrg.
- */
+ // Apply an org unit value at load time.
+ // This will NOT result in an onChange event.
+ @Input() set initialOrg(org: EgIdlObject) {
+ if (org) this.startOrg = org;
+ }
+
+ // Apply an org unit value by ID at load time.
+ // This will NOT result in an onChange event.
+ @Input() set initialOrgId(id: number) {
+ if (id) this.startOrg = this.org.get(id);
+ }
+
+ // Modify the selected org unit via data binding.
+ // This WILL result in an onChange event firing.
+ @Input() set applyOrg(org: EgIdlObject) {
+ if (org) this.selected = this.formatForDisplay(org);
+ }
+
+ // Modify the selected org unit by ID via data binding.
+ // This WILL result in an onChange event firing.
+ @Input() set applyOrgId(id: number) {
+ if (id) this.selected = this.formatForDisplay(this.org.get(id));
+ }
+
+ // Emitted when the org unit value is changed via the selector.
+ // Does not fire on initialOrg
@Output() onChange = new EventEmitter<EgIdlObject>();
constructor(
) {}
ngOnInit() {
+
+ // Apply a default org unit if desired and possible.
+ if (!this.startOrg && this.applyDefault && this.auth.user()) {
+ // note: ws_ou defaults to home_ou on the server
+ // when when no workstation is used
+ this.startOrg = this.org.get(this.auth.user().ws_ou());
+ this.selected = this.formatForDisplay(
+ this.org.get(this.auth.user().ws_ou())
+ );
+ }
+
if (this.startOrg) {
this.selected = this.formatForDisplay(this.startOrg);
}
}
+ // Format for display in the selector drop-down and input.
formatForDisplay(org: EgIdlObject): OrgDisplay {
return {
id : org.id(),
};
}
+ // Fired by the typeahead to inform us of a change.
orgChanged(selEvent: NgbTypeaheadSelectItemEvent) {
this.onChange.emit(this.org.get(selEvent.item.id));
}
- // Formats the selected value
+ // Remove the tree-padding spaces when matching.
formatter = (result: OrgDisplay) => result.label.trim();
filter = (text$: Observable<string>): Observable<OrgDisplay[]> => {
dialogBody='Workstation "{{newName}}" already exists. Use it anyway?'>
</eg-confirm-dialog>
-<!-- TESTING TESTING -->
+<!-- TESTING TESTING
+idlClass="cmrcfld"
+idlClass="cbt"
+-->
<fm-record-editor #fmRecordEditor
- idlClass="cmrcfld" mode="update"
- recordId="1">
+ idlClass="cmrcfld" mode="create"
+ recordId="1" [orgDefaultAllowed]="['owner']">
</fm-record-editor>
<button (click)="fmRecordEditor.open({size:'lg'})">Fm Record Editor Test</button>
<div class="row mt-2">
<div class="col-lg-2">
<eg-org-select
+ [applyDefault]="true"
(onChange)="orgOnChange($event)"
[hideOrgs]="hideOrgs"
[disableOrgs]="disableOrgs"
- [placeholder]="'Owner'" >
+ placeholder="Owner" >
</eg-org-select>
</div>
<div class="col-lg-6">