Skip to content
13 changes: 8 additions & 5 deletions src/dialog-user/components/dialog-user/dialogUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export class DialogUserController extends DialogClass implements IDialogs {
* @param {Object} DialogData factory.
*/

/*@ngInject*/
constructor(private DialogData: any,private $scope : ng.IScope) {
/* @ngInject */
constructor(private DialogData, private $q) {
super();
}

/**
* Runs when component is initialized
* @memberof DialogUserController
Expand Down Expand Up @@ -82,6 +83,10 @@ export class DialogUserController extends DialogClass implements IDialogs {
data: this.dialogValues
};
this.onUpdate({ data: outputData });
this.service.data = {
fields: this.dialogFields,
values: this.dialogValues,
};
}

public validateFields() {
Expand Down Expand Up @@ -184,13 +189,12 @@ export class DialogUserController extends DialogClass implements IDialogs {
promiseList.push(this.refreshSingleField(field));
});

Promise.all(promiseList).then((_data) => {
this.$q.all(promiseList).then((_data) => {
this.refreshRequestCount -= promiseList.length;
if (this.refreshRequestCount === 0) {
this.areFieldsBeingRefreshed = false;
}
this.saveDialogData();
this.$scope.$apply();
});
}

Expand Down Expand Up @@ -224,7 +228,6 @@ export class DialogUserController extends DialogClass implements IDialogs {
this.dialogFields[field].fieldBeingRefreshed = false;

this.saveDialogData();
this.$scope.$apply();

if (! _.isEmpty(this.fieldAssociations[field])) {
this.updateTargetedFieldsFrom(field);
Expand Down
116 changes: 81 additions & 35 deletions src/dialog-user/services/dialogData.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import DialogData from './dialogData';
import * as angular from 'angular';

const dialogField = {
'href': 'http://localhost:3001/api/service_templates/10000000000015/service_dialogs/10000000007060',
'id': 10000000007060,
Expand Down Expand Up @@ -465,41 +466,86 @@ describe('DialogDataService test', () => {
});
});

it('should allow a select list to be sorted', () => {
const testDropDown = {
values: [
[1, 'Test'],
[5, 'Test2'],
[2, 'Test5']
],
options: { sort_by: 'value', sort_order: 'descending', data_type: 'integer' }
};
const testSorted = dialogData.updateFieldSortOrder(testDropDown);
const expectedResult = [[5, 'Test2'], [2, 'Test5'], [1, 'Test']];
expect(testSorted).toEqual(expectedResult);
const testDropDownDescription = {
values: [
[1, 'B'],
[5, 'C'],
[2, 'A']
],
options: { sort_by: 'description', sort_order: 'descending' }
};
const testSortedDescription = dialogData.updateFieldSortOrder(testDropDownDescription);
const expectedSortedResult = [[5, 'C'], [1, 'B'], [2, 'A']];
expect(testSortedDescription).toEqual(expectedSortedResult);
describe('#outputConversion', () => {
beforeEach(() => {
const configuredField = dialogData.setupField({
name: 'date_1',
type: 'DialogFieldDateControl',
default_value: '2019-10-15',
});

dialogData.data = {
fields: {
[configuredField.name]: configuredField,
},
values: {
[configuredField.name]: configuredField.default_value,
},
};
});

it('converts Dates to string', () => {
let input = dialogData.data.values;
let output = dialogData.outputConversion(input);

expect(input === output).toBe(false); // shallow copy
expect(typeof input.date_1).toEqual('object'); // Date
expect(typeof output.date_1).toEqual('string');
expect(output.date_1).toMatch(/^\d+-\d+-\d+$/); // YYYY-MM-DD
});

// this test requires the "local timezone" to be UTC+1 or more
// timezone-mock is not compatible with current karma it seems:
// ERROR [karma]: { inspect: [Function: inspect] }
xit('preserves local timezone', () => {
let input = dialogData.data.values;
input.default_value = new Date('2019-10-15T00:11:22+01:00');

let output = dialogData.outputConversion(input);

expect(input.date_1.getUTCDate()).toEqual(14); // UTC is off by one
expect(output.date_1).toEqual('2019-10-15'); // not 2019-10-14
});
});
it('should allow a numeric Description field to be sorted in a dropdown', () => {
const testDropDownDescription = {
values: [
['zero', '1'],
['five', '5'],
['two', '2']
],
options: { sort_by: 'description', sort_order: 'descending' }
};
const testSortedDescription = dialogData.updateFieldSortOrder(testDropDownDescription);
const expectedSortedResult = [['five', '5'], ['two', '2'], ['zero', '1']];
expect(testSortedDescription).toEqual(expectedSortedResult);

describe('#updateFieldSortOrder', () => {
it('should allow a select list to be sorted', () => {
const testDropDown = {
values: [
[1, 'Test'],
[5, 'Test2'],
[2, 'Test5']
],
options: { sort_by: 'value', sort_order: 'descending', data_type: 'integer' }
};
const testSorted = dialogData.updateFieldSortOrder(testDropDown);
const expectedResult = [[5, 'Test2'], [2, 'Test5'], [1, 'Test']];
expect(testSorted).toEqual(expectedResult);
const testDropDownDescription = {
values: [
[1, 'B'],
[5, 'C'],
[2, 'A']
],
options: { sort_by: 'description', sort_order: 'descending' }
};
const testSortedDescription = dialogData.updateFieldSortOrder(testDropDownDescription);
const expectedSortedResult = [[5, 'C'], [1, 'B'], [2, 'A']];
expect(testSortedDescription).toEqual(expectedSortedResult);
});

it('should allow a numeric Description field to be sorted in a dropdown', () => {
const testDropDownDescription = {
values: [
['zero', '1'],
['five', '5'],
['two', '2']
],
options: { sort_by: 'description', sort_order: 'descending' }
};
const testSortedDescription = dialogData.updateFieldSortOrder(testDropDownDescription);
const expectedSortedResult = [['five', '5'], ['two', '2'], ['zero', '1']];
expect(testSortedDescription).toEqual(expectedSortedResult);
});
});
});
33 changes: 33 additions & 0 deletions src/dialog-user/services/dialogData.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as _ from 'lodash';
import * as angular from 'angular';
import {__} from '../../common/translateFunction';
import {sprintf} from 'sprintf-js';

export default class DialogDataService {
public data: any;

/**
* Sets up and configures properties for a dialog field
Expand Down Expand Up @@ -246,4 +248,35 @@ export default class DialogDataService {

return invalid;
}

// converts the internal representation into the representation parsed by the API
// currently, this means we convert Date instances to strings
public outputConversion(dialogData) {
const dateString = (date) => {
let y = date.getFullYear(),
m = date.getMonth() + 1,
d = date.getDate();
return sprintf('%04d-%02d-%02d', y, m, d);
};

let out = {...dialogData};

Object.values(this.data.fields || {}).forEach(({name, type}) => {
let value = out[name];

switch (type) {
case 'DialogFieldDateControl':
// server expects 2019-10-20, anything longer gets cut
// converting first to prevent timezone conversions
out[name] = _.isDate(value) ? dateString(value) : null;
break;
case 'DialogFieldDateTimeControl':
// explicit conversion to ISO datetime
out[name] = _.isDate(value) ? value.toISOString() : null;
break;
};
});

return out;
}
}