@flumens/models 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Collection.d.ts +1 -1
- package/dist/Collection.js +108 -1
- package/dist/Drupal/User.d.ts +2 -2
- package/dist/Drupal/User.js +433 -1
- package/dist/Indicia/Media.js +369 -1
- package/dist/Indicia/Occurrence.d.ts +7 -7
- package/dist/Indicia/Occurrence.js +220 -1
- package/dist/Indicia/Sample.d.ts +2 -2
- package/dist/Indicia/Sample.js +687 -1
- package/dist/Indicia/SampleCollection.js +77 -1
- package/dist/Indicia/helpers.d.ts +1 -1
- package/dist/Indicia/helpers.js +120 -1
- package/dist/Model.d.ts +1 -1
- package/dist/Model.js +191 -1
- package/dist/Stores/LocalForageStore.js +228 -1
- package/dist/Stores/SQLiteDatabase.d.ts +1 -1
- package/dist/Stores/SQLiteDatabase.js +221 -1
- package/dist/Stores/SQLiteStore.d.ts +4 -6
- package/dist/Stores/SQLiteStore.js +310 -1
- package/dist/Stores/Store.js +11 -1
- package/dist/Stores/utils.js +60 -1
- package/dist/index.js +29 -1
- package/package.json +11 -16
package/dist/Indicia/Sample.js
CHANGED
|
@@ -1 +1,687 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("tslib"),t=require("mobx"),r=require("axios"),s=require("lodash"),n=require("@flumens/utils/dist/errors"),a=require("../Model.js"),i=require("./Media.js"),o=require("./Occurrence.js"),u=require("./helpers.js");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=c(r);function l(e,t){var r,s,n,a;if(null==t?void 0:t.values)e.id=t.values.id,e.samples&&t.samples&&(null===(s=e.samples)||void 0===s||s.forEach((function(e,r){return l(e,t.samples[r])}))),e.occurrences&&t.occurrences&&(null===(n=e.occurrences)||void 0===n||n.forEach((function(e,r){return l(e,t.occurrences[r])}))),e.media&&t.media&&(null===(a=e.media)||void 0===a||a.forEach((function(e,r){return l(e,t.media[r])})));else{if("test"===(null===(r=null===process||void 0===process?void 0:process.env)||void 0===r?void 0:r.NODE_ENV))return;console.warn("Model didn't receive an id from the server")}}var h=function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var r,s,n;return e.__generator(this,(function(a){switch(a.label){case 0:return r=[],t.media?(s=function(t){return e.__awaiter(void 0,void 0,void 0,(function(){var r;return e.__generator(this,(function(e){switch(e.label){case 0:return[4,t.getFormData()];case 1:return r=e.sent(),[2,[t,r]]}}))}))},[4,Promise.all(t.media.map(s))]):[3,2];case 1:n=a.sent(),r.push.apply(r,n),a.label=2;case 2:return t.occurrences?[4,Promise.all(t.occurrences.map(h))]:[3,4];case 3:n=a.sent(),r.push.apply(r,n.flat()),a.label=4;case 4:return t.samples?[4,Promise.all(t.samples.map(h))]:[3,6];case 5:n=a.sent(),r.push.apply(r,n.flat()),a.label=6;case 6:return[2,r]}}))}))};function m(e,t){var r={values:{id:t||-1}};return e.occurrences&&(r.occurrences=e.occurrences.map((function(e){return m(e)}))),e.samples&&(r.samples=e.samples.map((function(e){return m(e)}))),e.media&&(r.media=e.media.map((function(e){return m(e)}))),r}function p(e){try{console.warn(JSON.stringify(e).substring(0,1e5))}catch(e){}}var f=function(r){function a(s){var n=this;void 0===s&&(s={});var i=s.metadata,o=void 0===i?{}:i,c=s.samples,d=void 0===c?[]:c,l=s.occurrences,h=void 0===l?[]:l,m=s.media,p=void 0===m?[]:m,f=s.attrs,v=void 0===f?{}:f,_=e.__rest(s,["metadata","samples","occurrences","media","attrs"]);(n=r.call(this,e.__assign(e.__assign({},_),{attrs:e.__assign({},v)}))||this).remote=t.observable({synchronising:!1,url:null,headers:{},timeout:12e4}),n.validateRemote=u.validateRemoteModel,n.error=t.observable({message:""}),n.debouncedValue=300,n.keys=function(){return e.__assign(e.__assign({},a.keys),function(t){return Object.keys(t).reduce((function(r,s){var n;return e.__assign(e.__assign({},r),((n={})[s]=t[s].remote||t[s],n))}),{})}(n.getSurvey().attrs||{}))},n.requiresRemoteSync=function(){return!n.syncedAt||n.updatedAt>n.syncedAt},n.metadata=t.observable(o),n.samples=t.observable(d),n.occurrences=t.observable(h),n.media=t.observable(p);var y=function(e){return e.parent=n};n.samples.forEach(y),n.occurrences.forEach(y),n.media.forEach(y);var g=function(e){var t;return(null===(t=e.added)||void 0===t?void 0:t.length)?(e.added.forEach(y),n.setupdatedAtTimestamp(Date.now())):e.removedCount&&n.setupdatedAtTimestamp(Date.now()),e};return t.intercept(n.samples,g),t.intercept(n.occurrences,g),t.intercept(n.media,g),n}return e.__extends(a,r),a.fromJSON=function(t,r,s,n){var a,u,c,d,l,h,m;void 0===r&&(r=o.default),void 0===s&&(s=this),void 0===n&&(n=i.default);var p=(null===(a=null==t?void 0:t.attrs)||void 0===a?void 0:a.attrs)?null==t?void 0:t.attrs:t;return new this(e.__assign(e.__assign({},t),{attrs:p.attrs,metadata:p.metadata,createdAt:t.createdAt||(null===(u=t.metadata)||void 0===u?void 0:u.createdOn),updatedAt:t.updatedAt||(null===(c=t.metadata)||void 0===c?void 0:c.updatedOn),syncedAt:t.syncedAt||(null===(d=t.metadata)||void 0===d?void 0:d.syncedOn),samples:null===(l=p.samples)||void 0===l?void 0:l.map((function(e){return s.fromJSON(e,r,s,n)})),occurrences:null===(h=p.occurrences)||void 0===h?void 0:h.map((function(e){return r.fromJSON(e,n)})),media:null===(m=p.media)||void 0===m?void 0:m.map((function(e){return n.fromJSON(e)}))}))},a.prototype.setupdatedAtTimestamp=function(e){var t;r.prototype.setUpdatedAtTimestamp.call(this,e),null===(t=this.parent)||void 0===t||t.setupdatedAtTimestamp(e)},a.prototype.toJSON=function(){var s,n,a,i,o=r.prototype.toJSON.call(this);return this.parent?JSON.parse(JSON.stringify(e.__assign(e.__assign({},o),{metadata:t.toJS(this.metadata)||{},occurrences:this.occurrences.map((function(e){return e.toJSON()}))||[],samples:(null===(a=this.samples)||void 0===a?void 0:a.map((function(e){return e.toJSON()})))||[],media:(null===(i=this.media)||void 0===i?void 0:i.map((function(e){return e.toJSON()})))||[]}))):JSON.parse(JSON.stringify(e.__assign(e.__assign({},o),{attrs:{attrs:o.attrs,metadata:t.toJS(this.metadata)||{},occurrences:this.occurrences.map((function(e){return e.toJSON()}))||[],samples:(null===(s=this.samples)||void 0===s?void 0:s.map((function(e){return e.toJSON()})))||[],media:(null===(n=this.media)||void 0===n?void 0:n.map((function(e){return e.toJSON()})))||[]}})))},a.prototype.getSurvey=function(){return this.survey?this.parent?this.parent.getSurvey().smp||{}:this.survey:{}},a.prototype.save=function(){return e.__awaiter(this,void 0,void 0,(function(){var t;return e.__generator(this,(function(r){switch(r.label){case 0:if(this.attrs.deleted)return[2];if(this.parent)return this.parent.save(),[2];if(!this.store)throw new Error("Trying to sync locally without a store");return t=this.toJSON(),[4,this.store.save(e.__assign(e.__assign({},t),{data:t.attrs}))];case 1:return r.sent(),[2]}}))}))},a.prototype.destroy=function(t){var r;return e.__awaiter(this,void 0,void 0,(function(){var s,n=this;return e.__generator(this,(function(e){switch(e.label){case 0:return s=function(){return Promise.all([Promise.all(n.media.map((function(e){return e.destroy(!0)}))),Promise.all(n.occurrences.map((function(e){return e.destroy(!0)})))])},this.parent?(this.parent.samples.remove(this),[4,s()]):[3,2];case 1:return e.sent(),t?[2]:(this.parent.save(),[2]);case 2:if(!this.store)throw new Error("Trying to sync locally without a store");return[4,this.store.delete(this.cid)];case 3:return e.sent(),null===(r=this.collection)||void 0===r||r.remove(this),[4,s()];case 4:return e.sent(),this.attrs.deleted=!0,[2]}}))}))},a.prototype.sync=function(){return e.__awaiter(this,void 0,void 0,(function(){return e.__generator(this,(function(e){return[2,this.parent?this.parent.sync():r.prototype.sync.call(this)]}))}))},a.prototype.saveRemote=function(){return e.__awaiter(this,void 0,void 0,(function(){var t,r,s,n,a;return e.__generator(this,(function(e){switch(e.label){case 0:if(!this.remote.url)throw new Error('A "remote" property is not configured.');e.label=1;case 1:return e.trys.push([1,4,,5]),this.remote.synchronising=!0,[4,this.uploadMedia()];case 2:return t=e.sent(),r=this.getSubmission(t),[4,this.postRemote(r)];case 3:return s=e.sent(),this.remote.synchronising=!1,l(this,s),n=(new Date).getTime(),this.updatedAt=n,this.syncedAt=n,this.save(),[3,5];case 4:throw a=e.sent(),this.remote.synchronising=!1,a;case 5:return[2]}}))}))},a.prototype.postRemote=function(t){var r,s,a;return e.__awaiter(this,void 0,void 0,(function(){var i,o,c,l,h;return e.__generator(this,(function(e){switch(e.label){case 0:return i=this.remote.url,"function"!=typeof this.remote.headers?[3,2]:[4,this.remote.headers()];case 1:return c=e.sent(),[3,3];case 2:c=this.remote.headers,e.label=3;case 3:o=c,e.label=4;case 4:return e.trys.push([4,6,,7]),[4,d.default.post("".concat(i,"/samples"),t,{headers:o,timeout:12e4})];case 5:return[2,e.sent().data];case 6:if(l=e.sent(),409===(h=l).status&&(null===(r=h.response)||void 0===r?void 0:r.data.duplicate_of))return[2,m(this,h.response.data.duplicate_of.id)];if(n.isAxiosNetworkError(h))throw new n.HandledError("Request aborted because of a network issue (timeout or similar).");if(400===h.status)throw p(t),new Error(u.getErrorMessageFromObject(null===(a=null===(s=h.response)||void 0===s?void 0:s.data)||void 0===a?void 0:a.message));throw new Error(h.message);case 7:return[2]}}))}))},a.prototype.fetchRemote=function(){return e.__awaiter(this,void 0,void 0,(function(){return e.__generator(this,(function(e){throw new Error("Not implemented.")}))}))},a.prototype.updateRemote=function(){return e.__awaiter(this,void 0,void 0,(function(){var t,r,s,n;return e.__generator(this,(function(e){switch(e.label){case 0:if(!this.remote.url)throw new Error('A "remote" property is not configured.');e.label=1;case 1:return e.trys.push([1,3,,4]),this.remote.synchronising=!0,t={},r=this.getSubmission(t),[4,this.putRemote(this.id,r)];case 2:return l(this,e.sent()),s=(new Date).getTime(),this.updatedAt=s,this.syncedAt=s,this.save(),this.remote.synchronising=!1,[3,4];case 3:throw n=e.sent(),this.remote.synchronising=!1,n;case 4:return[2]}}))}))},a.prototype.putRemote=function(t,r){var s,a;return e.__awaiter(this,void 0,void 0,(function(){var i,o,c,l,h;return e.__generator(this,(function(e){switch(e.label){case 0:return i=this.remote.url,"function"!=typeof this.remote.headers?[3,2]:[4,this.remote.headers()];case 1:return c=e.sent(),[3,3];case 2:c=this.remote.headers,e.label=3;case 3:o=c,e.label=4;case 4:return e.trys.push([4,6,,7]),[4,d.default.put("".concat(i,"/samples/").concat(t),r,{headers:o,timeout:12e4})];case 5:return[2,e.sent().data];case 6:if(l=e.sent(),h=l,n.isAxiosNetworkError(h))throw new n.HandledError("Request aborted because of a network issue (timeout or similar).");if(400===h.status)throw p(r),new Error(u.getErrorMessageFromObject(null===(a=null===(s=h.response)||void 0===s?void 0:s.data)||void 0===a?void 0:a.message));throw new Error(h.message);case 7:return[2]}}))}))},a.prototype.uploadMedia=function(){return e.__awaiter(this,void 0,void 0,(function(){var t,r,s,a,i,o,u,c,l=this;return e.__generator(this,(function(m){switch(m.label){case 0:return t={},[4,h(this)];case 1:if(r=m.sent(),!r.length)return[2,t];s=function(t){return e.__awaiter(l,void 0,void 0,(function(){var r,s,a,i;return e.__generator(this,(function(e){switch(e.label){case 0:return r=this.remote.url,"function"!=typeof this.remote.headers?[3,2]:[4,this.remote.headers()];case 1:return a=e.sent(),[3,3];case 2:a=this.remote.headers,e.label=3;case 3:s=a,e.label=4;case 4:return e.trys.push([4,6,,7]),[4,d.default.post("".concat(r,"/media-queue"),t,{headers:s,timeout:12e4})];case 5:return[2,e.sent().data];case 6:if("timeout"===(i=e.sent()).message)throw new n.HandledError("Request aborted because of a network issue (timeout or similar).");throw i;case 7:return[2]}}))}))},a=[],i=Date.now()-432e5,r.forEach((function(e){var r=e[0];r.syncedAt>i&&r.attrs.queued?t[r.cid]={name:r.attrs.queued}:a.push(e)})),o=5,u=function(r){var n,i,u,c;return e.__generator(this,(function(d){switch(d.label){case 0:return n=a.slice(r,r+o),i=new FormData,n.forEach((function(e){var t=e[1];return i.append.apply(i,t)})),[4,s(i)];case 1:return u=d.sent(),c=(new Date).getTime(),n.forEach((function(e){var t=e[0];t.syncedAt=c,t.attrs.queued=u[t.cid].name})),t=e.__assign(e.__assign({},t),u),[2]}}))},c=0,m.label=2;case 2:return c<a.length?[5,u(c)]:[3,5];case 3:m.sent(),m.label=4;case 4:return c+=o,[3,2];case 5:return[2,t]}}))}))},a.prototype.getSubmission=function(t){var r=this;void 0===t&&(t={});var n="function"==typeof this.keys?this.keys():this.keys,i=e.__assign(e.__assign({},a.keys),n),o={values:{external_key:this.cid},media:[],samples:[],occurrences:[]};this.id&&(o.values.id=this.id);var u=function(e,t){var s=i[e].values;if(!s)return t;if("function"==typeof s)return s(t,o,r);if(t instanceof Array)return t.map((function(t){return u(e,t)}));if(s instanceof Array){var n=s.find((function(e){return e.value===t}));if(!n||!n.id)throw new Error('A "'.concat(e,'" attribute "').concat(t,'" value could not be mapped to a remote database field.'));return n.id}return s[t]};Object.keys(this.attrs).forEach((function(e){var t=r.attrs[e],n=function(e){return null==e};if(!n(t)){if(!i[e])return e=e.includes("smpAttr:")?e:s.snakeCase(e),void(o.values[e]=t);if(!n(t=u(e,t))){var a=i[e].id||e,c=Number.isNaN(Number(a))?a:"smpAttr:".concat(a);c=c.includes("smpAttr:")?c:s.snakeCase(c),o.values[c]=t}}})),this.samples.forEach((function(e){r.attrs.training&&(e.attrs.training=r.attrs.training);var s=e.getSubmission(t);s&&o.samples.push(s)})),this.occurrences.forEach((function(e){r.attrs.training&&(e.attrs.training=r.attrs.training);var s=e.getSubmission(t);s&&o.occurrences.push(s)})),this.media.forEach((function(e){var r=e.getSubmission(t);r&&o.media.push(r)}));var c=this.getSurvey();return c.modifySubmission?c.modifySubmission(o,this):o},a.prototype.isUploaded=function(){return this.parent?this.parent.isUploaded():!!this.syncedAt},a.prototype.isDisabled=function(){return this.isUploaded()},a.keys={location:{id:"entered_sref"},location_type:{id:"entered_sref_system",values:{british:"OSGB",irish:"OSIE",channel:"utm30ed50",latlon:4326}},group:{id:"group_id"},training:{id:"training",values:u.boolToWarehouseValue},deleted:{id:"deleted",values:u.boolToWarehouseValue}},a}(a.default);exports.default=f,exports.getMediaFormData=h;
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tslib = require('tslib');
|
|
6
|
+
var mobx = require('mobx');
|
|
7
|
+
var axios = require('axios');
|
|
8
|
+
var lodash = require('lodash');
|
|
9
|
+
var utils = require('@flumens/utils');
|
|
10
|
+
var Model = require('../Model.js');
|
|
11
|
+
var Media = require('./Media.js');
|
|
12
|
+
var Occurrence = require('./Occurrence.js');
|
|
13
|
+
var helpers = require('./helpers.js');
|
|
14
|
+
|
|
15
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
16
|
+
|
|
17
|
+
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
18
|
+
|
|
19
|
+
function setNewRemoteID(model, responseData) {
|
|
20
|
+
var _a, _b, _c, _d;
|
|
21
|
+
if (!(responseData === null || responseData === void 0 ? void 0 : responseData.values)) {
|
|
22
|
+
if (((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === 'test')
|
|
23
|
+
return;
|
|
24
|
+
console.warn("Model didn't receive an id from the server");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// eslint-disable-next-line no-param-reassign
|
|
28
|
+
model.id = responseData.values.id;
|
|
29
|
+
// do that for all submodels
|
|
30
|
+
if (model.samples && responseData.samples) {
|
|
31
|
+
(_b = model.samples) === null || _b === void 0 ? void 0 : _b.forEach(function (subModel, index) {
|
|
32
|
+
return setNewRemoteID(subModel, responseData.samples[index]);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (model.occurrences && responseData.occurrences) {
|
|
36
|
+
(_c = model.occurrences) === null || _c === void 0 ? void 0 : _c.forEach(function (subModel, index) {
|
|
37
|
+
return setNewRemoteID(subModel, responseData.occurrences[index]);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (model.media && responseData.media) {
|
|
41
|
+
(_d = model.media) === null || _d === void 0 ? void 0 : _d.forEach(function (subModel, index) {
|
|
42
|
+
return setNewRemoteID(subModel, responseData.media[index]);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
var getMediaFormData = function (model) { return tslib.__awaiter(void 0, void 0, void 0, function () {
|
|
47
|
+
var formDataArgs, getFormData, formData, formData, formData;
|
|
48
|
+
return tslib.__generator(this, function (_a) {
|
|
49
|
+
switch (_a.label) {
|
|
50
|
+
case 0:
|
|
51
|
+
formDataArgs = [];
|
|
52
|
+
if (!model.media) return [3 /*break*/, 2];
|
|
53
|
+
getFormData = function (m) { return tslib.__awaiter(void 0, void 0, void 0, function () {
|
|
54
|
+
var formData;
|
|
55
|
+
return tslib.__generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
57
|
+
case 0: return [4 /*yield*/, m.getFormData()];
|
|
58
|
+
case 1:
|
|
59
|
+
formData = _a.sent();
|
|
60
|
+
return [2 /*return*/, [m, formData]];
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}); };
|
|
64
|
+
return [4 /*yield*/, Promise.all(model.media.map(getFormData))];
|
|
65
|
+
case 1:
|
|
66
|
+
formData = _a.sent();
|
|
67
|
+
formDataArgs.push.apply(formDataArgs, formData);
|
|
68
|
+
_a.label = 2;
|
|
69
|
+
case 2:
|
|
70
|
+
if (!model.occurrences) return [3 /*break*/, 4];
|
|
71
|
+
return [4 /*yield*/, Promise.all(model.occurrences.map(getMediaFormData))];
|
|
72
|
+
case 3:
|
|
73
|
+
formData = _a.sent();
|
|
74
|
+
formDataArgs.push.apply(formDataArgs, formData.flat());
|
|
75
|
+
_a.label = 4;
|
|
76
|
+
case 4:
|
|
77
|
+
if (!model.samples) return [3 /*break*/, 6];
|
|
78
|
+
return [4 /*yield*/, Promise.all(model.samples.map(getMediaFormData))];
|
|
79
|
+
case 5:
|
|
80
|
+
formData = _a.sent();
|
|
81
|
+
formDataArgs.push.apply(formDataArgs, formData.flat());
|
|
82
|
+
_a.label = 6;
|
|
83
|
+
case 6: return [2 /*return*/, formDataArgs];
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}); };
|
|
87
|
+
function handleDuplicates(model, existingId) {
|
|
88
|
+
var fullResponse = {
|
|
89
|
+
values: {
|
|
90
|
+
id: existingId || -1,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
if (model.occurrences) {
|
|
94
|
+
fullResponse.occurrences = model.occurrences.map(function (m) {
|
|
95
|
+
return handleDuplicates(m);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (model.samples) {
|
|
99
|
+
fullResponse.samples = model.samples.map(function (m) {
|
|
100
|
+
return handleDuplicates(m);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (model.media) {
|
|
104
|
+
fullResponse.media = model.media.map(function (m) {
|
|
105
|
+
return handleDuplicates(m);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return fullResponse;
|
|
109
|
+
}
|
|
110
|
+
function logTruncatedJSON(payload) {
|
|
111
|
+
try {
|
|
112
|
+
var MAX_PAYLOAD = 200000; // kb. https://develop.sentry.dev/sdk/event-payloads/
|
|
113
|
+
console.warn(JSON.stringify(payload).substring(0, MAX_PAYLOAD / 2));
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
// do nothing
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
var Sample = /** @class */ (function (_super) {
|
|
120
|
+
tslib.__extends(Sample, _super);
|
|
121
|
+
function Sample(_a) {
|
|
122
|
+
if (_a === void 0) { _a = {}; }
|
|
123
|
+
var _this = this;
|
|
124
|
+
var _b = _a.metadata, metadata = _b === void 0 ? {} : _b, _c = _a.samples, samples = _c === void 0 ? [] : _c, _d = _a.occurrences, occurrences = _d === void 0 ? [] : _d, _e = _a.media, media = _e === void 0 ? [] : _e, _f = _a.attrs, attrs = _f === void 0 ? {} : _f, options = tslib.__rest(_a, ["metadata", "samples", "occurrences", "media", "attrs"]);
|
|
125
|
+
_this = _super.call(this, tslib.__assign(tslib.__assign({}, options), { attrs: tslib.__assign({}, attrs) })) || this;
|
|
126
|
+
_this.remote = mobx.observable({
|
|
127
|
+
synchronising: false,
|
|
128
|
+
url: null, // must be set up for remote sync
|
|
129
|
+
headers: {}, // auth and other headers
|
|
130
|
+
timeout: 120000, // 120s
|
|
131
|
+
});
|
|
132
|
+
_this.validateRemote = helpers.validateRemoteModel;
|
|
133
|
+
_this.error = mobx.observable({ message: '' });
|
|
134
|
+
_this.debouncedValue = 300;
|
|
135
|
+
_this.keys = function () {
|
|
136
|
+
var getRemoteProps = function (attrs) {
|
|
137
|
+
var extractRemoteIfExists = function (agg, key) {
|
|
138
|
+
var _a;
|
|
139
|
+
return (tslib.__assign(tslib.__assign({}, agg), (_a = {}, _a[key] = attrs[key].remote || attrs[key], _a)));
|
|
140
|
+
};
|
|
141
|
+
return Object.keys(attrs).reduce(extractRemoteIfExists, {});
|
|
142
|
+
};
|
|
143
|
+
return tslib.__assign(tslib.__assign({}, Sample.keys), getRemoteProps(_this.getSurvey().attrs || {}));
|
|
144
|
+
};
|
|
145
|
+
_this.requiresRemoteSync = function () { return !_this.syncedAt || _this.updatedAt > _this.syncedAt; };
|
|
146
|
+
_this.metadata = mobx.observable(metadata);
|
|
147
|
+
_this.samples = mobx.observable(samples);
|
|
148
|
+
_this.occurrences = mobx.observable(occurrences);
|
|
149
|
+
_this.media = mobx.observable(media);
|
|
150
|
+
// eslint-disable-next-line no-param-reassign, no-return-assign
|
|
151
|
+
var attachParent = function (model) { return (model.parent = _this); };
|
|
152
|
+
_this.samples.forEach(attachParent);
|
|
153
|
+
_this.occurrences.forEach(attachParent);
|
|
154
|
+
_this.media.forEach(attachParent);
|
|
155
|
+
var onAddedSetParentAndUpdateTime = function (change) {
|
|
156
|
+
var _a;
|
|
157
|
+
if ((_a = change.added) === null || _a === void 0 ? void 0 : _a.length) {
|
|
158
|
+
change.added.forEach(attachParent);
|
|
159
|
+
_this.setupdatedAtTimestamp(Date.now());
|
|
160
|
+
}
|
|
161
|
+
else if (change.removedCount) {
|
|
162
|
+
_this.setupdatedAtTimestamp(Date.now());
|
|
163
|
+
}
|
|
164
|
+
return change;
|
|
165
|
+
};
|
|
166
|
+
mobx.intercept(_this.samples, onAddedSetParentAndUpdateTime);
|
|
167
|
+
mobx.intercept(_this.occurrences, onAddedSetParentAndUpdateTime);
|
|
168
|
+
mobx.intercept(_this.media, onAddedSetParentAndUpdateTime);
|
|
169
|
+
return _this;
|
|
170
|
+
}
|
|
171
|
+
Sample.fromJSON = function (jsonProp, OccurrenceClass, Sample, // eslint-disable-line
|
|
172
|
+
MediaClass) {
|
|
173
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
174
|
+
if (OccurrenceClass === void 0) { OccurrenceClass = Occurrence["default"]; }
|
|
175
|
+
if (Sample === void 0) { Sample = this; }
|
|
176
|
+
if (MediaClass === void 0) { MediaClass = Media["default"]; }
|
|
177
|
+
var json = ((_a = jsonProp === null || jsonProp === void 0 ? void 0 : jsonProp.attrs) === null || _a === void 0 ? void 0 : _a.attrs) ? jsonProp === null || jsonProp === void 0 ? void 0 : jsonProp.attrs : jsonProp;
|
|
178
|
+
var sample = new this(tslib.__assign(tslib.__assign({}, jsonProp), { attrs: json.attrs, metadata: json.metadata, createdAt: jsonProp.createdAt || ((_b = jsonProp.metadata) === null || _b === void 0 ? void 0 : _b.createdOn), updatedAt: jsonProp.updatedAt || ((_c = jsonProp.metadata) === null || _c === void 0 ? void 0 : _c.updatedOn), syncedAt: jsonProp.syncedAt || ((_d = jsonProp.metadata) === null || _d === void 0 ? void 0 : _d.syncedOn), samples: (_e = json.samples) === null || _e === void 0 ? void 0 : _e.map(function (mJson) {
|
|
179
|
+
return Sample.fromJSON(mJson, OccurrenceClass, Sample, MediaClass);
|
|
180
|
+
}), occurrences: (_f = json.occurrences) === null || _f === void 0 ? void 0 : _f.map(function (mJson) {
|
|
181
|
+
return OccurrenceClass.fromJSON(mJson, MediaClass);
|
|
182
|
+
}), media: (_g = json.media) === null || _g === void 0 ? void 0 : _g.map(function (mJson) { return MediaClass.fromJSON(mJson); }) }));
|
|
183
|
+
return sample;
|
|
184
|
+
};
|
|
185
|
+
Sample.prototype.setupdatedAtTimestamp = function (newUpdatedAt) {
|
|
186
|
+
var _a;
|
|
187
|
+
_super.prototype.setUpdatedAtTimestamp.call(this, newUpdatedAt);
|
|
188
|
+
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.setupdatedAtTimestamp(newUpdatedAt);
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Returns a clean (no observables) JSON representation of the model.
|
|
192
|
+
*/
|
|
193
|
+
Sample.prototype.toJSON = function () {
|
|
194
|
+
var _a, _b, _c, _d;
|
|
195
|
+
var json = _super.prototype.toJSON.call(this);
|
|
196
|
+
if (!this.parent) {
|
|
197
|
+
return JSON.parse(JSON.stringify(tslib.__assign(tslib.__assign({}, json), { attrs: {
|
|
198
|
+
attrs: json.attrs,
|
|
199
|
+
metadata: mobx.toJS(this.metadata) || {},
|
|
200
|
+
occurrences: this.occurrences.map(function (model) { return model.toJSON(); }) || [],
|
|
201
|
+
samples: ((_a = this.samples) === null || _a === void 0 ? void 0 : _a.map(function (model) { return model.toJSON(); })) || [],
|
|
202
|
+
media: ((_b = this.media) === null || _b === void 0 ? void 0 : _b.map(function (model) { return model.toJSON(); })) || [],
|
|
203
|
+
} })));
|
|
204
|
+
}
|
|
205
|
+
return JSON.parse(JSON.stringify(tslib.__assign(tslib.__assign({}, json), { metadata: mobx.toJS(this.metadata) || {}, occurrences: this.occurrences.map(function (model) { return model.toJSON(); }) || [], samples: ((_c = this.samples) === null || _c === void 0 ? void 0 : _c.map(function (model) { return model.toJSON(); })) || [], media: ((_d = this.media) === null || _d === void 0 ? void 0 : _d.map(function (model) { return model.toJSON(); })) || [] })));
|
|
206
|
+
};
|
|
207
|
+
Sample.prototype.getSurvey = function () {
|
|
208
|
+
if (!this.survey)
|
|
209
|
+
return {};
|
|
210
|
+
if (this.parent)
|
|
211
|
+
return this.parent.getSurvey().smp || {};
|
|
212
|
+
return this.survey;
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Save the model to the offline store.
|
|
216
|
+
*/
|
|
217
|
+
Sample.prototype.save = function () {
|
|
218
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
219
|
+
var json;
|
|
220
|
+
return tslib.__generator(this, function (_a) {
|
|
221
|
+
switch (_a.label) {
|
|
222
|
+
case 0:
|
|
223
|
+
if (this.attrs.deleted)
|
|
224
|
+
return [2 /*return*/]; // we don't want to store deleted samples yet
|
|
225
|
+
if (this.parent) {
|
|
226
|
+
this.parent.save();
|
|
227
|
+
return [2 /*return*/];
|
|
228
|
+
}
|
|
229
|
+
if (!this.store) {
|
|
230
|
+
throw new Error('Trying to sync locally without a store');
|
|
231
|
+
}
|
|
232
|
+
json = this.toJSON();
|
|
233
|
+
return [4 /*yield*/, this.store.save(tslib.__assign(tslib.__assign({}, json), { data: json.attrs }))];
|
|
234
|
+
case 1:
|
|
235
|
+
_a.sent();
|
|
236
|
+
return [2 /*return*/];
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Destroy the model and remove from the offline store.
|
|
243
|
+
*/
|
|
244
|
+
Sample.prototype.destroy = function (silent) {
|
|
245
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
246
|
+
var destroySubModels;
|
|
247
|
+
var _this = this;
|
|
248
|
+
var _a;
|
|
249
|
+
return tslib.__generator(this, function (_b) {
|
|
250
|
+
switch (_b.label) {
|
|
251
|
+
case 0:
|
|
252
|
+
destroySubModels = function () {
|
|
253
|
+
return Promise.all([
|
|
254
|
+
Promise.all(_this.media.map(function (media) { return media.destroy(true); })),
|
|
255
|
+
Promise.all(_this.occurrences.map(function (occ) { return occ.destroy(true); })),
|
|
256
|
+
]);
|
|
257
|
+
};
|
|
258
|
+
if (!this.parent) return [3 /*break*/, 2];
|
|
259
|
+
this.parent.samples.remove(this);
|
|
260
|
+
return [4 /*yield*/, destroySubModels()];
|
|
261
|
+
case 1:
|
|
262
|
+
_b.sent();
|
|
263
|
+
if (silent)
|
|
264
|
+
return [2 /*return*/];
|
|
265
|
+
this.parent.save();
|
|
266
|
+
return [2 /*return*/];
|
|
267
|
+
case 2:
|
|
268
|
+
if (!this.store) {
|
|
269
|
+
throw new Error('Trying to sync locally without a store');
|
|
270
|
+
}
|
|
271
|
+
return [4 /*yield*/, this.store.delete(this.cid)];
|
|
272
|
+
case 3:
|
|
273
|
+
_b.sent();
|
|
274
|
+
(_a = this.collection) === null || _a === void 0 ? void 0 : _a.remove(this);
|
|
275
|
+
return [4 /*yield*/, destroySubModels()];
|
|
276
|
+
case 4:
|
|
277
|
+
_b.sent();
|
|
278
|
+
this.attrs.deleted = true;
|
|
279
|
+
return [2 /*return*/];
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
Sample.prototype.sync = function () {
|
|
285
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
286
|
+
return tslib.__generator(this, function (_a) {
|
|
287
|
+
return [2 /*return*/, this.parent ? this.parent.sync() : _super.prototype.sync.call(this)];
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
Sample.prototype.saveRemote = function () {
|
|
292
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
293
|
+
var warehouseMediaNames, submission, remoteResponse, timeNow, e_1;
|
|
294
|
+
return tslib.__generator(this, function (_a) {
|
|
295
|
+
switch (_a.label) {
|
|
296
|
+
case 0:
|
|
297
|
+
if (!this.remote.url) {
|
|
298
|
+
throw new Error('A "remote" property is not configured.');
|
|
299
|
+
}
|
|
300
|
+
_a.label = 1;
|
|
301
|
+
case 1:
|
|
302
|
+
_a.trys.push([1, 4, , 5]);
|
|
303
|
+
this.remote.synchronising = true;
|
|
304
|
+
return [4 /*yield*/, this.uploadMedia()];
|
|
305
|
+
case 2:
|
|
306
|
+
warehouseMediaNames = _a.sent();
|
|
307
|
+
submission = this.getSubmission(warehouseMediaNames);
|
|
308
|
+
return [4 /*yield*/, this.postRemote(submission)];
|
|
309
|
+
case 3:
|
|
310
|
+
remoteResponse = _a.sent();
|
|
311
|
+
this.remote.synchronising = false;
|
|
312
|
+
// update the model and occurrences with new remote IDs
|
|
313
|
+
setNewRemoteID(this, remoteResponse);
|
|
314
|
+
timeNow = new Date().getTime();
|
|
315
|
+
// TODO: use server times
|
|
316
|
+
this.updatedAt = timeNow;
|
|
317
|
+
this.syncedAt = timeNow;
|
|
318
|
+
this.save();
|
|
319
|
+
return [3 /*break*/, 5];
|
|
320
|
+
case 4:
|
|
321
|
+
e_1 = _a.sent();
|
|
322
|
+
this.remote.synchronising = false;
|
|
323
|
+
throw e_1;
|
|
324
|
+
case 5: return [2 /*return*/];
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
Sample.prototype.postRemote = function (data) {
|
|
330
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
331
|
+
var url, headers, _a, res, _1, e;
|
|
332
|
+
var _b, _c, _d;
|
|
333
|
+
return tslib.__generator(this, function (_e) {
|
|
334
|
+
switch (_e.label) {
|
|
335
|
+
case 0:
|
|
336
|
+
url = this.remote.url;
|
|
337
|
+
if (!(typeof this.remote.headers === 'function')) return [3 /*break*/, 2];
|
|
338
|
+
return [4 /*yield*/, this.remote.headers()];
|
|
339
|
+
case 1:
|
|
340
|
+
_a = _e.sent();
|
|
341
|
+
return [3 /*break*/, 3];
|
|
342
|
+
case 2:
|
|
343
|
+
_a = this.remote.headers;
|
|
344
|
+
_e.label = 3;
|
|
345
|
+
case 3:
|
|
346
|
+
headers = _a;
|
|
347
|
+
_e.label = 4;
|
|
348
|
+
case 4:
|
|
349
|
+
_e.trys.push([4, 6, , 7]);
|
|
350
|
+
return [4 /*yield*/, axios__default["default"].post("".concat(url, "/samples"), data, {
|
|
351
|
+
headers: headers,
|
|
352
|
+
timeout: 120000,
|
|
353
|
+
})];
|
|
354
|
+
case 5:
|
|
355
|
+
res = _e.sent();
|
|
356
|
+
return [2 /*return*/, res.data];
|
|
357
|
+
case 6:
|
|
358
|
+
_1 = _e.sent();
|
|
359
|
+
e = _1;
|
|
360
|
+
if (e.status === 409 && ((_b = e.response) === null || _b === void 0 ? void 0 : _b.data.duplicate_of)) {
|
|
361
|
+
// TODO: we're doing updates so must handle sub-model IDs too
|
|
362
|
+
return [2 /*return*/, handleDuplicates(this, e.response.data.duplicate_of.id)];
|
|
363
|
+
}
|
|
364
|
+
if (utils.isAxiosNetworkError(e)) {
|
|
365
|
+
throw new utils.HandledError('Request aborted because of a network issue (timeout or similar).');
|
|
366
|
+
}
|
|
367
|
+
if (e.status === 400) {
|
|
368
|
+
logTruncatedJSON(data);
|
|
369
|
+
throw new Error(helpers.getErrorMessageFromObject((_d = (_c = e.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.message));
|
|
370
|
+
}
|
|
371
|
+
throw new Error(e.message);
|
|
372
|
+
case 7: return [2 /*return*/];
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
};
|
|
377
|
+
Sample.prototype.fetchRemote = function () {
|
|
378
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
379
|
+
return tslib.__generator(this, function (_a) {
|
|
380
|
+
throw new Error('Not implemented.');
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
Sample.prototype.updateRemote = function () {
|
|
385
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
386
|
+
var warehouseMediaNames, submission, remoteResponse, timeNow, e_2;
|
|
387
|
+
return tslib.__generator(this, function (_a) {
|
|
388
|
+
switch (_a.label) {
|
|
389
|
+
case 0:
|
|
390
|
+
if (!this.remote.url) {
|
|
391
|
+
throw new Error('A "remote" property is not configured.');
|
|
392
|
+
}
|
|
393
|
+
_a.label = 1;
|
|
394
|
+
case 1:
|
|
395
|
+
_a.trys.push([1, 3, , 4]);
|
|
396
|
+
this.remote.synchronising = true;
|
|
397
|
+
warehouseMediaNames = {};
|
|
398
|
+
submission = this.getSubmission(warehouseMediaNames);
|
|
399
|
+
return [4 /*yield*/, this.putRemote(this.id, submission)];
|
|
400
|
+
case 2:
|
|
401
|
+
remoteResponse = _a.sent();
|
|
402
|
+
// update the model and occurrences with new remote IDs
|
|
403
|
+
setNewRemoteID(this, remoteResponse);
|
|
404
|
+
timeNow = new Date().getTime();
|
|
405
|
+
// TODO: use server times
|
|
406
|
+
this.updatedAt = timeNow;
|
|
407
|
+
this.syncedAt = timeNow;
|
|
408
|
+
this.save();
|
|
409
|
+
this.remote.synchronising = false;
|
|
410
|
+
return [3 /*break*/, 4];
|
|
411
|
+
case 3:
|
|
412
|
+
e_2 = _a.sent();
|
|
413
|
+
this.remote.synchronising = false;
|
|
414
|
+
throw e_2;
|
|
415
|
+
case 4: return [2 /*return*/];
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
};
|
|
420
|
+
Sample.prototype.putRemote = function (sampleId, data) {
|
|
421
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
422
|
+
var url, headers, _a, res, _2, e;
|
|
423
|
+
var _b, _c;
|
|
424
|
+
return tslib.__generator(this, function (_d) {
|
|
425
|
+
switch (_d.label) {
|
|
426
|
+
case 0:
|
|
427
|
+
url = this.remote.url;
|
|
428
|
+
if (!(typeof this.remote.headers === 'function')) return [3 /*break*/, 2];
|
|
429
|
+
return [4 /*yield*/, this.remote.headers()];
|
|
430
|
+
case 1:
|
|
431
|
+
_a = _d.sent();
|
|
432
|
+
return [3 /*break*/, 3];
|
|
433
|
+
case 2:
|
|
434
|
+
_a = this.remote.headers;
|
|
435
|
+
_d.label = 3;
|
|
436
|
+
case 3:
|
|
437
|
+
headers = _a;
|
|
438
|
+
_d.label = 4;
|
|
439
|
+
case 4:
|
|
440
|
+
_d.trys.push([4, 6, , 7]);
|
|
441
|
+
return [4 /*yield*/, axios__default["default"].put("".concat(url, "/samples/").concat(sampleId), data, {
|
|
442
|
+
headers: headers,
|
|
443
|
+
timeout: 120000,
|
|
444
|
+
})];
|
|
445
|
+
case 5:
|
|
446
|
+
res = _d.sent();
|
|
447
|
+
return [2 /*return*/, res.data];
|
|
448
|
+
case 6:
|
|
449
|
+
_2 = _d.sent();
|
|
450
|
+
e = _2;
|
|
451
|
+
if (utils.isAxiosNetworkError(e)) {
|
|
452
|
+
throw new utils.HandledError('Request aborted because of a network issue (timeout or similar).');
|
|
453
|
+
}
|
|
454
|
+
if (e.status === 400) {
|
|
455
|
+
logTruncatedJSON(data);
|
|
456
|
+
throw new Error(helpers.getErrorMessageFromObject((_c = (_b = e.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.message));
|
|
457
|
+
}
|
|
458
|
+
throw new Error(e.message);
|
|
459
|
+
case 7: return [2 /*return*/];
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
};
|
|
464
|
+
Sample.prototype.uploadMedia = function () {
|
|
465
|
+
return tslib.__awaiter(this, void 0, void 0, function () {
|
|
466
|
+
var warehouseMediaNames, media, hasPhotos, upload, mediaNotInRemote, twelveHrsAgo, chunk, _loop_1, index;
|
|
467
|
+
var _this = this;
|
|
468
|
+
return tslib.__generator(this, function (_a) {
|
|
469
|
+
switch (_a.label) {
|
|
470
|
+
case 0:
|
|
471
|
+
warehouseMediaNames = {};
|
|
472
|
+
return [4 /*yield*/, getMediaFormData(this)];
|
|
473
|
+
case 1:
|
|
474
|
+
media = _a.sent();
|
|
475
|
+
hasPhotos = media.length;
|
|
476
|
+
if (!hasPhotos)
|
|
477
|
+
return [2 /*return*/, warehouseMediaNames];
|
|
478
|
+
upload = function (data) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
479
|
+
var url, headers, _a, res, e_3;
|
|
480
|
+
return tslib.__generator(this, function (_b) {
|
|
481
|
+
switch (_b.label) {
|
|
482
|
+
case 0:
|
|
483
|
+
url = this.remote.url;
|
|
484
|
+
if (!(typeof this.remote.headers === 'function')) return [3 /*break*/, 2];
|
|
485
|
+
return [4 /*yield*/, this.remote.headers()];
|
|
486
|
+
case 1:
|
|
487
|
+
_a = _b.sent();
|
|
488
|
+
return [3 /*break*/, 3];
|
|
489
|
+
case 2:
|
|
490
|
+
_a = this.remote.headers;
|
|
491
|
+
_b.label = 3;
|
|
492
|
+
case 3:
|
|
493
|
+
headers = _a;
|
|
494
|
+
_b.label = 4;
|
|
495
|
+
case 4:
|
|
496
|
+
_b.trys.push([4, 6, , 7]);
|
|
497
|
+
return [4 /*yield*/, axios__default["default"].post("".concat(url, "/media-queue"), data, {
|
|
498
|
+
headers: headers,
|
|
499
|
+
timeout: 120000,
|
|
500
|
+
})];
|
|
501
|
+
case 5:
|
|
502
|
+
res = _b.sent();
|
|
503
|
+
return [2 /*return*/, res.data];
|
|
504
|
+
case 6:
|
|
505
|
+
e_3 = _b.sent();
|
|
506
|
+
if (e_3.message === 'timeout') {
|
|
507
|
+
throw new utils.HandledError('Request aborted because of a network issue (timeout or similar).');
|
|
508
|
+
}
|
|
509
|
+
throw e_3;
|
|
510
|
+
case 7: return [2 /*return*/];
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}); };
|
|
514
|
+
mediaNotInRemote = [];
|
|
515
|
+
twelveHrsAgo = Date.now() - 1000 * 60 * 60 * 12;
|
|
516
|
+
media.forEach(function (m) {
|
|
517
|
+
var model = m[0];
|
|
518
|
+
if (model.syncedAt > twelveHrsAgo && model.attrs.queued) {
|
|
519
|
+
warehouseMediaNames[model.cid] = { name: model.attrs.queued };
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
mediaNotInRemote.push(m);
|
|
523
|
+
});
|
|
524
|
+
chunk = 5;
|
|
525
|
+
_loop_1 = function (index) {
|
|
526
|
+
var mediaChunkToUpload, data, ids, now;
|
|
527
|
+
return tslib.__generator(this, function (_b) {
|
|
528
|
+
switch (_b.label) {
|
|
529
|
+
case 0:
|
|
530
|
+
mediaChunkToUpload = mediaNotInRemote.slice(index, index + chunk);
|
|
531
|
+
data = new FormData();
|
|
532
|
+
mediaChunkToUpload.forEach(function (_a) {
|
|
533
|
+
var formData = _a[1];
|
|
534
|
+
return data.append.apply(data, formData);
|
|
535
|
+
});
|
|
536
|
+
return [4 /*yield*/, upload(data)];
|
|
537
|
+
case 1:
|
|
538
|
+
ids = _b.sent();
|
|
539
|
+
now = new Date().getTime();
|
|
540
|
+
mediaChunkToUpload.forEach(function (_a) {
|
|
541
|
+
var m = _a[0];
|
|
542
|
+
m.syncedAt = now;
|
|
543
|
+
m.attrs.queued = ids[m.cid].name;
|
|
544
|
+
});
|
|
545
|
+
warehouseMediaNames = tslib.__assign(tslib.__assign({}, warehouseMediaNames), ids);
|
|
546
|
+
return [2 /*return*/];
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
};
|
|
550
|
+
index = 0;
|
|
551
|
+
_a.label = 2;
|
|
552
|
+
case 2:
|
|
553
|
+
if (!(index < mediaNotInRemote.length)) return [3 /*break*/, 5];
|
|
554
|
+
return [5 /*yield**/, _loop_1(index)];
|
|
555
|
+
case 3:
|
|
556
|
+
_a.sent();
|
|
557
|
+
_a.label = 4;
|
|
558
|
+
case 4:
|
|
559
|
+
index += chunk;
|
|
560
|
+
return [3 /*break*/, 2];
|
|
561
|
+
case 5: return [2 /*return*/, warehouseMediaNames];
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
};
|
|
566
|
+
Sample.prototype.getSubmission = function (warehouseMediaNames) {
|
|
567
|
+
var _this = this;
|
|
568
|
+
if (warehouseMediaNames === void 0) { warehouseMediaNames = {}; }
|
|
569
|
+
var sampleKeys = typeof this.keys === 'function' ? this.keys() : this.keys;
|
|
570
|
+
var keys = tslib.__assign(tslib.__assign({}, Sample.keys), sampleKeys); // warehouse keys/values to transform
|
|
571
|
+
var submission = {
|
|
572
|
+
values: {
|
|
573
|
+
external_key: this.cid,
|
|
574
|
+
},
|
|
575
|
+
media: [],
|
|
576
|
+
samples: [],
|
|
577
|
+
occurrences: [],
|
|
578
|
+
};
|
|
579
|
+
if (this.id) {
|
|
580
|
+
submission.values.id = this.id;
|
|
581
|
+
}
|
|
582
|
+
var mapValue = function (attr, value) {
|
|
583
|
+
var valuesMapping = keys[attr].values;
|
|
584
|
+
if (!valuesMapping) {
|
|
585
|
+
return value;
|
|
586
|
+
}
|
|
587
|
+
if (typeof valuesMapping === 'function') {
|
|
588
|
+
return valuesMapping(value, submission, _this);
|
|
589
|
+
}
|
|
590
|
+
if (value instanceof Array) {
|
|
591
|
+
return value.map(function (v) { return mapValue(attr, v); });
|
|
592
|
+
}
|
|
593
|
+
if (valuesMapping instanceof Array) {
|
|
594
|
+
var mapping = valuesMapping.find(function (_a) {
|
|
595
|
+
var val = _a.value;
|
|
596
|
+
return val === value;
|
|
597
|
+
});
|
|
598
|
+
if (!mapping || !mapping.id) {
|
|
599
|
+
throw new Error("A \"".concat(attr, "\" attribute \"").concat(value, "\" value could not be mapped to a remote database field."));
|
|
600
|
+
}
|
|
601
|
+
return mapping.id;
|
|
602
|
+
}
|
|
603
|
+
return valuesMapping[value];
|
|
604
|
+
};
|
|
605
|
+
var getValue = function (attr) {
|
|
606
|
+
var value = _this.attrs[attr];
|
|
607
|
+
var isEmpty = function (val) { return val === null || val === undefined; };
|
|
608
|
+
if (isEmpty(value)) {
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
if (!keys[attr]) {
|
|
612
|
+
attr = attr.includes('smpAttr:') ? attr : lodash.snakeCase(attr);
|
|
613
|
+
submission.values[attr] = value;
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
value = mapValue(attr, value);
|
|
617
|
+
if (isEmpty(value)) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
var warehouseAttr = keys[attr].id || attr;
|
|
621
|
+
var attrKey = !Number.isNaN(Number(warehouseAttr))
|
|
622
|
+
? "smpAttr:".concat(warehouseAttr)
|
|
623
|
+
: warehouseAttr;
|
|
624
|
+
attrKey = attrKey.includes('smpAttr:') ? attrKey : lodash.snakeCase(attrKey);
|
|
625
|
+
submission.values[attrKey] = value;
|
|
626
|
+
};
|
|
627
|
+
Object.keys(this.attrs).forEach(getValue);
|
|
628
|
+
this.samples.forEach(function (model) {
|
|
629
|
+
if (_this.attrs.training)
|
|
630
|
+
model.attrs.training = _this.attrs.training; // eslint-disable-line no-param-reassign
|
|
631
|
+
var modelSubmission = model.getSubmission(warehouseMediaNames);
|
|
632
|
+
if (!modelSubmission)
|
|
633
|
+
return;
|
|
634
|
+
submission.samples.push(modelSubmission);
|
|
635
|
+
});
|
|
636
|
+
this.occurrences.forEach(function (model) {
|
|
637
|
+
if (_this.attrs.training)
|
|
638
|
+
model.attrs.training = _this.attrs.training; // eslint-disable-line no-param-reassign
|
|
639
|
+
var modelSubmission = model.getSubmission(warehouseMediaNames);
|
|
640
|
+
if (!modelSubmission)
|
|
641
|
+
return;
|
|
642
|
+
submission.occurrences.push(modelSubmission);
|
|
643
|
+
});
|
|
644
|
+
this.media.forEach(function (model) {
|
|
645
|
+
var modelSubmission = model.getSubmission(warehouseMediaNames);
|
|
646
|
+
if (!modelSubmission)
|
|
647
|
+
return;
|
|
648
|
+
submission.media.push(modelSubmission);
|
|
649
|
+
});
|
|
650
|
+
var survey = this.getSurvey();
|
|
651
|
+
if (survey.modifySubmission) {
|
|
652
|
+
return survey.modifySubmission(submission, this);
|
|
653
|
+
}
|
|
654
|
+
return submission;
|
|
655
|
+
};
|
|
656
|
+
Sample.prototype.isUploaded = function () {
|
|
657
|
+
if (this.parent) {
|
|
658
|
+
return this.parent.isUploaded();
|
|
659
|
+
}
|
|
660
|
+
return !!this.syncedAt;
|
|
661
|
+
};
|
|
662
|
+
Sample.prototype.isDisabled = function () {
|
|
663
|
+
return this.isUploaded();
|
|
664
|
+
};
|
|
665
|
+
/**
|
|
666
|
+
* Warehouse attributes and their values.
|
|
667
|
+
*/
|
|
668
|
+
Sample.keys = {
|
|
669
|
+
location: { id: 'entered_sref' },
|
|
670
|
+
location_type: {
|
|
671
|
+
id: 'entered_sref_system',
|
|
672
|
+
values: {
|
|
673
|
+
british: 'OSGB', // for British National Grid
|
|
674
|
+
irish: 'OSIE', // for Irish Grid
|
|
675
|
+
channel: 'utm30ed50', // for Channel Islands Grid
|
|
676
|
+
latlon: 4326, // for Latitude and Longitude in decimal form (WGS84 datum)
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
group: { id: 'group_id' },
|
|
680
|
+
training: { id: 'training', values: helpers.boolToWarehouseValue },
|
|
681
|
+
deleted: { id: 'deleted', values: helpers.boolToWarehouseValue },
|
|
682
|
+
};
|
|
683
|
+
return Sample;
|
|
684
|
+
}(Model["default"]));
|
|
685
|
+
|
|
686
|
+
exports["default"] = Sample;
|
|
687
|
+
exports.getMediaFormData = getMediaFormData;
|