-
Tor-Einar Skog authoredTor-Einar Skog authored
Sync.vue 31.49 KiB
<!--
Copyright (c) 2022 NIBIO <http://www.nibio.no/>.
This file is part of VIPSObservationApp.
VIPSObservationApp is free software: you can redistribute it and/or modify
it under the terms of the NIBIO Open Source License as published by
NIBIO, either version 1 of the License, or (at your option) any
later version.
VIPSObservationApp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
NIBIO Open Source License for more details.
You should have received a copy of the NIBIO Open Source License
along with VIPSObservationApp. If not, see <http://www.nibio.no/licenses/>.
Author: Bhabesh Bhabani Mukhopadhyay
Author: Tor-Einar Skog <tor-einar.skog@nibio.no>
Dated : 19-Aug-2021
-->
<template>
<div>
<div v-if="loading">
<div class="spinner-border text-success" role="status">
</div> <span class="text-danger"> Data Loading...</span>
<!-- -- Sync : <div v-html="isSyncNeeded"></div> -->
</div>
<div v-show="isMounted">
<common-util ref="CommonUtil" />
</div>
</div>
</template>
<script>
import CommonUtil from "@/components/CommonUtil";
export default {
name: "Sync",
components: {CommonUtil},
props: {
isSyncNeeded: Boolean
},
data() {
return {
isMounted: false,
CONST_URL_DOMAIN: '',
booIsSyncOneWayReady: false,
booIsSyncTwoWayReady: false,
arrSyncOneWay: [
{"name": CommonUtil.CONST_STORAGE_CROP_CATEGORY, "complete": false},
{"name": CommonUtil.CONST_STORAGE_CROP_LIST, "complete": false},
{"name": CommonUtil.CONST_STORAGE_PEST_LIST, "complete": false},
{"name": CommonUtil.CONST_STORAGE_CROP_PEST_LIST, "complete": false},
{"name": CommonUtil.CONST_STORAGE_VISIBILITY_POLYGON, "complete": false},
],
arrSyncTwoWay: [
{"name": CommonUtil.CONST_STORAGE_OBSERVATION_LIST, "complete": false},
{"name": CommonUtil.CONST_STORAGE_POI_LIST, "complete": false},
],
appUser: {},
loading: false,
counterTwoWaySyncPOST: 0,
totalTwoWaySyncPOST: 0,
counterTwoWaySyncPOST: 0,
};
},
watch: {
booIsSyncOneWayReady:
{
immediate: true,
handler(val, oldVal) {
if (val) {
/* Starting of Sync */
CommonUtil.logInfo('----- SYNC ONE WAY STARTED -----');
this.syncOneWay();
}
if (typeof (booIsSyncOneWayReady) === undefined) {
this.loading = false;
/* refresh for next time */
this.refreshOneWaySyncItems();
}
if (typeof (booIsSyncOneWayReady) == false) {
this.loading = false;
}
}
},
booIsSyncTwoWayReady:
{
immediate: true,
handler(val, oldVal) {
if (val) {
this.loading = true;
CommonUtil.logInfo('----- SYNC TWO WAY STARTED -----');
this.syncTwoWayAtLogin();
this.loading = false;
}
}
}
},
methods: {
/** One way Sync. Fetching the data from server and stored in local storage */
syncOneWay() {
if (this.booIsSyncOneWayReady) {
this.loading = true;
let appUser = this.appUser;
let funStorageSet = this.oneWaySyncStorageSet;
if (typeof (appUser) == undefined || appUser == null || appUser === '') {
// TODO if appUser is not available
}
else {
let strUrl = '';
let This = this;
$.each(this.arrSyncOneWay, function (index, value) {
switch (value.name) {
case CommonUtil.CONST_STORAGE_CROP_CATEGORY:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_CROP_CATEGORY + appUser.organization_id;
break;
case CommonUtil.CONST_STORAGE_CROP_LIST:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_CROP_LIST;
break;
case CommonUtil.CONST_STORAGE_PEST_LIST:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_PEST_LIST + '?organizationId=' + appUser.organization_id;
break;
case CommonUtil.CONST_STORAGE_CROP_PEST_LIST:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_CROP_PEST_LIST;
break;
case CommonUtil.CONST_STORAGE_VISIBILITY_POLYGON:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_POLYGON_SERVICES + appUser.organization_id;
break;
default:
}
funStorageSet(value, strUrl);
});
}
this.loading = false;
}
},
syncTwoWayAtLogin() {
let appUser = this.appUser;
let funStorageSet = this.oneWaySyncStorageSet;
if (typeof (appUser) == undefined || appUser == null || appUser === '') {
// TODO if appUser is not available
}
else {
this.syncTwoWay();
}
},
syncTwoWay() {
// Run this only when we are online
if (navigator.onLine) {
let strUrl = '';
let This = this;
$.each(this.arrSyncTwoWay, function (index, value) {
switch (value.name) {
case CommonUtil.CONST_STORAGE_OBSERVATION_LIST:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_USER_OBSERVATION_LIST;
break;
case CommonUtil.CONST_STORAGE_POI_LIST:
strUrl = This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_USER_POI;
break;
default:
}
This.syncTwoWayInitiate(value, strUrl);
});
}
},
/** Writing server data to localstorage using sync */
oneWaySyncStorageSet(value, strUrl) {
fetch(strUrl)
.then((response) => response.json())
.then((data) => {
localStorage.setItem(value.name, JSON.stringify(data));
value.complete = true;
this.setOneWaySyncStatus(value);
});
},
/** Set status whether the sync of items completed or not */
setOneWaySyncStatus(itemValue) {
let booFlag;
/* Set the status - array value status set by reference */
$.each(this.arrSyncOneWay, function (index, value) {
if (value.name === itemValue.name) {
value.complete = itemValue.complete;
}
});
/* Set the global flag - to mark the end of sync*/
$.each(this.arrSyncOneWay, function (index, value) {
if (value.complete === false) {
booFlag = false;
}
});
this.booIsSyncOneWayReady = booFlag;
},
/** Reset One way sync items */
refreshOneWaySyncItems() {
$.each(this.arrSyncOneWay, function (index, value) {
value.complete = false;
})
this.booIsSyncOneWayReady = false;
},
/** Deciding factor whether oneway should start or not */
isSyncOnewayNeeded(loggedUser) {
if (!this.booIsSyncOneWayReady) {
this.syncOneWayEmptyProduct(loggedUser);
this.syncOneWayDifferentUser(loggedUser);
this.syncOneWayDifferentTimeStamp(loggedUser);
}
},
/** Oneway Sync on empty products in store -- (e.g. first time) */
syncOneWayEmptyProduct(appUser) {
let booLocalIsSyncOneWayReady = false;
if (!this.booIsSyncOneWayReady) {
$.each(this.arrSyncOneWay, function (index, value) {
let strItem = localStorage.getItem(value.name);
/** Check empty local storage */
if (typeof (strItem) == undefined || strItem == null || strItem === '') {
booLocalIsSyncOneWayReady = true;
return false;
}
});
this.booIsSyncOneWayReady = booLocalIsSyncOneWayReady;
this.appUser = appUser;
}
},
/** Oneway Sync For Different user login */
syncOneWayDifferentUser(loggedUser) {
if (!this.booIsSyncOneWayReady) {
let userStored = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_USER_DETAIL));
if (userStored.userId != loggedUser.userId) {
this.booIsSyncOneWayReady = true;
this.appUser = loggedUser;
}
}
},
/** Oneway sync for different timestamp (e.g. changes in server) */
syncOneWayDifferentTimeStamp(appUser) {
if (!this.booIsSyncOneWayReady) {
let strStoreTimeStamp = localStorage.getItem(CommonUtil.CONST_STORE_TIMESTAMP);
let jsonHeader = {Authorization: appUser.userUuid};
fetch(
this.CONST_URL_DOMAIN + CommonUtil.CONST_URL_LAST_TIMESTAMP,
{
method: "GET",
headers: jsonHeader,
}
)
.then((response) => response.json())
.then((data) => {
if (typeof (strStoreTimeStamp) == undefined || strStoreTimeStamp == null || strStoreTimeStamp === '') {
localStorage.setItem(CommonUtil.CONST_STORE_TIMESTAMP, JSON.stringify(data));
this.booIsSyncOneWayReady = true;
this.appUser = appUser;
}
else {
let jsonServerTimeStamp = data;
let jsonStoredTimeStamp = JSON.parse(strStoreTimeStamp);
let jsTimeStamp = new Date(jsonServerTimeStamp.lastUpdated);
let dtStoreTimeStamp = new Date(jsonStoredTimeStamp.lastUpdated);
if (jsTimeStamp.getTime() != dtStoreTimeStamp.getTime()) {
this.booIsSyncOneWayReady = true;
this.appUser = appUser;
localStorage.setItem(CommonUtil.CONST_STORE_TIMESTAMP, JSON.stringify(data));
}
}
});
}
},
/** Decide which two way sync will start */
syncTwoWayInitiate(value, strUrl) {
switch (value.name) {
case CommonUtil.CONST_STORAGE_OBSERVATION_LIST:
this.syncTwoWayObservation(value, strUrl);
break;
case CommonUtil.CONST_STORAGE_POI_LIST:
this.syncTwoWayPOI(value, strUrl);
break;
default:
}
},
/** Two way Sync POI */
syncTwoWayPOI(value, strUrl) {
this.syncPOISendPrepare(value);
},
/** Findout which data at POI need to be synced */
syncPOISendPrepare(value) {
let This = this;
let lstPOI = JSON.parse(localStorage.getItem(value.name));
if (lstPOI) {
let lstPOIUpload = lstPOI.filter(poi => poi.uploaded === false);
this.totalTwoWaySyncPOST = lstPOIUpload.length;
if (lstPOIUpload && lstPOIUpload.length != 0) {
lstPOIUpload.forEach(function (poi) {
This.syncPOIPOST(poi, This.totalTwoWaySyncPOST);
})
}
else {
/** Create the list using GET */
let totalTwoWaySyncPOST = 0;
let updatedPOI = {};
This.getPOIFromServerTwowaySync(totalTwoWaySyncPOST, updatedPOI);
}
}
else {
/** Create the list using GET */
this.getPOIFromServerTwowaySync(0, undefined);
}
},
/** Posting required POI data for sync */
syncPOIPOST(poi, totalTwoWaySyncPOST) {
let This = this;
let userUUID = localStorage.getItem(CommonUtil.CONST_STORAGE_UUID);
let jsonBody = null;
if (poi.deleted) {
/** prepare POI object for server Delete Operation */
let delPOI = {};
delPOI.pointOfInterestId = poi.pointOfInterestId;
delPOI.deleted = poi.deleted;
jsonBody = JSON.stringify(delPOI);
this.removeLocalPOI(poi.pointOfInterestId);
}
else {
jsonBody = JSON.stringify(poi);
}
fetch(
This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_SYNC_UPDATE_POI,
{
method: "POST",
headers: {
"Content-Type": "application/json",
'Authorization': userUUID
},
body: jsonBody
})
.then(function (response) {
if (response.status === 200) {
}
else {
/** Even if the response is not success, still need to increase the counter,
* to decide for next action after all PUSH */
This.counterTwoWaySyncPOST = This.counterTwoWaySyncPOST + 1;
if (response.status === 500) {
return false;
}
}
return response.text()
})
.then((data) => {
if (data) {
let updatedPOI = JSON.parse(data);
if (updatedPOI.deleted) {
This.removeLocalPOI(poupdatedPOI.pointOfInterestId);
}
else {
if (poi.pointOfInterestId < 0) {
let indexPosition = null;
let lstPOI = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_POI_LIST));
$.each(lstPOI, function (index, jsonPOI) {
if (poi.pointOfInterestId == jsonPOI.pointOfInterestId) {
indexPosition = index;
return false;
}
})
if (indexPosition) {
/** Remove/delete the POI with nagative number (localy created ) */
lstPOI.splice(indexPosition, 1);
localStorage.setItem(CommonUtil.CONST_STORAGE_POI_LIST, JSON.stringify(lstPOI));
this.getPOIFromServerTwowaySync(1, updatedPOI);
}
}
if (poi.pointOfInterestId === updatedPOI.pointOfInterestId) {
this.updatePOIPOST(updatedPOI, totalTwoWaySyncPOST);
}
}
}
})
},
/** Update POI after response from server */
updatePOIPOST(updatedPOI, totalTwoWaySyncPOST) {
let lstPOI = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_POI_LIST));
let counter = undefined;
$.each(lstPOI, function (index, jsonPOI) {
if (jsonPOI.pointOfInterestId === updatedPOI.pointOfInterestId) {
counter = index;
return false;
}
});
if (counter) {
lstPOI[counter] = updatedPOI;
localStorage.setItem(CommonUtil.CONST_STORAGE_POI_LIST, JSON.stringify(lstPOI));
this.counterTwoWaySyncPOST = this.counterTwoWaySyncPOST + 1;
CommonUtil.logInfo('total number of upload : ' + totalTwoWaySyncPOST + ' ---- counter value : ' + this.counterTwoWaySyncPOST);
if (this.counterTwoWaySyncPOST === totalTwoWaySyncPOST) {
this.counterTwoWaySyncPOST = 0;
this.getPOIFromServerTwowaySync(totalTwoWaySyncPOST, updatedPOI);
}
}
},
/** GET POIs */
getPOIFromServerTwowaySync(totalTwoWaySyncPOST, updatedPOI) {
let This = this;
let strUUID = localStorage.getItem(CommonUtil.CONST_STORAGE_UUID);
let jsonHeader = {Authorization: strUUID};
fetch(This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_USER_POI, {
method: "GET",
headers: jsonHeader,
}).then((response) => response.json())
.then((data) => {
let serverPOIs = data;
if (localStorage.getItem(CommonUtil.CONST_STORAGE_POI_LIST)) {
let lstLocalPOI = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_POI_LIST));
serverPOIs.forEach(function (serverPOI) {
let arrIndex = undefined;
let booNoRecordFound = false;
let booRecordFound = false;
$.each(lstLocalPOI, function (index, localPOI) {
if (serverPOI.pointOfInterestId === localPOI.pointOfInterestId) {
booRecordFound = true;
if (updatedPOI && (totalTwoWaySyncPOST === 1 && updatedPOI.pointOfInterestId === serverPOI.pointOfInterestId)) {
}
else {
if (serverPOI.lastEditedTime) {
let srvDate = new Date(serverPOI.lastEditedTime);
let localDate = new Date(localPOI.lastEditedTime);
if (srvDate >= localDate) {
arrIndex = index;
return false;
}
}
else {
arrIndex = index;
return false;
}
}
}
});
if (booRecordFound) {}
else {
booNoRecordFound = true;
}
if (arrIndex) {
lstLocalPOI[arrIndex] = serverPOI;
}
if (booNoRecordFound) {
lstLocalPOI.push(serverPOI);
return false;
}
});
localStorage.setItem(CommonUtil.CONST_STORAGE_POI_LIST, JSON.stringify(lstLocalPOI));
}
else {
localStorage.setItem(CommonUtil.CONST_STORAGE_POI_LIST, JSON.stringify(serverPOIs));
}
// Update the POI list after sync
if (this.$root.sharedState.placesListComponent != undefined) {
this.$root.sharedState.placesListComponent.getPOIListFromStore();
}
})
},
/** Remove local POI */
removeLocalPOI(id) {
let lstPOI = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_POI_LIST));
let indexPosition = null;
$.each(lstPOI, function (index, poi) {
if (poi.pointOfInterestId === id) {
indexPosition = index;
return false;
}
});
if (indexPosition) {
lstPOI.splice(indexPosition, 1);
localStorage.setItem(CommonUtil.CONST_STORAGE_POI_LIST, JSON.stringify(lstPOI));
}
},
/** Two way Sync - Observation */
syncTwoWayObservation(value, strUrl) {
this.syncObservationSendPrepare(value);
},
/** Sync - Observation - embed with image data for POST */
syncObservationSendPrepare(value) {
let This = this;
let lstObservations = JSON.parse(localStorage.getItem(value.name));
if (lstObservations) {
let lstObservationUpload = lstObservations.filter(observation => observation.uploaded === false);
this.totalTwoWaySyncPOST = lstObservationUpload.length;
if (lstObservationUpload && lstObservationUpload.length != 0) {
lstObservationUpload.forEach(function (observation) {
//CommonUtil.logInfo("syncObservationSendPrepare:observation.geoinfo= " + observation.geoinfo);
let observationForStore = {};
observationForStore.observationId = observation.observationId;
observationForStore.cropOrganismId = observation.cropOrganismId;
observationForStore.organismId = observation.organismId
observationForStore.timeOfObservation = observation.timeOfObservation;
observationForStore.isPositive = observation.isPositive;
observationForStore.statusChangedTime = observation.statusChangedTime;
observationForStore.statusTypeId = observation.statusTypeId;
observationForStore.isQuantified = observation.isQuantified;
observationForStore.userId = observation.userId;
observationForStore.geoinfo = observation.geoinfo;
observationForStore.locationPointOfInterestId = observation.locationPointOfInterestId;
observationForStore.broadcastMessage = observation.broadcastMessage;
observationForStore.statusRemarks = observation.statusRemarks;
observationForStore.observationHeading = observation.observationHeading;
observationForStore.observationText = observation.observationText;
observationForStore.observationData = observation.observationData;
observationForStore.locationIsPrivate = observation.locationIsPrivate;
observationForStore.polygonService = observation.polygonService;
observationForStore.uploaded = observation.uploaded;
observationForStore.observationIllustrationSet = observation.observationIllustrationSet;
if (observation.deleted) {
observationForStore.deleted = observation.deleted;
}
This.syncObservationSendPrepareSingleObject(observationForStore, This.totalTwoWaySyncPOST);
});
}
else {
let totalTwoWaySyncPOST = 0;
let updatedObservation = {};
/** GET Observations */
this.getObservationsFromServerTwowaySync(totalTwoWaySyncPOST, updatedObservation);
}
}
else {
this.getObservationsFromServerTwowaySync(0, undefined);
}
},
/** Prepare a single object includes image data */
syncObservationSendPrepareSingleObject(observation, totalTwoWaySyncPOST, syncObservationPOST) {
let This = this;
let entityName = CommonUtil.CONST_DB_ENTITY_PHOTO;
if (observation.uploaded === false) {
let observationUpload = observation;
let observationIllustrationSet = observationUpload.observationIllustrationSet;
// talk to Innodb, embed image data to JSON POST and exit
let dbRequest = indexedDB.open(CommonUtil.CONST_DB_NAME, CommonUtil.CONST_DB_VERSION);
dbRequest.onsuccess = function (evt) {
let db = evt.target.result;
if (db.objectStoreNames.contains(entityName)) {
let transaction = db.transaction([entityName], 'readwrite');
let objectstore = transaction.objectStore(entityName);
if (observationIllustrationSet) {
observationIllustrationSet.forEach(function (illustration) {
let fileName = illustration.observationIllustrationPK.fileName;
let objectstoreRequest = objectstore.get(fileName);
objectstoreRequest.onsuccess = function (event) {
let observationImage = event.target.result;
if (observationImage) {
let imageTextData = observationImage.illustration.imageTextData;
illustration.imageTextData = imageTextData;
}
}
});
}
transaction.oncomplete = function () {
This.syncObservationPOST(observation, totalTwoWaySyncPOST);
}
}
else {
This.syncObservationPOST(observation, totalTwoWaySyncPOST);
db.close();
}
db.close();
}
}
},
/** Posting Observation data to VIPS server for sync */
syncObservationPOST(observation, totalTwoWaySyncPOST) {
//CommonUtil.logInfo("syncObservationPOST: observation.geoinfo=" + observation.geoinfo);
let This = this;
//if(this.isSyncNeeded)
{
let userUUID = localStorage.getItem(CommonUtil.CONST_STORAGE_UUID);
let jsonBody = null;
if (observation.deleted) {
let delObservation = {};
delObservation.observationId = observation.observationId;
delObservation.deleted = observation.deleted;
jsonBody = JSON.stringify(delObservation);
}
else {
jsonBody = JSON.stringify(observation);
}
if (observation.deleted) {
This.removeLocalObservation(observation.observationId);
}
/*CommonUtil.logInfo("syncObservationPOST: jsonbody=" + jsonBody);
CommonUtil.logInfo("Sending observation");*/
fetch(
This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_SYNC_UPDATE_OBSERVATION,
{
method: "POST",
headers: {
"Content-Type": "application/json",
'Authorization': userUUID
},
body: jsonBody
}
)
.then(function (response) {
if (response.status === 200) {
//CommonUtil.logInfo("Done POSTING")
}
else {
/** Even if the response is not success, still need to increase the counter,
* to decide for next action after all PUSH */
This.counterTwoWaySyncPOST = This.counterTwoWaySyncPOST + 1;
}
return response.text()
})
.then((data) => {
if (data) {
//console.info(data);
let updatedObservation = JSON.parse(data);
if (observation.observationId < 0) {
let indexPosition = null;
let lstObservations = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST));
$.each(lstObservations, function (index, jsonObservation) {
if (observation.observationId == jsonObservation.observationId) {
indexPosition = index;
return false;
}
})
if (indexPosition || indexPosition === 0) {
/** Remove/delete the Observation with nagative number (localy created ) */
lstObservations.splice(indexPosition, 1);
localStorage.setItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST, JSON.stringify(lstObservations));
this.getObservationsFromServerTwowaySync(1, updatedObservation)
}
}
if (updatedObservation.observationId === observation.observationId) {
this.updateObservationPOST(updatedObservation, totalTwoWaySyncPOST);
}
}
});
}
},
/** After App's POST opecation, update local observation when response received from VIPS Server */
updateObservationPOST(updatedObservation, totalTwoWaySyncPOST) {
let lstObservations = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST));
let observationOld = {};
let counter = undefined;
$.each(lstObservations, function (index, jsonObservation) {
if (jsonObservation.observationId === updatedObservation.observationId) {
observationOld = Object.assign({}, jsonObservation); // Deep cloning
counter = index;
return false;
}
});
if (counter || counter === 0) {
let illustrationsUpdated = updatedObservation.observationIllustrationSet;
let illustrationsOld = observationOld.observationIllustrationSet;
illustrationsOld.forEach(function (illOld) {
let recFound = false;
if (illustrationsUpdated) {
illustrationsUpdated.forEach(function (illUpdated) {
if (illOld.observationIllustrationPK.fileName === illUpdated.observationIllustrationPK.fileName) {
recFound = true;
return false;
}
});
}
if (recFound) {
delete illOld.uploaded;
if (illOld.deleted) {
CommonUtil.logInfo('record to delete --- found');
}
}
})
updatedObservation.observationIllustrationSet = observationOld.observationIllustrationSet;
lstObservations[counter] = updatedObservation;
localStorage.setItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST, JSON.stringify(lstObservations));
this.counterTwoWaySyncPOST = this.counterTwoWaySyncPOST + 1;
CommonUtil.logInfo('total number of upload : ' + totalTwoWaySyncPOST + ' ---- counter value : ' + this.counterTwoWaySyncPOST);
if (this.counterTwoWaySyncPOST === totalTwoWaySyncPOST) {
this.counterTwoWaySyncPOST = 0;
this.getObservationsFromServerTwowaySync(totalTwoWaySyncPOST, updatedObservation);
}
}
},
/** GET Observations from server to sync local data */
getObservationsFromServerTwowaySync(totalTwoWaySyncPOST, updatedObservation) {
let This = this;
let strUUID = localStorage.getItem(CommonUtil.CONST_STORAGE_UUID);
let jsonHeader = {Authorization: strUUID};
fetch(This.CONST_URL_DOMAIN + CommonUtil.CONST_URL_USER_OBSERVATION_LIST, {
method: "GET",
headers: jsonHeader,
}).then((response) => response.json())
.then((data) => {
let serverObservations = data;
if (localStorage.getItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST)) {
let lstLocalObservations = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST));
serverObservations.forEach(function (srvObservation) {
let arrIndex = undefined;
let booNoRecordFound = false;
let booRecordFound = false;
$.each(lstLocalObservations, function (index, localObservation) {
if (srvObservation.observationId === localObservation.observationId) {
booRecordFound = true;
if (updatedObservation && (totalTwoWaySyncPOST === 1 && updatedObservation.observationId === srvObservation.observationId)) {
}
else {
if (srvObservation.lastEditedTime) {
if (localObservation.lastEditedTime) {
let srvDate = new Date(srvObservation.lastEditedTime);
let localDate = new Date(localObservation.lastEditedTime);
if (srvDate >= localDate) {
arrIndex = index;
return false;
}
}
else {
arrIndex = index;
return false;
}
}
else {
arrIndex = index;
return false;
}
}
}
else {
//booNoRecordFound = true;
}
})
if (booRecordFound) {}
else {
booNoRecordFound = true;
}
if (arrIndex || arrIndex === 0) {
lstLocalObservations[arrIndex] = srvObservation;
}
if (booNoRecordFound) {
lstLocalObservations.push(srvObservation);
return false;
}
});
//CommonUtil.logInfo(lstLocalObservations);
localStorage.setItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST, JSON.stringify(lstLocalObservations));
}
else {
localStorage.setItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST, JSON.stringify(serverObservations));
//this.$router.replace({path:'/'});
/* this.$router.push("/").catch(()=>{});
this.$router.go(); */
}
serverObservations.forEach(function (srvObservation) {
let observationId = srvObservation.observationId;
let organismId = srvObservation.organismId;
let illustrations = srvObservation.observationIllustrationSet;
if (illustrations && illustrations.length != 0) {
illustrations.forEach(function (illustration) {
let imageFileName = illustration.observationIllustrationPK.fileName;
if (imageFileName) {
This.fetchImageFromServer(observationId, organismId, imageFileName);
}
})
}
});
// Update the data model for the observation list.
if (this.$root.sharedState.observationListComponent != undefined) {
this.$root.sharedState.observationListComponent.getObservationsFromStore();
}
})
},
/** GET image from server */
fetchImageFromServer(observationId, organismId, imageFileName) {
let photoURL = this.CONST_URL_DOMAIN + CommonUtil.CONST_URL_STATIC_IMAGE_PATH + organismId + '/' + imageFileName;
let imgTest;
let This = this;
let observationImage = {
observationId: '',
organismId: '',
illustration: {
fileName: '',
imageTextData: '',
deleted: false
}
};
observationImage.observationId = observationId;
observationImage.organismId = organismId;
observationImage.illustration.fileName = imageFileName;
if (organismId) {
const toDataURL = url => fetch(url)
.then(response => response.blob())
.then(blob => new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => resolve(reader.result)
reader.onerror = reject
reader.readAsDataURL(blob)
}))
toDataURL(photoURL)
.then(imageTextData => {
observationImage.illustration.imageTextData = imageTextData;
This.storeImageData(observationImage);
})
}
},
/** Store image from server
*/
storeImageData(observationImage) {
let This = this;
let entityName = CommonUtil.CONST_DB_ENTITY_PHOTO;
let dbRequest = indexedDB.open(CommonUtil.CONST_DB_NAME, CommonUtil.CONST_DB_VERSION);
dbRequest.onsuccess = function (evt) {
let db = evt.target.result;
if (db.objectStoreNames.contains(entityName)) {
let transaction = db.transaction([entityName], 'readwrite');
let objectstore = transaction.objectStore(entityName).add(observationImage, observationImage.illustration.fileName);
}
else {
alert("Photo part of IndexedDB not created. Please report this error.");
}
db.close();
}
},
/** Remove local Observation */
removeLocalObservation(id) {
let lstObservations = JSON.parse(localStorage.getItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST));
let indexPosition = null;
$.each(lstObservations, function (index, observation) {
if (observation.observationId === id) {
indexPosition = index;
return false;
}
});
if (indexPosition || indexPosition === 0) {
this.removeImageRecord(id);
lstObservations.splice(indexPosition, 1);
localStorage.setItem(CommonUtil.CONST_STORAGE_OBSERVATION_LIST, JSON.stringify(lstObservations));
}
},
/**
* Remove image data from indexed DB
*/
removeImageRecord(observationId) {
let entityName = CommonUtil.CONST_DB_ENTITY_PHOTO;
let dbRequest = indexedDB.open(CommonUtil.CONST_DB_NAME, CommonUtil.CONST_DB_VERSION);
let indexName = CommonUtil.CONST_DB_INDEX_NAME_OBSERVATION_ID;
dbRequest.onsuccess = function (evt) {
let db = evt.target.result;
if (db.objectStoreNames.contains(entityName)) {
let transaction = db.transaction([entityName], 'readwrite');
let objectstore = transaction.objectStore(entityName);
let indexStore = objectstore.index(indexName);
let keyRange = IDBKeyRange.only(observationId);
let cursorRequest = indexStore.openCursor(keyRange);
cursorRequest.onsuccess = function (event) {
let cursor = event.target.result;
if (cursor) {
cursor.delete();
cursor.continue();
}
}
}
db.close();
}
},
},
mounted() {
this.isMounted = true;
this.CONST_URL_DOMAIN = CommonUtil.CONST_URL_DOMAIN;
}
};
</script>