Skip to content

Commit

Permalink
simplify date handling
Browse files Browse the repository at this point in the history
Now we just try to quickly get the date into a yyyy-mm-dd format, and don't mess with it after that.

Had to change tsconfig settings and how commonjs modules are imported in order to get both jest and the app to both be happy with moment. See aurelia/skeleton-navigation#606
  • Loading branch information
hatton committed Aug 17, 2018
1 parent 9ca8f17 commit 4c7a461
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 78 deletions.
2 changes: 1 addition & 1 deletion app/components/ConfirmDeleteDialog/ConfirmDeleteDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import * as fs from "fs";
import * as Path from "path";
import * as ReactModal from "react-modal";
import ReactModal from "react-modal";
import "./ConfirmDeleteDialog.scss";
import CloseOnEscape from "react-close-on-escape";
import { locate } from "../../crossPlatformUtilities";
Expand Down
2 changes: 1 addition & 1 deletion app/components/FileList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { computed } from "mobx";
import { observer, Observer } from "mobx-react";
import { Folder } from "../model/Folder";
import { File } from "../model/file/File";
import * as Dropzone from "react-dropzone";
import Dropzone from "react-dropzone";
import { remote } from "electron";
const moment = require("moment");
import { Dictionary } from "typescript-collections";
Expand Down
2 changes: 1 addition & 1 deletion app/components/export/ExportDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react";
import * as ReactModal from "react-modal";
import ReactModal from "react-modal";
import "./ExportDialog.scss";
import CloseOnEscape from "react-close-on-escape";
import CsvExporter from "../../export/CsvExporter";
Expand Down
2 changes: 1 addition & 1 deletion app/components/people/person/MugShot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import { observer } from "mobx-react";
import { Person } from "../../../model/Project/Person/Person";
import * as Dropzone from "react-dropzone";
import Dropzone from "react-dropzone";
import * as fs from "fs-extra";
import { MugshotPlaceholder } from "./MugshotPlaceholder";
import ImageField from "../../ImageField";
Expand Down
2 changes: 1 addition & 1 deletion app/components/project/CreateProjectDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";
import * as fs from "fs";
import * as Path from "path";
import * as ReactModal from "react-modal";
import ReactModal from "react-modal";
import "./CreateProjectDialog.scss";
const { app } = require("electron").remote;

Expand Down
11 changes: 7 additions & 4 deletions app/model/Folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ import * as fs from "fs-extra";
import * as Path from "path";
import * as glob from "glob";
import { FieldSet } from "./field/FieldSet";
import * as assert from "assert";
import assert from "assert";
import ConfirmDeleteDialog from "../components/ConfirmDeleteDialog/ConfirmDeleteDialog";
const sanitize = require("sanitize-filename");
import { trash } from "../crossPlatformUtilities";

export class IFolderSelection {
@observable public index: number;
@observable
public index: number;
}

// Project, Session, or Person
export abstract class Folder {
public directory: string = "";
@observable public files: File[] = [];
@observable public selectedFile: File | null;
@observable
public files: File[] = [];
@observable
public selectedFile: File | null;
public metadataFile: File | null;
protected safeFileNameBase: string;

Expand Down
57 changes: 57 additions & 0 deletions app/model/Project/ReadProject.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ProjectMetadataFile } from "../Project/Project";
import * as temp from "temp";
import fs from "fs";
import Path from "path";

let projectDirectory;
let projectName;

describe("Project Read", () => {
beforeEach(async () => {
projectDirectory = temp.mkdirSync("test");
projectName = Path.basename(projectDirectory);
});
afterEach(async () => {
temp.cleanupSync();
});
it("should read title", () => {
const f = GetProjectFileWithOneField("Title", "This is the title.");
expect(f.getTextProperty("title")).toBe("This is the title.");
});
it("empty date should just be empty string", () => {
const f = GetProjectFileWithOneField("DateAvailable", "");
expect(f.properties.getDateField("dateAvailable").asISODateString()).toBe(
""
);
});
it("should read iso date properly", () => {
const f = GetProjectFileWithOneField("DateAvailable", "2015-03-05");
expect(f.properties.getDateField("dateAvailable").asISODateString()).toBe(
"2015-03-05"
);
});
it("should read iso date with time and offset properly", () => {
const f = GetProjectFileWithOneField(
"DateAvailable",
"2016-01-01T00:00:00+02:00"
);
// The original says it's at midnight in a timezone 2 hours ahead of UTC.
// In SayMore we don't want to deal with timezones, so we convert that to
// UTC, which is actually the previous day, drop the time, drop the time offset.
expect(f.properties.getDateField("dateAvailable").asISODateString()).toBe(
"2015-12-31"
);
});
});

