for (var cls in this.classes)
mkclass(cls, this.classes[cls].fields);
- };
+ }
+
+ // Makes a deep copy of an EgIdlObject's / structures containing
+ // EgIdlObject's. Note we don't use JSON cross-walk because our
+ // JSON lib does not handle circular references.
+ // @depth specifies the maximum number of steps through EgIdlObject'
+ // we will traverse.
+ clone(source: any, depth?: number): any {
+ if (depth === undefined) depth = 100;
+
+ var result;
+ if (typeof source == 'undefined' || source === null) {
+ return source;
+
+ } else if (source._isfieldmapper) {
+ // same depth because we're still cloning this same object
+ result = this.create(source.classname, this.clone(source.a, depth));
+
+ } else {
+ if(Array.isArray(source)) {
+ result = [];
+ } else if(typeof source === 'object') { // source is not null
+ result = {};
+ } else {
+ return source; // primitive
+ }
+
+ for (var j in source) {
+ if (source[j] === null || typeof source[j] == 'undefined') {
+ result[j] = source[j];
+ } else if(source[j]._isfieldmapper) {
+ if (depth) result[j] = this.clone(source[j], depth - 1);
+ } else {
+ result[j] = this.clone(source[j], depth);
+ }
+ }
+ }
+
+ return result;
+ }
}
return this.dispatch(method, [this.token(reqOps), search, pcrudOps]);
}
- create(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ create(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.cud('create', list)
}
- update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ update(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.cud('update', list)
}
- remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ remove(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.cud('delete', list)
}
- autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> { // RENAMED
+ autoApply(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> { // RENAMED
return this.cud('auto', list)
}
private cud(action: string,
list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
+ this.cudList = [].concat(list); // value or array
this.log(`CUD(): ${action}`);
this.cudAction = action;
this.xactCloseMode = 'commit';
- if (!Array.isArray(list)) this.cudList = [list];
-
return this.wrapXact(() => {
return Observable.create(observer => {
this.cudObserver = observer;
return this.newContext().search(fmClass, search, pcrudOps, reqOps);
}
- create(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ create(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.newContext().create(list);
}
- update(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ update(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.newContext().update(list);
}
- remove(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ remove(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.newContext().remove(list);
}
- autoApply(list: EgIdlObject[]): Observable<EgPcrudResponse> {
+ autoApply(list: EgIdlObject | EgIdlObject[]): Observable<EgPcrudResponse> {
return this.newContext().autoApply(list);
}
}
<ng-template #dialogContent>
<div class="modal-header bg-info">
- <h4 class="modal-title" i18n>Record Editor</h4>
+ <h4 class="modal-title" i18n>Record Editor: {{recordLabel}}</h4>
<button type="button" class="close"
i18n-aria-label aria-label="Close"
(click)="dismiss('cross_click')">
</form>
</div>
<div class="modal-footer">
- <button type="button" class="btn btn-success"
+ <button type="button" class="btn btn-success" *ngIf="mode == 'view'"
(click)="close()" i18n>Close</button>
+ <button type="button" class="btn btn-warning" *ngIf="mode != 'view'"
+ (click)="cancel()" i18n>Cancel</button>
+ <button type="button" class="btn btn-success pl-1" *ngIf="mode != 'view'"
+ (click)="save()" i18n>Save</button>
</div>
</ng-template>
});
}
+ // Modifies the provided FM record in place, replacing JS values
+ // with IDL-compatible values.
+ convertDatatypesToIdl(rec: EgIdlObject) {
+ var fields = this.idlDef.fields;
+ fields.forEach(field => {
+ if (field.datatype == 'bool') {
+ if (rec[field.name]() == true) {
+ rec[field.name]('t');
+ } else if (rec[field.name]() == false) {
+ rec[field.name]('f');
+ }
+ } else if (field.datatype == 'org_unit') {
+ let org = rec[field.name]();
+ if (org != null && typeof org == 'object') {
+ rec[field.name](org.id());
+ }
+ }
+
+ /* TODO
+ // retrieve values from any fields controlled
+ // by custom templates, which for the moment all
+ // expect to be passed an ordinary flat value
+ if (field.name in $scope.rec_flat) {
+ rec[field.name]($scope.rec_flat[field.name]);
+ }
+ */
+ });
+ }
+
+
private flattenLinkedValues(cls: string, list: EgIdlObject[]): any[] {
let idField = this.idl.classes[cls].pkey;
let selector =
}
save() {
- // save changes here
- this.close(/* data for caller */);
+ let recToSave = this.idl.clone(this.record);
+ this.convertDatatypesToIdl(recToSave);
+ this.pcrud[this.mode]([recToSave]).toPromise().then(
+ result => this.close(result),
+ error => this.dismiss(error)
+ );
}
cancel() {
- this.dismiss(/* data for caller */);
+ this.dismiss('canceled');
}
}