wisemapping-frontend/packages/mindplot/src/components/RestPersistenceManager.ts

176 lines
5.6 KiB
TypeScript
Raw Normal View History

2021-07-16 16:41:58 +02:00
/*
2021-12-25 23:39:34 +01:00
* Copyright [2021] [wisemapping]
2021-07-16 16:41:58 +02:00
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
2021-12-04 01:11:17 +01:00
import { $assert } from '@wisemapping/core-js';
import $ from 'jquery';
2021-12-15 02:54:11 +01:00
import { $msg } from './Messages';
2022-02-21 03:50:03 +01:00
import PersistenceManager, { PersistenceError } from './PersistenceManager';
2021-07-16 16:41:58 +02:00
class RESTPersistenceManager extends PersistenceManager {
2022-01-31 03:33:26 +01:00
private documentUrl: string;
2022-01-31 14:12:05 +01:00
2022-01-31 03:33:26 +01:00
private revertUrl: string;
2022-01-31 14:12:05 +01:00
2022-01-31 03:33:26 +01:00
private lockUrl: string;
2022-01-31 14:12:05 +01:00
2022-01-31 03:33:26 +01:00
private onSave: boolean;
2022-01-31 14:12:05 +01:00
2022-01-31 03:33:26 +01:00
private clearTimeout;
2022-03-24 03:33:44 +01:00
constructor(options: { documentUrl: string, revertUrl: string, lockUrl: string }) {
2021-10-05 02:05:34 +02:00
$assert(options.documentUrl, 'documentUrl can not be null');
$assert(options.revertUrl, 'revertUrl can not be null');
$assert(options.lockUrl, 'lockUrl can not be null');
super();
2021-10-05 02:05:34 +02:00
this.documentUrl = options.documentUrl;
this.revertUrl = options.revertUrl;
this.lockUrl = options.lockUrl;
2021-12-05 00:39:20 +01:00
}
2021-10-05 02:05:34 +02:00
2022-02-14 03:06:50 +01:00
saveMapXml(mapId: string, mapXml: Document, pref: string, saveHistory: boolean, events): void {
2021-10-05 02:05:34 +02:00
const data = {
id: mapId,
2022-02-14 03:06:50 +01:00
xml: new XMLSerializer().serializeToString(mapXml),
2021-10-05 02:05:34 +02:00
properties: pref,
};
2022-03-24 03:33:44 +01:00
const query = `minor=${!saveHistory}`;
2021-10-05 02:05:34 +02:00
2022-01-31 03:33:26 +01:00
if (!this.onSave) {
2021-10-05 02:05:34 +02:00
// Mark save in process and fire a event unlocking the save ...
2022-01-31 03:33:26 +01:00
this.onSave = true;
this.clearTimeout = setTimeout(() => {
this.clearTimeout = null;
this.onSave = false;
}, 10000);
2021-10-05 02:05:34 +02:00
2022-01-31 03:33:26 +01:00
const persistence = this;
2022-02-14 03:06:50 +01:00
fetch(
`${this.documentUrl.replace('{id}', mapId)}?${query}`,
{
method: 'PUT',
2022-02-18 19:00:26 +01:00
// Blob helps to resuce the memory on large payload.
body: new Blob([JSON.stringify(data)], { type: 'text/plain' }),
2022-02-21 03:50:03 +01:00
headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json', 'X-CSRF-Token': this.getCSRFToken() },
},
2022-02-14 03:06:50 +01:00
).then(async (response: Response) => {
if (response.ok) {
events.onSuccess();
} else {
console.log(`Saving error: ${response.status}`);
let userMsg;
if (response.status === 405) {
2022-02-21 03:50:03 +01:00
userMsg = { severity: 'SEVERE', message: $msg('SESSION_EXPIRED'), errorType: 'session-expired' };
2022-02-14 03:06:50 +01:00
} else {
const responseText = await response.text();
const contentType = response.headers['Content-Type'];
if (contentType != null && contentType.indexOf('application/json') !== -1) {
let serverMsg = null;
try {
serverMsg = JSON.parse(responseText);
serverMsg = serverMsg.globalSeverity ? serverMsg : null;
} catch (e) {
// Message could not be decoded ...
}
userMsg = persistence._buildError(serverMsg);
}
2021-10-05 02:05:34 +02:00
}
2022-02-21 03:50:03 +01:00
this.triggerError(userMsg);
2021-10-05 02:05:34 +02:00
events.onError(userMsg);
2022-02-14 03:06:50 +01:00
}
// Clear event timeout ...
if (persistence.clearTimeout) {
clearTimeout(persistence.clearTimeout);
}
persistence.onSave = false;
2022-02-21 03:50:03 +01:00
}).catch(() => {
const userMsg: PersistenceError = {
severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED'), errorType: 'generic',
};
this.triggerError(userMsg);
2022-02-14 03:06:50 +01:00
events.onError(userMsg);
// Clear event timeout ...
if (persistence.clearTimeout) {
clearTimeout(persistence.clearTimeout);
}
persistence.onSave = false;
2021-10-05 02:05:34 +02:00
});
}
2021-12-05 00:39:20 +01:00
}
2021-10-05 02:05:34 +02:00
2022-01-31 03:33:26 +01:00
discardChanges(mapId: string) {
2022-02-14 03:06:50 +01:00
fetch(this.revertUrl.replace('{id}', mapId),
{
method: 'POST',
2022-02-21 03:50:03 +01:00
headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json', 'X-CSRF-Token': this.getCSRFToken() },
2022-02-14 03:06:50 +01:00
});
2021-12-05 00:39:20 +01:00
}
2021-10-05 02:05:34 +02:00
2022-02-18 19:00:26 +01:00
unlockMap(mapId: string): void {
2022-02-14 03:06:50 +01:00
fetch(
this.lockUrl.replace('{id}', mapId),
{
2022-02-18 19:00:26 +01:00
method: 'PUT',
2022-02-21 03:50:03 +01:00
headers: { 'Content-Type': 'text/plain', 'X-CSRF-Token': this.getCSRFToken() },
2022-02-14 03:06:50 +01:00
body: 'false',
2021-12-25 21:09:02 +01:00
},
2022-02-14 03:06:50 +01:00
);
2021-12-05 00:39:20 +01:00
}
2021-10-05 02:05:34 +02:00
2022-01-31 03:33:26 +01:00
private _buildError(jsonSeverResponse) {
2021-10-05 02:05:34 +02:00
let message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
let severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
if (!message) {
message = $msg('SAVE_COULD_NOT_BE_COMPLETED');
}
2021-07-16 16:41:58 +02:00
2021-10-05 02:05:34 +02:00
if (!severity) {
severity = 'INFO';
}
return { severity, message };
2021-12-05 00:39:20 +01:00
}
2021-10-05 02:05:34 +02:00
2022-01-31 03:33:26 +01:00
loadMapDom(mapId: string): Document {
let xml: Document;
2021-10-05 02:05:34 +02:00
$.ajax({
url: `${this.documentUrl.replace('{id}', mapId)}/xml`,
method: 'get',
async: false,
2022-02-21 03:50:03 +01:00
headers: { 'Content-Type': 'text/plain', Accept: 'application/xml', 'X-CSRF-Token': this.getCSRFToken() },
2021-10-05 02:05:34 +02:00
success(responseText) {
xml = responseText;
},
2021-12-25 21:09:02 +01:00
error(xhr, ajaxOptions, thrownError) {
console.error(`Request error => status:${xhr.status} ,thrownError: ${thrownError}`);
},
2021-10-05 02:05:34 +02:00
});
// If I could not load it from a file, hard code one.
if (xml == null) {
2021-12-25 21:09:02 +01:00
throw new Error(`Map with id ${mapId} could not be loaded`);
2021-07-16 16:41:58 +02:00
}
2021-10-05 02:05:34 +02:00
return xml;
2021-12-05 00:39:20 +01:00
}
}
2021-07-16 16:41:58 +02:00
export default RESTPersistenceManager;