salix/client/core/src/components/watcher/watcher.js

223 lines
6.2 KiB
JavaScript
Raw Normal View History

2018-02-10 15:18:01 +00:00
import ngModule from '../../module';
import Component from '../../lib/component';
import getModifiedData from '../../lib/modified';
import copyObject from '../../lib/copy';
import isEqual from '../../lib/equals';
import isFullEmpty from '../../lib/full-empty';
/**
* 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 {
2018-01-09 12:49:15 +00:00
constructor($element, $scope, $state, $transitions, $http, vnApp, $translate, $attrs) {
super($element);
this.$scope = $scope;
this.$state = $state;
this.$http = $http;
2017-02-07 16:38:30 +00:00
this.$translate = $translate;
2018-01-09 12:49:15 +00:00
this.$attrs = $attrs;
this.vnApp = vnApp;
this.state = null;
this.deregisterCallback = $transitions.onStart({},
transition => this.callback(transition));
2017-10-05 07:31:28 +00:00
this.updateOriginalData();
}
$onInit() {
2017-09-28 09:29:01 +00:00
if (this.get && this.url) {
this.fetchData();
2017-09-28 09:29:01 +00:00
} else if (this.get && !this.url) {
throw new Error('Error: Parameter url ommitted');
}
}
$onChanges(changes) {
if (this.data) {
2017-10-05 07:31:28 +00:00
this.updateOriginalData();
}
}
$onDestroy() {
this.deregisterCallback();
}
fetchData() {
let id = this.data[this.idField];
2018-02-08 12:13:42 +00:00
// return new Promise((resolve, reject) => {
2017-09-28 09:29:01 +00:00
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)
);
2018-02-08 12:13:42 +00:00
// });
}
2018-02-08 12:13:42 +00:00
2017-03-07 16:11:56 +00:00
/**
* Submits the data and goes back in the history.
2018-02-08 12:13:42 +00:00
*
* @return {Promise} The request promise
2017-03-07 16:11:56 +00:00
*/
submitBack() {
return this.submit().then(
2017-03-07 16:11:56 +00:00
() => this.window.history.back()
);
}
2018-02-08 12:13:42 +00:00
2017-06-03 11:01:47 +00:00
/**
* Submits the data and goes another state.
*
* @param {String} state The state name
2018-02-08 12:13:42 +00:00
* @param {Object} params The request params
* @return {Promise} The request promise
2017-06-03 11:01:47 +00:00
*/
2017-12-04 07:17:29 +00:00
submitGo(state, params) {
return this.submit().then(
2017-12-04 07:17:29 +00:00
() => this.$state.go(state, params || {})
2017-06-03 11:01:47 +00:00
);
}
2018-02-08 12:13:42 +00:00
2017-03-07 16:11:56 +00:00
/**
* Submits the data to the server.
*
* @return {Promise} The http request promise
*/
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
}
if (!this.dataChanged()) {
return new Promise(
2017-02-21 10:36:43 +00:00
(resolve, reject) => this.noChanges(reject)
2017-02-07 16:38:30 +00:00
);
}
2018-02-08 11:57:57 +00:00
let changedData = (this.$attrs.save && this.$attrs.save.toLowerCase() === 'post')
? this.copyInNewObject(this.data)
: getModifiedData(this.data, this.orgData);
2017-02-21 10:36:43 +00:00
2018-02-01 12:28:45 +00:00
if (this.save && this.save.accept) {
2018-01-09 08:50:08 +00:00
this.save.model = changedData; // this.copyInNewObject(changedData);
2017-02-21 10:36:43 +00:00
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
2018-02-01 12:28:45 +00:00
let id = this.idField ? this.orgData[this.idField] : null;
if (id) {
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),
json => reject(json)
);
});
}
return new Promise((resolve, reject) => {
2018-02-01 12:28:45 +00:00
this.$http.post(this.url, changedData).then(
json => this.writeData(json, resolve),
json => reject(json)
);
});
}
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-02-21 10:36:43 +00:00
noChanges(resolve) {
this.vnApp.showMessage(
2017-02-21 10:36:43 +00:00
this.$translate.instant('No changes to save')
);
resolve();
}
2017-02-21 10:36:43 +00:00
invalidForm(resolve) {
this.vnApp.showMessage(
2017-02-21 10:36:43 +00:00
this.$translate.instant('Some fields are invalid')
);
resolve();
}
2017-10-05 07:31:28 +00:00
updateOriginalData() {
this.orgData = this.copyInNewObject(this.data);
2018-02-06 08:33:37 +00:00
if (this.form && this.form.$dirty)
this.form.$setPristine();
}
2017-10-05 07:31:28 +00:00
copyInNewObject(data) {
let newCopy = {};
if (data && typeof data === 'object') {
Object.keys(data).forEach(
val => {
2017-12-21 13:09:16 +00:00
if (!isFullEmpty(data[val])) {
2017-10-05 07:20:40 +00:00
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-10-05 07:31:28 +00:00
return newCopy;
}
callback(transition) {
2017-09-21 10:24:14 +00:00
let dataChanged = this.dataChanged();
if (!this.state && dataChanged) {
this.state = transition.to().name;
2017-02-07 16:38:30 +00:00
this.$scope.confirm.show();
return false;
}
return true;
}
dataChanged() {
2018-02-01 12:28:45 +00:00
if (this.form && this.form.$dirty) return true;
2017-10-05 07:31:28 +00:00
let newData = this.copyInNewObject(this.data);
return !isEqual(newData, this.orgData);
}
onConfirmResponse(response) {
if (response === 'ACCEPT') {
2017-10-05 07:20:40 +00:00
Object.assign(this.data, this.orgData);
this.$state.go(this.state);
} else {
this.state = null;
}
}
}
2018-01-09 12:49:15 +00:00
Watcher.$inject = ['$element', '$scope', '$state', '$transitions', '$http', 'vnApp', '$translate', '$attrs'];
2018-02-10 15:18:01 +00:00
ngModule.component('vnWatcher', {
2017-05-31 08:28:39 +00:00
template: require('./watcher.html'),
bindings: {
url: '@?',
idField: '@?',
data: '<',
2017-02-21 10:36:43 +00:00
form: '<',
save: '<',
get: '=?'
},
controller: Watcher
});