2017-02-06 17:01:04 +00:00
|
|
|
import {module} from '../module';
|
2017-02-07 13:34:26 +00:00
|
|
|
import Component from '../lib/component';
|
|
|
|
import getModifiedData from '../lib/modified';
|
2017-10-05 07:20:40 +00:00
|
|
|
import copyObject from '../lib/copy';
|
2017-10-05 07:51:27 +00:00
|
|
|
import isEqual from '../lib/equals';
|
2017-02-06 17:01:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Component that checks for changes on a specific model property and
|
|
|
|
* asks the user to save or discard it when the state changes.
|
|
|
|
* Also it can save the data to the server when the @url and @idField
|
|
|
|
* properties are provided.
|
|
|
|
*/
|
|
|
|
export default class Watcher extends Component {
|
2017-10-05 07:53:40 +00:00
|
|
|
constructor($element, $scope, $state, $transitions, $http, vnApp, $translate) {
|
2017-02-06 17:01:04 +00:00
|
|
|
super($element);
|
2017-02-07 11:58:25 +00:00
|
|
|
this.$scope = $scope;
|
2017-02-06 17:01:04 +00:00
|
|
|
this.$state = $state;
|
|
|
|
this.$http = $http;
|
2017-02-07 16:38:30 +00:00
|
|
|
this.$translate = $translate;
|
2017-06-05 07:01:21 +00:00
|
|
|
this.vnApp = vnApp;
|
2017-02-06 17:01:04 +00:00
|
|
|
|
|
|
|
this.state = null;
|
|
|
|
this.deregisterCallback = $transitions.onStart({},
|
2017-03-07 11:37:59 +00:00
|
|
|
transition => this.callback(transition));
|
2017-10-05 07:31:28 +00:00
|
|
|
this.updateOriginalData();
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-07 11:58:25 +00:00
|
|
|
$onInit() {
|
2017-09-28 09:29:01 +00:00
|
|
|
if (this.get && this.url) {
|
2017-02-07 11:58:25 +00:00
|
|
|
this.fetchData();
|
2017-09-28 09:29:01 +00:00
|
|
|
} else if (this.get && !this.url) {
|
|
|
|
throw new Error('Error: Parameter url ommitted');
|
2017-02-07 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-07 11:58:25 +00:00
|
|
|
$onChanges(changes) {
|
2017-03-07 11:37:59 +00:00
|
|
|
if (this.data) {
|
2017-10-05 07:31:28 +00:00
|
|
|
this.updateOriginalData();
|
2017-02-07 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-07 11:58:25 +00:00
|
|
|
$onDestroy() {
|
|
|
|
this.deregisterCallback();
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-07 11:58:25 +00:00
|
|
|
fetchData() {
|
|
|
|
let id = this.data[this.idField];
|
2017-09-28 09:29:01 +00:00
|
|
|
// return new Promise((resolve, reject) => {
|
|
|
|
this.$http.get(`${this.url}/${id}`).then(
|
|
|
|
json => {
|
2017-10-05 07:20:40 +00:00
|
|
|
this.data = copyObject(json.data);
|
2017-10-05 07:31:28 +00:00
|
|
|
this.updateOriginalData();
|
2017-09-28 09:29:01 +00:00
|
|
|
}
|
|
|
|
// json => reject(json)
|
|
|
|
);
|
|
|
|
// });
|
2017-02-07 11:58:25 +00:00
|
|
|
}
|
2017-03-07 16:11:56 +00:00
|
|
|
/**
|
|
|
|
* Submits the data and goes back in the history.
|
|
|
|
*/
|
|
|
|
submitBack() {
|
2017-10-16 13:20:40 +00:00
|
|
|
return this.submit().then(
|
2017-03-07 16:11:56 +00:00
|
|
|
() => this.window.history.back()
|
|
|
|
);
|
|
|
|
}
|
2017-06-03 11:01:47 +00:00
|
|
|
/**
|
|
|
|
* Submits the data and goes another state.
|
|
|
|
*
|
|
|
|
* @param {String} state The state name
|
|
|
|
*/
|
|
|
|
submitGo(state) {
|
2017-10-16 13:20:40 +00:00
|
|
|
return this.submit().then(
|
2017-06-03 11:01:47 +00:00
|
|
|
() => this.$state.go(state)
|
|
|
|
);
|
|
|
|
}
|
2017-03-07 16:11:56 +00:00
|
|
|
/**
|
|
|
|
* Submits the data to the server.
|
|
|
|
*
|
|
|
|
* @return {Promise} The http request promise
|
|
|
|
*/
|
2017-02-06 17:01:04 +00:00
|
|
|
submit() {
|
2017-03-07 16:11:56 +00:00
|
|
|
if (this.form) {
|
|
|
|
this.form.$setSubmitted();
|
|
|
|
|
|
|
|
if (!this.form.$valid)
|
|
|
|
return new Promise(
|
|
|
|
(resolve, reject) => this.invalidForm(reject)
|
|
|
|
);
|
2017-02-21 10:36:43 +00:00
|
|
|
}
|
2017-02-06 17:01:04 +00:00
|
|
|
if (!this.dataChanged()) {
|
2017-03-07 11:37:59 +00:00
|
|
|
return new Promise(
|
2017-02-21 10:36:43 +00:00
|
|
|
(resolve, reject) => this.noChanges(reject)
|
2017-02-07 16:38:30 +00:00
|
|
|
);
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-02-21 10:36:43 +00:00
|
|
|
let changedData = getModifiedData(this.data, this.orgData);
|
|
|
|
|
2017-03-07 11:37:59 +00:00
|
|
|
if (this.save) {
|
2017-02-21 10:36:43 +00:00
|
|
|
this.save.model = changedData;
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
this.save.accept().then(
|
|
|
|
json => this.writeData({data: json}, resolve),
|
|
|
|
json => reject(json)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX: Alternative when mgCrud is not used
|
2017-02-06 17:01:04 +00:00
|
|
|
|
2017-02-07 11:58:25 +00:00
|
|
|
let id = this.orgData[this.idField];
|
2017-02-06 17:01:04 +00:00
|
|
|
|
2017-03-07 11:37:59 +00:00
|
|
|
if (id) {
|
2017-02-07 11:58:25 +00:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-06-03 11:01:47 +00:00
|
|
|
this.$http.patch(`${this.url}/${id}`, changedData).then(
|
2017-02-07 16:02:17 +00:00
|
|
|
json => this.writeData(json, resolve),
|
2017-02-07 11:58:25 +00:00
|
|
|
json => reject(json)
|
|
|
|
);
|
|
|
|
});
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-03-07 11:37:59 +00:00
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
this.$http.post(this.url, this.data).then(
|
|
|
|
json => this.writeData(json, resolve),
|
|
|
|
json => reject(json)
|
|
|
|
);
|
|
|
|
});
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-07 16:02:17 +00:00
|
|
|
writeData(json, resolve) {
|
2017-10-05 07:31:28 +00:00
|
|
|
Object.assign(this.data, json.data);
|
|
|
|
this.updateOriginalData();
|
2017-02-07 16:02:17 +00:00
|
|
|
resolve(json);
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-21 10:36:43 +00:00
|
|
|
noChanges(resolve) {
|
2017-06-05 07:01:21 +00:00
|
|
|
this.vnApp.showMessage(
|
2017-02-21 10:36:43 +00:00
|
|
|
this.$translate.instant('No changes to save')
|
|
|
|
);
|
|
|
|
resolve();
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-21 10:36:43 +00:00
|
|
|
invalidForm(resolve) {
|
2017-06-05 07:01:21 +00:00
|
|
|
this.vnApp.showMessage(
|
2017-02-21 10:36:43 +00:00
|
|
|
this.$translate.instant('Some fields are invalid')
|
|
|
|
);
|
|
|
|
resolve();
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-10-05 07:31:28 +00:00
|
|
|
updateOriginalData() {
|
|
|
|
this.orgData = this.copyInNewObject(this.data);
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-10-05 07:31:28 +00:00
|
|
|
copyInNewObject(data) {
|
|
|
|
let newCopy = {};
|
|
|
|
if (data && typeof data === 'object') {
|
2017-07-13 12:55:07 +00:00
|
|
|
Object.keys(data).forEach(
|
|
|
|
val => {
|
2017-10-05 07:20:40 +00:00
|
|
|
if (data[val] !== "" && data[val] !== undefined && data[val] !== null) {
|
|
|
|
if (typeof data[val] === 'object') {
|
2017-10-05 07:31:28 +00:00
|
|
|
newCopy[val] = this.copyInNewObject(data[val]);
|
2017-10-05 07:20:40 +00:00
|
|
|
} else {
|
2017-10-05 07:31:28 +00:00
|
|
|
newCopy[val] = data[val];
|
2017-10-05 07:20:40 +00:00
|
|
|
}
|
|
|
|
}
|
2017-07-13 12:55:07 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2017-10-05 07:31:28 +00:00
|
|
|
return newCopy;
|
2017-07-13 12:55:07 +00:00
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
callback(transition) {
|
2017-09-21 10:24:14 +00:00
|
|
|
let dataChanged = this.dataChanged();
|
|
|
|
if (!this.state && dataChanged) {
|
2017-02-06 17:01:04 +00:00
|
|
|
this.state = transition.to().name;
|
2017-02-07 16:38:30 +00:00
|
|
|
this.$scope.confirm.show();
|
2017-02-06 17:01:04 +00:00
|
|
|
return false;
|
|
|
|
}
|
2017-03-07 11:37:59 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
dataChanged() {
|
2017-10-05 07:31:28 +00:00
|
|
|
let newData = this.copyInNewObject(this.data);
|
2017-10-05 07:51:27 +00:00
|
|
|
return !isEqual(newData, this.orgData);
|
2017-02-06 17:01:04 +00:00
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-02-06 17:01:04 +00:00
|
|
|
onConfirmResponse(response) {
|
2017-03-07 11:37:59 +00:00
|
|
|
if (response === 'ACCEPT') {
|
2017-10-05 07:20:40 +00:00
|
|
|
Object.assign(this.data, this.orgData);
|
2017-02-06 17:01:04 +00:00
|
|
|
this.$state.go(this.state);
|
2017-03-07 11:37:59 +00:00
|
|
|
} else {
|
2017-02-06 17:01:04 +00:00
|
|
|
this.state = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-04 11:27:39 +00:00
|
|
|
|
2017-10-05 07:53:40 +00:00
|
|
|
Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate'];
|
2017-02-06 17:01:04 +00:00
|
|
|
|
|
|
|
module.component('vnWatcher', {
|
2017-05-31 08:28:39 +00:00
|
|
|
template: require('./watcher.html'),
|
2017-02-06 17:01:04 +00:00
|
|
|
bindings: {
|
|
|
|
url: '@?',
|
|
|
|
idField: '@?',
|
2017-02-07 11:58:25 +00:00
|
|
|
data: '<',
|
2017-02-21 10:36:43 +00:00
|
|
|
form: '<',
|
|
|
|
save: '<',
|
2017-02-07 11:58:25 +00:00
|
|
|
get: '=?'
|
2017-02-06 17:01:04 +00:00
|
|
|
},
|
|
|
|
controller: Watcher
|
|
|
|
});
|