This repository has been archived by the owner on Mar 13, 2024. It is now read-only.
/
DateKeyValueType.ts
121 lines (108 loc) · 4.32 KB
/
DateKeyValueType.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import {
CompOperator,
compOperators,
compOpsAndSymbols,
CompOpSymbol,
compOpToSelector, compOpToSymbol,
} from "../helpers/operators";
import { KeyValueSuggestion, KeyValueTextDisplay } from "./KeyValueDatatypes";
import { KeyValueType } from "./KeyValueType";
import moment from "moment";
export interface SlackDateKeyValue {
operator: CompOpSymbol | CompOperator;
date: Date;
}
export interface DateKeyValue extends SlackDateKeyValue {
operator: CompOperator;
}
export default class DateKeyValueType extends KeyValueType<DateKeyValue> {
public static mongoSelectorFor(value: DateKeyValue) {
return { [compOpToSelector(value.operator)]: value.date };
}
public static mongoDateExpressionFor(value: DateKeyValue, field: string): object {
switch (value.operator) {
case "<":
case ">=":
return { [field]: { [compOpToSelector(value.operator)]: moment(value.date).startOf("day").toDate() } };
case ">":
case "<=":
return { [field]: { [compOpToSelector(value.operator)]: moment(value.date).endOf("day").toDate() } };
case "=":
return { $and: [
this.mongoDateExpressionFor({ date: value.date, operator: "<=" }, field),
this.mongoDateExpressionFor({ date: value.date, operator: ">=" }, field),
]};
case "!=":
return { $or: [
this.mongoDateExpressionFor({ date: value.date, operator: "<" }, field),
this.mongoDateExpressionFor({ date: value.date, operator: ">" }, field),
]};
}
}
private _dateFormat: string = "YYYY-MM-DD";
set dateFormat(dateFormat: string) {
this._dateFormat = dateFormat;
}
private _dateParseFormats: string[] = [ "YYYY-MM-DD", "YY-MM-DD", "MM-DD" ];
set dateParseFormats(dateParseFormats: string[]) {
this._dateParseFormats = dateParseFormats;
}
public getSuggestions(prefix: string): KeyValueSuggestion[] {
const parsed = this.parseString(prefix);
// empty input or invalid input or fallback "="
if (prefix === "" || !parsed || (parsed.operator === "=" && !prefix.startsWith("="))) {
let date = new Date();
let operators = Object.keys(compOperators) as Array<CompOpSymbol | CompOperator>;
if (prefix !== "") {
date = parsed ? parsed.date : date;
const filteredOperators = compOpsAndSymbols.filter((op) => op.startsWith(prefix));
operators = filteredOperators.length > 0 ? filteredOperators : operators;
}
return operators.map((operator) => ({
display: this.display({ operator, date })!,
value: this.editText({ operator, date })!,
}));
} else {
return [];
}
}
public parseString(val: string): DateKeyValue | undefined {
let value = val.trim();
if (value === "") {
value = "=" + new Date();
}
value = value.replace(/\s/g, ""); // remove spaces
const match = value.replace("≥", ">=")
.replace("≤", "<=")
.replace("<>", "!=")
.replace("≠", "!=")
.replace("==", "=")
.match(/^(<=|<|>=|>|!=|=)?(.+)/);
if (match) {
const parsedDate = moment.utc(match[2], this._dateParseFormats, true);
if (parsedDate.isValid()) {
return {
operator: match[1] as CompOperator ?? "=",
date: parsedDate.toDate(),
};
} else {
return undefined;
}
} else {
return undefined;
}
}
public checkValue(val: any): DateKeyValue | undefined {
if (Object.keys(compOperators).includes(val.operator) && val.date instanceof Date && !isNaN(val.date)) {
return val;
} else {
return undefined;
}
}
public display(value: SlackDateKeyValue): KeyValueTextDisplay {
return { text: compOpToSymbol(value.operator) + " " + moment(value.date).format(this._dateFormat) };
}
public editText(value: SlackDateKeyValue): string {
return this.display(value).text;
}
}