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.
@@ -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, DateFormatter } from "./date_converter";
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, DateFormatter } from "./date_converter";
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,EAAC,aAAa,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAC,oBAAoB,EAAC,MAAM,0BAA0B,CAAC"}
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
- dateVal = DateConverter.dateToInstant(moment(val, "MMM D, YYYY").utc(true));
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 || moment.isMoment(val)) {
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;AAC5B,OAAO,aAAa,MAAM,8BAA8B,CAAC;AAGzD,MAAM,UAAU,mCAAmC,CAAC,aAAqB,EAAE,YAAoB,EAAE,YAAuB;IACtH,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,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;aAC7E;iBAAM,IAAI,GAAG,YAAY,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACtD,OAAO,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;aAC5C;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
+ {"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 const makeErrorsPretty: (apiClass: any, options?: {
2
- exclude: any[];
3
- overrideErrorMessage: any[];
4
- }) => any;
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;AAE/B,MAAM,2BAA2B,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,EAAE;IAC9E,OAAO,CAAC,GAAG,YAAY,EAAE,EAAE;QACzB,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,CAAA;QACJ,CAAC,CAAC,CAAA;IAEN,CAAC,CAAA;AACH,CAAC,CAAA;AACD,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,EAAE;IACjC,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,CAAC,CAAA;AAC3E,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,EAAC,OAAO,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAC,EAAE,EAAE;IACvF,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,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,CAAA;AAED,eAAe,gBAAgB,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,7 +1,7 @@
1
1
  {
2
2
  "name": "avvir",
3
3
  "repository": "git@github.com:Avvir/avvir-javascript-client.git",
4
- "version": "0.4.17",
4
+ "version": "0.4.19",
5
5
  "description": "Javascript client for Avvir APIs",
6
6
  "license": "Apache-2.0",
7
7
  "module": "dist/esm/index.js",
@@ -116,4 +116,4 @@ export default class ProjectApi {
116
116
  }
117
117
  }
118
118
 
119
- makeErrorsPretty(ProjectApi);
119
+ makeErrorsPretty(ProjectApi, { exclude: ["getProjectDeviationsReportTsvUrl"] });
@@ -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 ApiProgressScanDataset from "../models/api/api_progress_scan_dataset";
6
- import ApiView, {ViewParameter} from "../models/api/api_view";
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
- projectId,
18
- floorId,
19
- scanDatasetId
20
- }: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
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
- projectId,
27
- floorId,
28
- scanDatasetId
29
- }: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
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
- projectId,
35
- floorId,
36
- scanDatasetId
33
+ projectId,
34
+ floorId,
35
+ scanDatasetId
37
36
  }: AssociationIds, scanDataset: ApiScanDataset, user: User): Promise<void> {
38
- const url = `${Http.baseUrl()}/projects/${projectId}/floors/${floorId}/scan-datasets/${scanDatasetId}`;
39
- return Http.put(url, user, scanDataset) as unknown as Promise<void>;
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, analysis: ApiScannedElementType<ApiBuiltStatus>[], user: User): Promise<void> {
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, user: User): Promise<string[]> {
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, { id, photoAreaId, sessionDate }:ApiPhotoSession, user: User): Promise<ApiPhotoSession> {
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
- export class DateFormatter {
5
- constructor(format: string) {
6
- this.formatString = format;
7
- }
3
+ import DateFormatter from "./date_formatter";
4
+ import { DateLike } from "../models";
8
5
 
9
- format(date?: Date): string {
10
- if (date) {
11
- return moment(date).format(this.formatString);
12
- } else {
13
- return "";
14
- }
6
+ export class DateConverter {
7
+ static getLocalizedDateFormatter(): DateFormatter {
8
+ return new DateFormatter("l");
15
9
  }
16
10
 
17
- private readonly formatString: string;
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 | Moment, format?: string): string {
15
+ static dateToText(date: Date, format: string): string {
26
16
  if (date instanceof Date) {
27
- if (format) {
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 moment(epochMillis).toDate();
26
+ return new Date(epochMillis);
47
27
  } else {
48
28
  return null;
49
29
  }
50
30
  }
51
31
 
52
- static dateToISO(date: DateLike): string {
53
- if (date == null) {
54
- return ""
55
- } else if (date instanceof Date || moment.isMoment(date)) {
56
- return date.toISOString();
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
- return date + "";
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 dateToInstant(date: Date | Moment): number | null {
47
+ static dateToLocalDate(date: DateLike): string {
63
48
  if (date instanceof Date) {
64
- const epochMillis = moment(date).utc(false).toDate().valueOf();
65
- return epochMillis / 1000;
66
- } else if (moment.isMoment(date) && date.isValid()) {
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 (epochMillis || epochMillis === 0) {
76
- return moment(epochMillis).toDate();
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 tsvStringToDate(dateString) {
87
- if (dateString) {
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, DateFormatter} from "./date_converter";
2
- export {kebabCase} from "./kebab_case";
3
- export {Matrix3Converter} from "./matrix_3_converter";
4
- export {Matrix4Converter} from "./matrix_4_converter";
5
- export {PurposeTypeConverter} from "./purpose_type_converter";
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, propertyName: string, initialValue?: DateLike) {
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
- dateVal = DateConverter.dateToInstant(moment(val, "MMM D, YYYY").utc(true));
14
- } else if (val instanceof Date || moment.isMoment(val)) {
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
  }