function GetProjectFileWithOneField(
tag: string,
content: string
): ProjectMetadataFile {
fs.writeFileSync(
Path.join(projectDirectory, projectName + ".sprj"),
`<?xml version="1.0" encoding="utf-8"?>
<Project><${tag}>${content}</${tag}></Project>`
);
return new ProjectMetadataFile(projectDirectory);
}
47 changes: 30 additions & 17 deletions app/model/field/Field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export class Field {
public readonly visibility: FieldVisibility;
public persist: boolean;
public readonly cssClass: string;
@observable public textHolder = new TextHolder();
@observable
public textHolder = new TextHolder();
public choices: string[];
public definition: FieldDefinition;
public contributorsArray: Contribution[]; //review
Expand Down Expand Up @@ -145,11 +146,17 @@ export class Field {
// //imdiIsClosedVocabulary?: boolean;
// isCustom: false
// };
assert.ok(
this.key.toLowerCase().indexOf("date") === -1 ||
this.type === FieldType.Date,
"SHOULDN'T " + key + " BE A DATE?"
);
//assert.ok(
// this.key.toLowerCase().indexOf("date") === -1 ||
// this.type === FieldType.Date,
// "SHOULDN'T " + key + " BE A DATE?"
//);
if (
this.key.toLowerCase().indexOf("date") > -1 &&
this.type !== FieldType.Date
) {
console.error(key + " should be a date?");
}
}

get text(): string {
Expand All @@ -165,21 +172,27 @@ export class Field {
this.text = s;
}

public asDate(): Date {
return new Date(Date.parse(this.text));
}
// public asDate(): Date {
// const x = new Date("2015-03-25Z");
// const y = x.getUTCDate();
// const z = this.text.indexOf("Z") > -1 ? this.text : this.text + "Z";
// return new Date(this.text);
// }

public asISODateString(): string {
if (moment(this.text).isValid()) {
return this.asDate().toISOString();
}
return "";
// our rule is that we always keep strings in "YYYY-MM-DD" format, and it's always UTC
return this.text;
}
public asLocaleDateString(): string {
if (moment(this.text).isValid()) {
return this.asDate().toLocaleDateString();
}
return "";
// if (moment(this.text).isValid()) {
// return this.asDate().toLocaleDateString();
// }
// return "";

// maybe someday. But at the moment, javascript's date stuff is so eager to get into timezones
// that it's introducing buts. So for now let' keep it simple by just sticking to storing dates only as
// "YYYY-MM-DD" format string, and always UTC
return this.text;
}
public typeAndValueForXml(): [string, string] {
switch (this.type) {
Expand Down
12 changes: 6 additions & 6 deletions app/model/field/FieldSet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Dictionary } from "typescript-collections";
import * as assert from "assert";
import assert from "assert";
import { Field, FieldType, FieldDefinition, HasConsentField } from "./Field";
import { Contribution } from "../file/File";
import { Person } from "../Project/Person/Person";
Expand Down Expand Up @@ -47,11 +47,11 @@ export class FieldSet extends Dictionary<string, Field> {
public addHasConsentProperty(person: Person) {
this.setValue("hasConsent", new HasConsentField(person));
}
public manditoryTextProperty(key: string, value: string) {
if (!this.containsKey(key)) {
this.setValue(key, new Field(key, FieldType.Text, value));
}
}
// public manditoryTextProperty(key: string, value: string) {
// if (!this.containsKey(key)) {
// this.setValue(key, new Field(key, FieldType.Text, value));
// }
// }
// public manditoryField(field: Field) {
// if (this.containsKey(field.key)) {
// const existing = this.getValue(field.key);
Expand Down
Loading

0 comments on commit 4c7a461

Please sign in to comment.