avvir 0.4.17 → 0.4.19
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/avvir_api.node.js +167 -61
- package/dist/esm/api/project_api.js +1 -1
- package/dist/esm/api/project_api.js.map +1 -1
- package/dist/esm/api/scan_dataset_api.d.ts +1 -2
- package/dist/esm/api/scan_dataset_api.js.map +1 -1
- package/dist/esm/converters/date_converter.d.ts +27 -10
- package/dist/esm/converters/date_converter.js +76 -45
- package/dist/esm/converters/date_converter.js.map +1 -1
- package/dist/esm/converters/date_formatter.d.ts +16 -0
- package/dist/esm/converters/date_formatter.js +48 -0
- package/dist/esm/converters/date_formatter.js.map +1 -0
- package/dist/esm/converters/index.d.ts +2 -1
- package/dist/esm/converters/index.js +2 -1
- package/dist/esm/converters/index.js.map +1 -1
- package/dist/esm/mixins/add_instant_getter_and_setter_to_api_model.js +11 -2
- package/dist/esm/mixins/add_instant_getter_and_setter_to_api_model.js.map +1 -1
- package/dist/esm/utilities/make_errors_pretty.d.ts +8 -4
- package/dist/esm/utilities/make_errors_pretty.js +3 -2
- package/dist/esm/utilities/make_errors_pretty.js.map +1 -1
- package/package.json +1 -1
- package/source/api/project_api.ts +1 -1
- package/source/api/scan_dataset_api.ts +33 -29
- package/source/converters/date_converter.ts +87 -46
- package/source/converters/date_formatter.ts +55 -0
- package/source/converters/index.ts +6 -5
- package/source/mixins/add_instant_getter_and_setter_to_api_model.ts +15 -4
- package/source/utilities/make_errors_pretty.ts +18 -10
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
export declare class DateFormatter {
|
|
3
|
+
constructor(format: string, secondaryFormat?: string);
|
|
4
|
+
/** Use formatLocal when displaying times relative to the user i.e. when
|
|
5
|
+
* somebody else replied to their comment, or when a file was uploaded. */
|
|
6
|
+
formatLocal(date: Date): string;
|
|
7
|
+
/** Use formatUTC when all users should see the same information, regardless
|
|
8
|
+
* of their geographical location. i.e. dates pertaining to what happened on
|
|
9
|
+
* the job site */
|
|
10
|
+
formatUTC(date: moment.MomentInput): string;
|
|
11
|
+
formatRangeLocal(startDate: Date, endDate?: Date): string;
|
|
12
|
+
parseUTC(date: string | null): Date;
|
|
13
|
+
private readonly formatString;
|
|
14
|
+
private readonly secondaryFormat?;
|
|
15
|
+
}
|
|
16
|
+
export default DateFormatter;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
export class DateFormatter {
|
|
3
|
+
constructor(format, secondaryFormat) {
|
|
4
|
+
this.formatString = format;
|
|
5
|
+
this.secondaryFormat = secondaryFormat;
|
|
6
|
+
}
|
|
7
|
+
/** Use formatLocal when displaying times relative to the user i.e. when
|
|
8
|
+
* somebody else replied to their comment, or when a file was uploaded. */
|
|
9
|
+
formatLocal(date) {
|
|
10
|
+
if (date) {
|
|
11
|
+
return moment(date).format(this.formatString);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return "";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Use formatUTC when all users should see the same information, regardless
|
|
18
|
+
* of their geographical location. i.e. dates pertaining to what happened on
|
|
19
|
+
* the job site */
|
|
20
|
+
formatUTC(date) {
|
|
21
|
+
if (date) {
|
|
22
|
+
return moment(date).utc().format(this.formatString);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
formatRangeLocal(startDate, endDate) {
|
|
29
|
+
let formatted = this.formatLocal(startDate);
|
|
30
|
+
if (endDate != null) {
|
|
31
|
+
formatted += " - ";
|
|
32
|
+
let endMoment = moment(endDate);
|
|
33
|
+
if (this.secondaryFormat
|
|
34
|
+
&& moment(startDate).isSame(endMoment, "day")) {
|
|
35
|
+
formatted += endMoment.format(this.secondaryFormat);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
formatted += this.formatLocal(endDate);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return formatted;
|
|
42
|
+
}
|
|
43
|
+
parseUTC(date) {
|
|
44
|
+
return moment.utc(date, this.formatString).toDate();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export default DateFormatter;
|
|
48
|
+
//# sourceMappingURL=date_formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date_formatter.js","sourceRoot":"","sources":["../../../source/converters/date_formatter.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,OAAO,aAAa;IACxB,YAAY,MAAc,EAAE,eAAwB;QAClD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACzC,CAAC;IAED;8EAC0E;IAC1E,WAAW,CAAC,IAAU;QACpB,IAAI,IAAI,EAAE;YACR,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC/C;aAAM;YACL,OAAO,EAAE,CAAC;SACX;IACH,CAAC;IAED;;sBAEkB;IAClB,SAAS,CAAC,IAAwB;QAChC,IAAI,IAAI,EAAE;YACR,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SACrD;aAAM;YACL,OAAO,EAAE,CAAC;SACX;IACH,CAAC;IAED,gBAAgB,CAAC,SAAe,EAAE,OAAc;QAC9C,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,OAAO,IAAI,IAAI,EAAE;YACnB,SAAS,IAAI,KAAK,CAAC;YACnB,IAAI,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAChC,IAAI,IAAI,CAAC,eAAe;mBACjB,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,EACjD;gBACE,SAAS,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;aACrD;iBAAM;gBACL,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;aACxC;SACF;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,IAAmB;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;IACtD,CAAC;CAIF;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { DateConverter
|
|
1
|
+
export { DateConverter } from "./date_converter";
|
|
2
|
+
export { DateFormatter } from "./date_formatter";
|
|
2
3
|
export { kebabCase } from "./kebab_case";
|
|
3
4
|
export { Matrix3Converter } from "./matrix_3_converter";
|
|
4
5
|
export { Matrix4Converter } from "./matrix_4_converter";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { DateConverter
|
|
1
|
+
export { DateConverter } from "./date_converter";
|
|
2
|
+
export { DateFormatter } from "./date_formatter";
|
|
2
3
|
export { kebabCase } from "./kebab_case";
|
|
3
4
|
export { Matrix3Converter } from "./matrix_3_converter";
|
|
4
5
|
export { Matrix4Converter } from "./matrix_4_converter";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source/converters/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../source/converters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -8,11 +8,20 @@ export function addInstantGetterAndSetterToApiModel(modelInstance, propertyName,
|
|
|
8
8
|
},
|
|
9
9
|
set(val) {
|
|
10
10
|
if (typeof val === "string") {
|
|
11
|
-
|
|
11
|
+
const date = moment(val, "MMM D, YYYY").utc(true).toDate();
|
|
12
|
+
if (DateConverter.isValidDate(date)) {
|
|
13
|
+
dateVal = DateConverter.dateToInstant(date);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
dateVal = null;
|
|
17
|
+
}
|
|
12
18
|
}
|
|
13
|
-
else if (val instanceof Date
|
|
19
|
+
else if (val instanceof Date) {
|
|
14
20
|
dateVal = DateConverter.dateToInstant(val);
|
|
15
21
|
}
|
|
22
|
+
else if (moment.isMoment(val)) {
|
|
23
|
+
dateVal = DateConverter.dateToInstant(val.toDate());
|
|
24
|
+
}
|
|
16
25
|
else {
|
|
17
26
|
dateVal = val;
|
|
18
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add_instant_getter_and_setter_to_api_model.js","sourceRoot":"","sources":["../../../source/mixins/add_instant_getter_and_setter_to_api_model.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"add_instant_getter_and_setter_to_api_model.js","sourceRoot":"","sources":["../../../source/mixins/add_instant_getter_and_setter_to_api_model.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,aAAa,MAAM,8BAA8B,CAAC;AAGzD,MAAM,UAAU,mCAAmC,CAAC,aAAqB,EACrB,YAAoB,EACpB,YAAuB;IAEzE,IAAI,OAAO,CAAC;IACZ,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,YAAY,EAAE;QACjD,GAAG;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,GAAG,CAAC,GAAG;YACL,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;gBAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC3D,IAAI,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;oBACnC,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;iBAC7C;qBAAM;oBACL,OAAO,GAAG,IAAI,CAAC;iBAChB;aACF;iBAAM,IAAI,GAAG,YAAY,IAAI,EAAE;gBAC9B,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;aAC5C;iBAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAC/B,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;aACrD;iBAAM;gBACL,OAAO,GAAG,GAAG,CAAC;aACf;QACH,CAAC;QACD,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,IAAI,YAAY,EAAE;QAChB,aAAa,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;KAC5C;AACH,CAAC;AAED,eAAe,mCAAmC,CAAC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
declare type MethodProperties<T> = keyof {
|
|
2
|
+
[P in keyof T as T[P] extends (...args: any) => any ? P : never]: any;
|
|
3
|
+
};
|
|
4
|
+
declare type Options<Class> = {
|
|
5
|
+
exclude?: MethodProperties<Class>[];
|
|
6
|
+
overrideErrorMessage?: MethodProperties<Class>[];
|
|
7
|
+
};
|
|
8
|
+
declare const makeErrorsPretty: <Class>(apiClass: Class, options?: Options<Class>) => Class;
|
|
5
9
|
export default makeErrorsPretty;
|
|
@@ -2,7 +2,7 @@ import _ from "underscore";
|
|
|
2
2
|
import checkFetchStatus from "./check_fetch_status";
|
|
3
3
|
import Config from "../config";
|
|
4
4
|
const makeErrorsPrettyForFunction = (actionName, action, displayErrorMessage) => {
|
|
5
|
-
return (...argumentList) => {
|
|
5
|
+
return ((...argumentList) => {
|
|
6
6
|
return action(...argumentList)
|
|
7
7
|
.then((response) => checkFetchStatus(response, displayErrorMessage))
|
|
8
8
|
.catch((error) => {
|
|
@@ -12,7 +12,7 @@ const makeErrorsPrettyForFunction = (actionName, action, displayErrorMessage) =>
|
|
|
12
12
|
arguments: argumentList
|
|
13
13
|
});
|
|
14
14
|
});
|
|
15
|
-
};
|
|
15
|
+
});
|
|
16
16
|
};
|
|
17
17
|
const getFunctionNames = (clazz) => {
|
|
18
18
|
let builtinProperties = ["length", "constructor", "name", "prototype"];
|
|
@@ -25,6 +25,7 @@ const makeErrorsPretty = (apiClass, options = { exclude: [], overrideErrorMessag
|
|
|
25
25
|
let isExcluded = options.exclude && options.exclude.includes(functionName);
|
|
26
26
|
let displayErrorMessage = !options.overrideErrorMessage || !options.overrideErrorMessage.includes(functionName);
|
|
27
27
|
if (!isExcluded) {
|
|
28
|
+
// @ts-ignore
|
|
28
29
|
apiClass[functionName] = makeErrorsPrettyForFunction(functionName, apiClass[functionName], displayErrorMessage);
|
|
29
30
|
}
|
|
30
31
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make_errors_pretty.js","sourceRoot":"","sources":["../../../source/utilities/make_errors_pretty.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,YAAY,CAAC;AAC3B,OAAO,gBAAgB,MAAM,sBAAsB,CAAC;AACpD,OAAO,MAAM,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"make_errors_pretty.js","sourceRoot":"","sources":["../../../source/utilities/make_errors_pretty.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,YAAY,CAAC;AAC3B,OAAO,gBAAgB,MAAM,sBAAsB,CAAC;AACpD,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B,MAAM,2BAA2B,GAAG,CAAoE,UAAe,EAAE,MAAkB,EAAE,mBAA4B,EAAc,EAAE;IACvL,OAAO,CAAC,CAAC,GAAG,YAAY,EAAE,EAAE;QAC1B,OAAO,MAAM,CAAC,GAAG,YAAY,CAAC;aAC3B,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;aACnE,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,OAAO,MAAM,CAAC,kBAAkB,CAAC;gBAC/B,KAAK;gBACL,MAAM,EAAE,UAAU;gBAClB,SAAS,EAAE,YAAY;aACxB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAe,CAAC;AACnB,CAAC,CAAC;AAGF,MAAM,gBAAgB,GAAG,CAAQ,KAAY,EAA6B,EAAE;IAC1E,IAAI,iBAAiB,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACvE,8DAA8D;IAC9D,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,iBAAiB,CAA8B,CAAC;AACzG,CAAC,CAAC;AAOF,MAAM,gBAAgB,GAAG,CAAQ,QAAe,EAAE,UAA0B,EAAE,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,EAAE,EAAE;IACvH,IAAI,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,YAAY,EAAE,EAAE;QACxC,IAAI,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC3E,IAAI,mBAAmB,GAAG,CAAC,OAAO,CAAC,oBAAoB,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAChH,IAAI,CAAC,UAAU,EAAE;YACf,aAAa;YACb,QAAQ,CAAC,YAAY,CAAC,GAAG,2BAA2B,CAAC,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC,CAAC;SACjH;IACH,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,42 +1,41 @@
|
|
|
1
|
-
import {User} from "../utilities/get_authorization_headers";
|
|
2
|
-
import {AssociationIds, DateLike} from "../models";
|
|
1
|
+
import { User } from "../utilities/get_authorization_headers";
|
|
2
|
+
import { ApiBuiltStatus, ApiDetailedElement, ApiPhotoSession, ApiScanDataset, ApiScannedElementType, AssociationIds, DateLike } from "../models";
|
|
3
3
|
import Http from "../utilities/http";
|
|
4
4
|
import makeErrorsPretty from "../utilities/make_errors_pretty";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {DateConverter} from "../converters";
|
|
8
|
-
import {ApiScanDataset, ApiDetailedElement, ApiPhotoSession, ApiBuiltStatus, ApiScannedElementType} from "../models";
|
|
5
|
+
import ApiView, { ViewParameter } from "../models/api/api_view";
|
|
6
|
+
import { DateConverter } from "../converters";
|
|
9
7
|
|
|
10
8
|
export default class ScanDatasetApi {
|
|
11
|
-
static listScanDatasetsForFloor({projectId, floorId}: AssociationIds, user: User): Promise<ApiScanDataset[]> {
|
|
9
|
+
static listScanDatasetsForFloor({ projectId, floorId }: AssociationIds, user: User): Promise<ApiScanDataset[]> {
|
|
12
10
|
let url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets`;
|
|
13
11
|
return Http.get(url, user) as unknown as Promise<ApiScanDataset[]>;
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
static mergeScanDataset({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
projectId,
|
|
16
|
+
floorId,
|
|
17
|
+
scanDatasetId
|
|
18
|
+
}: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
|
|
21
19
|
const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}`;
|
|
22
20
|
return Http.patch(url, user, scanDataset) as unknown as Promise<void>;
|
|
23
21
|
}
|
|
22
|
+
|
|
24
23
|
//@Deprecated
|
|
25
24
|
static updateScanDataset({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return this.mergeScanDataset({projectId, floorId, scanDatasetId}, scanDataset, user);
|
|
25
|
+
projectId,
|
|
26
|
+
floorId,
|
|
27
|
+
scanDatasetId
|
|
28
|
+
}: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
|
|
29
|
+
return this.mergeScanDataset({ projectId, floorId, scanDatasetId }, scanDataset, user);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
static replaceScanDataset({
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
projectId,
|
|
34
|
+
floorId,
|
|
35
|
+
scanDatasetId
|
|
37
36
|
}: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}`;
|
|
38
|
+
return Http.put(url, user, scanDataset) as unknown as Promise<void>;
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
static createScanDataset({
|
|
@@ -46,12 +45,12 @@ export default class ScanDatasetApi {
|
|
|
46
45
|
}: AssociationIds & { scanDate?: DateLike }, user: User): Promise<ApiScanDataset> {
|
|
47
46
|
let url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets`;
|
|
48
47
|
if (scanDate) {
|
|
49
|
-
url += `?scanDate=${DateConverter.dateToISO(scanDate)}
|
|
48
|
+
url += `?scanDate=${DateConverter.dateToISO(scanDate)}`;
|
|
50
49
|
}
|
|
51
50
|
return Http.post(url, user, null) as unknown as Promise<ApiScanDataset>;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
static deleteScanDataset({projectId, floorId, scanDatasetId}: AssociationIds, user: User): Promise<void> {
|
|
53
|
+
static deleteScanDataset({ projectId, floorId, scanDatasetId }: AssociationIds, user: User): Promise<void> {
|
|
55
54
|
let url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}`;
|
|
56
55
|
return Http.delete(url, user) as unknown as Promise<void>;
|
|
57
56
|
};
|
|
@@ -60,12 +59,14 @@ export default class ScanDatasetApi {
|
|
|
60
59
|
projectId,
|
|
61
60
|
floorId,
|
|
62
61
|
scanDatasetId
|
|
63
|
-
}: AssociationIds,
|
|
62
|
+
}: AssociationIds,
|
|
63
|
+
analysis: ApiScannedElementType<ApiBuiltStatus>[],
|
|
64
|
+
user: User): Promise<void> {
|
|
64
65
|
const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}/analysis?enforceBuiltPersistence=false`;
|
|
65
66
|
return Http.post(url, user, analysis) as unknown as Promise<void>;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
static getScanDataset({projectId, floorId, scanDatasetId}: AssociationIds, user: User): Promise<ApiScanDataset> {
|
|
69
|
+
static getScanDataset({ projectId, floorId, scanDatasetId }: AssociationIds, user: User): Promise<ApiScanDataset> {
|
|
69
70
|
let url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}`;
|
|
70
71
|
return Http.get(url, user) as unknown as Promise<ApiScanDataset>;
|
|
71
72
|
}
|
|
@@ -115,7 +116,8 @@ export default class ScanDatasetApi {
|
|
|
115
116
|
return Http.get(url, user) as unknown as Promise<ViewParameter[]>;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
static getNewElementsForScanDataset({ projectId, floorId, scanDatasetId }: AssociationIds,
|
|
119
|
+
static getNewElementsForScanDataset({ projectId, floorId, scanDatasetId }: AssociationIds,
|
|
120
|
+
user: User): Promise<string[]> {
|
|
119
121
|
const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}/new-elements`;
|
|
120
122
|
return Http.get(url, user) as unknown as Promise<string[]>;
|
|
121
123
|
}
|
|
@@ -133,13 +135,15 @@ export default class ScanDatasetApi {
|
|
|
133
135
|
projectId,
|
|
134
136
|
floorId,
|
|
135
137
|
scanDatasetId
|
|
136
|
-
}: AssociationIds,
|
|
138
|
+
}: AssociationIds,
|
|
139
|
+
{ id, photoAreaId, sessionDate }: ApiPhotoSession,
|
|
140
|
+
user: User): Promise<ApiPhotoSession> {
|
|
137
141
|
|
|
138
142
|
const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}/photo-session/${id}`;
|
|
139
|
-
return Http.post(url, user, {sessionDate}) as unknown as Promise<ApiPhotoSession>;
|
|
143
|
+
return Http.post(url, user, { sessionDate }) as unknown as Promise<ApiPhotoSession>;
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
static clearVerified({projectId, floorId, scanDatasetId}: AssociationIds, user: User): Promise<void> {
|
|
146
|
+
static clearVerified({ projectId, floorId, scanDatasetId }: AssociationIds, user: User): Promise<void> {
|
|
143
147
|
let url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}/clear-verified`;
|
|
144
148
|
return Http.post(url, user) as unknown as Promise<void>;
|
|
145
149
|
};
|
|
@@ -1,40 +1,20 @@
|
|
|
1
1
|
import moment, { Moment } from "moment";
|
|
2
|
-
import {DateLike} from "../models";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
this.formatString = format;
|
|
7
|
-
}
|
|
3
|
+
import DateFormatter from "./date_formatter";
|
|
4
|
+
import { DateLike } from "../models";
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} else {
|
|
13
|
-
return "";
|
|
14
|
-
}
|
|
6
|
+
export class DateConverter {
|
|
7
|
+
static getLocalizedDateFormatter(): DateFormatter {
|
|
8
|
+
return new DateFormatter("l");
|
|
15
9
|
}
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export class DateConverter {
|
|
21
|
-
static getDateFormatter(format: string): DateFormatter {
|
|
22
|
-
return new DateFormatter(format);
|
|
11
|
+
static getDateFormatter(format: string, secondaryFormat?: string): DateFormatter {
|
|
12
|
+
return new DateFormatter(format, secondaryFormat);
|
|
23
13
|
}
|
|
24
14
|
|
|
25
|
-
static dateToText(date: Date
|
|
15
|
+
static dateToText(date: Date, format: string): string {
|
|
26
16
|
if (date instanceof Date) {
|
|
27
|
-
|
|
28
|
-
return moment(date).format(format);
|
|
29
|
-
} else {
|
|
30
|
-
return `last scanned: ${moment(date).format("MMM D, YYYY")}`;
|
|
31
|
-
}
|
|
32
|
-
} else if (moment.isMoment(date)) {
|
|
33
|
-
if (format) {
|
|
34
|
-
return date.format(format);
|
|
35
|
-
} else {
|
|
36
|
-
return `last scanned: ${date.format("MMM D, YYYY")}`;
|
|
37
|
-
}
|
|
17
|
+
return moment(date).format(format);
|
|
38
18
|
} else {
|
|
39
19
|
return "";
|
|
40
20
|
}
|
|
@@ -43,37 +23,40 @@ export class DateConverter {
|
|
|
43
23
|
static instantToDate(instant: number): Date | null {
|
|
44
24
|
if (typeof instant === "number") {
|
|
45
25
|
const epochMillis = instant * 1000;
|
|
46
|
-
return
|
|
26
|
+
return new Date(epochMillis);
|
|
47
27
|
} else {
|
|
48
28
|
return null;
|
|
49
29
|
}
|
|
50
30
|
}
|
|
51
31
|
|
|
52
|
-
static
|
|
53
|
-
if (date
|
|
54
|
-
return
|
|
55
|
-
} else
|
|
56
|
-
return
|
|
32
|
+
static dateToInstant(date: Date): number | null {
|
|
33
|
+
if (date instanceof Date) {
|
|
34
|
+
return date.getTime() / 1000;
|
|
35
|
+
} else {
|
|
36
|
+
return null;
|
|
57
37
|
}
|
|
38
|
+
}
|
|
58
39
|
|
|
59
|
-
|
|
40
|
+
static localDateToMoment(localDate: string): Moment | null {
|
|
41
|
+
if (this.isValidDateString(localDate)) {
|
|
42
|
+
return moment(localDate);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
60
45
|
}
|
|
61
46
|
|
|
62
|
-
static
|
|
47
|
+
static dateToLocalDate(date: DateLike): string {
|
|
63
48
|
if (date instanceof Date) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const epochMillis = date.utc(false).toDate().valueOf();
|
|
68
|
-
return epochMillis / 1000;
|
|
49
|
+
return date.toISOString().substring(0, 10);
|
|
50
|
+
} else if (moment.isMoment(date)) {
|
|
51
|
+
return moment(date).format("YYYY-MM-DD");
|
|
69
52
|
} else {
|
|
70
53
|
return null;
|
|
71
54
|
}
|
|
72
55
|
}
|
|
73
56
|
|
|
74
57
|
static millisecondsToDate(epochMillis: number): Date | null {
|
|
75
|
-
if (
|
|
76
|
-
return
|
|
58
|
+
if (typeof epochMillis === "number") {
|
|
59
|
+
return new Date(epochMillis);
|
|
77
60
|
} else {
|
|
78
61
|
return null;
|
|
79
62
|
}
|
|
@@ -83,13 +66,71 @@ export class DateConverter {
|
|
|
83
66
|
return (value instanceof Date && !isNaN(value.valueOf())) || value === null;
|
|
84
67
|
}
|
|
85
68
|
|
|
86
|
-
static
|
|
87
|
-
|
|
69
|
+
static isValidDateString(value: string): boolean {
|
|
70
|
+
return (typeof value === "string")
|
|
71
|
+
&& !!value.match(/^\d{4}-\d{2}-\d{2}$/);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static tsvStringToDate(dateString: string): Date {
|
|
75
|
+
if (typeof dateString === "string") {
|
|
88
76
|
return moment(dateString, "MM/DD/YYYY").toDate();
|
|
89
77
|
} else {
|
|
90
78
|
return null;
|
|
91
79
|
}
|
|
92
80
|
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* truncate 2 dates to days and compare
|
|
84
|
+
* @param date1
|
|
85
|
+
* @param date2
|
|
86
|
+
* @returns true when date2 is on or after the day of date1;
|
|
87
|
+
* false if either date1 or date2 is null
|
|
88
|
+
*/
|
|
89
|
+
static isOnOrAfterDay(date1: Date | string, date2: Date | string): boolean {
|
|
90
|
+
if (date1 == null || date2 == null) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return this.dateToString(date1) <= this.dateToString(date2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* truncate 2 dates to days and compare
|
|
99
|
+
* @param date1
|
|
100
|
+
* @param date2
|
|
101
|
+
* @returns true when date2 is on the same day as date1
|
|
102
|
+
*/
|
|
103
|
+
static isOnDay(date1: Date | string, date2: Date | string): boolean {
|
|
104
|
+
if (date1 == null || date2 == null) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return this.dateToString(date1) === this.dateToString(date2);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private static dateToString(date: Date | string): string {
|
|
112
|
+
if (date instanceof Date) {
|
|
113
|
+
return `${this.pad(date.getUTCFullYear())}-${this.pad(date.getUTCMonth() + 1)}-${this.pad(date.getUTCDate())}`;
|
|
114
|
+
}
|
|
115
|
+
if (this.isValidDateString(date)) {
|
|
116
|
+
return date;
|
|
117
|
+
}
|
|
118
|
+
throw new TypeError("Expected date to be a Date or string");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static dateToISO(date: DateLike): string {
|
|
122
|
+
if (date == null) {
|
|
123
|
+
return "";
|
|
124
|
+
} else if (date instanceof Date || moment.isMoment(date)) {
|
|
125
|
+
return date.toISOString();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return date + "";
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private static pad(i: number): string {
|
|
132
|
+
return i.toString().padStart(2, "0");
|
|
133
|
+
}
|
|
93
134
|
}
|
|
94
135
|
|
|
95
136
|
export default DateConverter;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
|
|
3
|
+
export class DateFormatter {
|
|
4
|
+
constructor(format: string, secondaryFormat?: string) {
|
|
5
|
+
this.formatString = format;
|
|
6
|
+
this.secondaryFormat = secondaryFormat;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Use formatLocal when displaying times relative to the user i.e. when
|
|
10
|
+
* somebody else replied to their comment, or when a file was uploaded. */
|
|
11
|
+
formatLocal(date: Date): string {
|
|
12
|
+
if (date) {
|
|
13
|
+
return moment(date).format(this.formatString);
|
|
14
|
+
} else {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Use formatUTC when all users should see the same information, regardless
|
|
20
|
+
* of their geographical location. i.e. dates pertaining to what happened on
|
|
21
|
+
* the job site */
|
|
22
|
+
formatUTC(date: moment.MomentInput): string {
|
|
23
|
+
if (date) {
|
|
24
|
+
return moment(date).utc().format(this.formatString);
|
|
25
|
+
} else {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
formatRangeLocal(startDate: Date, endDate?: Date): string {
|
|
31
|
+
let formatted = this.formatLocal(startDate);
|
|
32
|
+
if (endDate != null) {
|
|
33
|
+
formatted += " - ";
|
|
34
|
+
let endMoment = moment(endDate);
|
|
35
|
+
if (this.secondaryFormat
|
|
36
|
+
&& moment(startDate).isSame(endMoment, "day"))
|
|
37
|
+
{
|
|
38
|
+
formatted += endMoment.format(this.secondaryFormat);
|
|
39
|
+
} else {
|
|
40
|
+
formatted += this.formatLocal(endDate);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return formatted;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
parseUTC(date: string | null): Date {
|
|
48
|
+
return moment.utc(date, this.formatString).toDate();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private readonly formatString: string;
|
|
52
|
+
private readonly secondaryFormat?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default DateFormatter;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export {DateConverter
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
1
|
+
export { DateConverter } from "./date_converter";
|
|
2
|
+
export { DateFormatter } from "./date_formatter";
|
|
3
|
+
export { kebabCase } from "./kebab_case";
|
|
4
|
+
export { Matrix3Converter } from "./matrix_3_converter";
|
|
5
|
+
export { Matrix4Converter } from "./matrix_4_converter";
|
|
6
|
+
export { PurposeTypeConverter } from "./purpose_type_converter";
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import moment from "moment";
|
|
2
|
+
|
|
2
3
|
import DateConverter from "../converters/date_converter";
|
|
3
|
-
import {DateLike} from "../models";
|
|
4
|
+
import { DateLike } from "../models";
|
|
4
5
|
|
|
5
|
-
export function addInstantGetterAndSetterToApiModel(modelInstance: Object,
|
|
6
|
+
export function addInstantGetterAndSetterToApiModel(modelInstance: Object,
|
|
7
|
+
propertyName: string,
|
|
8
|
+
initialValue?: DateLike)
|
|
9
|
+
{
|
|
6
10
|
let dateVal;
|
|
7
11
|
Object.defineProperty(modelInstance, propertyName, {
|
|
8
12
|
get() {
|
|
@@ -10,9 +14,16 @@ export function addInstantGetterAndSetterToApiModel(modelInstance: Object, prope
|
|
|
10
14
|
},
|
|
11
15
|
set(val) {
|
|
12
16
|
if (typeof val === "string") {
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
const date = moment(val, "MMM D, YYYY").utc(true).toDate();
|
|
18
|
+
if (DateConverter.isValidDate(date)) {
|
|
19
|
+
dateVal = DateConverter.dateToInstant(date);
|
|
20
|
+
} else {
|
|
21
|
+
dateVal = null;
|
|
22
|
+
}
|
|
23
|
+
} else if (val instanceof Date) {
|
|
15
24
|
dateVal = DateConverter.dateToInstant(val);
|
|
25
|
+
} else if (moment.isMoment(val)) {
|
|
26
|
+
dateVal = DateConverter.dateToInstant(val.toDate());
|
|
16
27
|
} else {
|
|
17
28
|
dateVal = val;
|
|
18
29
|
}
|