</span>
<input *ngIf="field.datatype == 'id' && pkeyIsEditable"
+ class="form-control"
name="{{field.name}}"
[readonly]="field.readOnly"
[required]="field.isRequired()"
(ngModelChange)="record[field.name]($event)"/>
<input *ngIf="field.datatype == 'text'"
+ class="form-control"
name="{{field.name}}"
[readonly]="field.readOnly"
[required]="field.isRequired()"
[ngModel]="record[field.name]()"
(ngModelChange)="record[field.name]($event)"/>
+ <input *ngIf="field.datatype == 'int'"
+ class="form-control"
+ type="number"
+ name="{{field.name}}"
+ [readonly]="field.readOnly"
+ [required]="field.isRequired()"
+ [ngModel]="record[field.name]()"
+ (ngModelChange)="record[field.name]($event)"/>
+
+ <input *ngIf="field.datatype == 'float'"
+ class="form-control"
+ type="number" step="0.1"
+ name="{{field.name}}"
+ [readonly]="field.readOnly"
+ [required]="field.isRequired()"
+ [ngModel]="record[field.name]()"
+ (ngModelChange)="record[field.name]($event)"/>
+
+ <span *ngIf="field.datatype == 'money'">
+ <!-- in read-only mode display the local-aware currency -->
+ <input *ngIf="field.readOnly"
+ class="form-control"
+ type="number" step="0.1"
+ 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}}"
+ [readonly]="field.readOnly"
+ [required]="field.isRequired()"
+ [ngModel]="record[field.name]()"
+ (ngModelChange)="record[field.name]($event)"/>
+ </span>
+
+ <input *ngIf="field.datatype == 'bool'"
+ class="form-check-input"
+ type="checkbox"
+ name="{{field.name}}"
+ [readonly]="field.readOnly"
+ [ngModel]="record[field.name]()"
+ (ngModelChange)="record[field.name]($event)"/>
+
+ <span *ngIf="field.datatype == 'link'"
+ [ngClass]="{nullable : !field.isRequired()}">
+ <select
+ class="form-control"
+ name="{{field.name}}"
+ [disabled]="field.readOnly"
+ [required]="field.isRequired()"
+ [ngModel]="record[field.name]()"
+ (ngModelChange)="record[field.name]($event)">
+ <option *ngFor="let item of field.linkedValues"
+ [value]="item.id">{{item.name}}</option>
+ </select>
+ </span>
+
</div>
</div>
</form>
import {EgIdlService, EgIdlObject} from '@eg/core/idl.service';
import {EgPcrudService} from '@eg/core/pcrud.service';
import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
-import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'fm-record-editor',
// mode: 'create' for creating a new record,
// 'update' for editing an existing record
+ // 'view' for viewing an existing record without editing
@Input() mode: string;
// record ID to update. Not all IDs are numbers.
super(modal)
}
+ // Avoid fetching data on init since that may lead to unnecessary
+ // data retrieval.
ngOnInit() {
this.idlDef = this.idl.classes[this.idlClass];
this.recordLabel = this.idlDef.label;
- this.initRecord();
+ }
+
+ // Opening dialog, fetch data.
+ open(options?: NgbModalOptions): Promise<any> {
+ return this.initRecord().then(
+ ok => super.open(options),
+ err => console.warn(`Error fetching FM data: ${err}`)
+ );
}
private initRecord(): Promise<any> {
- if (this.mode == 'update') {
+ if (this.mode == 'update' || this.mode == 'view') {
return this.pcrud.retrieve(this.idlClass, this.recordId)
.toPromise().then(rec => {
+
+ if (!rec) {
+ return Promise.reject(
+ `No record found with id ${this.recordId}`);
+ }
+
this.record = rec;
this.convertDatatypesToJs();
- this.fields = this.getFieldList();
+ return this.getFieldList().then(
+ fields => this.fields = fields);
});
}
// create a new record from scratch
this.pkeyIsEditable = !('pkey_sequence' in this.idlDef);
this.record = this.idl.create(this.idlClass);
- this.fields = this.getFieldList();
- return Promise.resolve();
+ return this.getFieldList().then(fields => this.fields = fields);
}
// Modifies the FM record in place, replacing IDL-compatible values
}
private flattenLinkedValues(cls: string, list: EgIdlObject[]): any[] {
- let results: any[] = [];
- let idField: string = this.idlDef.pkey;
- let selector: string =
- this.idlDef.field_map[idField].selector || idField;
-
+ let idField = this.idl.classes[cls].pkey;
+ let selector =
+ this.idl.classes[cls].field_map[idField].selector || idField;
return list.map(item => {
return {id: item[idField](), name: item[selector]()}
});
}
- private getFieldList(): any[] {
+ private getFieldList(): Promise<any[]> {
let fields = this.idlDef.fields.filter(f =>
f.virtual != 'true' &&
!this.hiddenFields.includes(f.name)
);
+ let promises = [];
+
fields.forEach(field => {
- field.readOnly = this.readonlyFields.includes(field.name);
+ field.readOnly = this.mode == 'view'
+ || this.readonlyFields.includes(field.name);
if (this.isRequiredOverride &&
field.name in this.isRequiredOverride) {
}
}
- // TODO
+ if (field.datatype == 'link') {
+ promises.push(
+ this.pcrud.retrieveAll(field.class, {}, {atomic : true})
+ .toPromise().then(list => {
+ field.linkedValues =
+ this.flattenLinkedValues(field.class, list);
+ })
+ );
+ }
+
+ // TODO org unit
+ // TODO custom field templates
});
- console.debug(fields);
- return fields;
+ return Promise.all(promises).then(ok => fields);
}
save() {