fix date range behavior to be more strongly typed, last 7 days is not an alias for a static date range.
This commit is contained in:
Generated
+45
-14701
File diff suppressed because it is too large
Load Diff
@@ -19,12 +19,14 @@
|
||||
"@tsconfig/svelte": "^1.0.0",
|
||||
"@types/marked": "^1.2.1",
|
||||
"@types/node": "^14.14.17",
|
||||
"@types/pluralize": "0.0.29",
|
||||
"amazon-cognito-identity-js": "^4.5.6",
|
||||
"aws-amplify": "^3.3.14",
|
||||
"fa-svelte": "^3.1.0",
|
||||
"insane": "^2.6.2",
|
||||
"lodash-es": "^4.17.20",
|
||||
"marked": "^2.0.1",
|
||||
"pluralize": "^8.0.0",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-css-only": "^3.1.0",
|
||||
"rollup-plugin-dev": "^1.1.3",
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
</script>
|
||||
|
||||
<div class="composition">
|
||||
{#each list as item (item.name)}
|
||||
{#each list as item}
|
||||
<div class="item">
|
||||
<span class="amount">{item.amount}x </span>
|
||||
<a href={item.link}>{item.name}</a>
|
||||
|
||||
@@ -1,194 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { endOfDay, endOfMonth, endOfWeek, endOfYear, formatFormTime, lastMonth, lastYear, monthName, nextMonth, nextYear, startOfDay, startOfMonth, startOfWeek, startOfYear } from "../utils/time";
|
||||
import EveryMinute from "./EveryMinute.svelte";
|
||||
import { allOffsets, pastOffsets, customDateRange } from "../utils/date-range";
|
||||
import type { DateRange } from "../utils/date-range";
|
||||
import { formatFormTime } from "../utils/time";
|
||||
|
||||
interface DateOption {
|
||||
id: string
|
||||
label: string
|
||||
from: Date
|
||||
to: Date
|
||||
}
|
||||
|
||||
export let fromValue: string;
|
||||
export let toValue: string;
|
||||
export let noFuture: boolean = false;
|
||||
export let value: DateRange;
|
||||
export let styled: boolean = false;
|
||||
export let label: string = "Time";
|
||||
export let disabled: boolean = false;
|
||||
export let styled: boolean;
|
||||
export let noFuture: boolean;
|
||||
export let label: string = "Time Period";
|
||||
|
||||
let selected: string = "custom";
|
||||
let options: DateOption[] = [];
|
||||
let now: Date = new Date();
|
||||
|
||||
onMount(() => {
|
||||
for (const option of options) {
|
||||
console.log(formatFormTime(option.from), fromValue, formatFormTime(option.to), toValue);
|
||||
if (formatFormTime(option.from) === fromValue && formatFormTime(option.to) === toValue) {
|
||||
selected = option.id;
|
||||
console.log("-- SELECTED")
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
let rangeOptions: DateRange[];
|
||||
let selected = value.name;
|
||||
let [customMin, customMax] = pastOffsets[0].calculate(new Date()).map(d => formatFormTime(d));
|
||||
|
||||
$: rangeOptions = noFuture ? pastOffsets : allOffsets;
|
||||
$: {
|
||||
if (options.length === 0) {
|
||||
let current = startOfMonth(now);
|
||||
const nextWeek = new Date(now.getTime() + (86400000 * 7));
|
||||
const lastWeek = new Date(now.getTime() - (86400000 * 7));
|
||||
|
||||
options.push({
|
||||
id: "this_week",
|
||||
label: "This Week",
|
||||
from: startOfWeek(now),
|
||||
to: endOfWeek(now),
|
||||
});
|
||||
if (!noFuture) {
|
||||
options.push({
|
||||
id: "next_week",
|
||||
label: "Next Week",
|
||||
from: startOfWeek(nextWeek),
|
||||
to: endOfWeek(nextWeek),
|
||||
});
|
||||
options.push({
|
||||
id: "next_7days",
|
||||
label: "Next 7 Days",
|
||||
from: startOfDay(now),
|
||||
to: endOfDay(new Date(now.getTime() + 86400000 * 7)),
|
||||
});
|
||||
}
|
||||
options.push({
|
||||
id: "last_week",
|
||||
label: "Last Week",
|
||||
from: startOfWeek(lastWeek),
|
||||
to: endOfWeek(lastWeek),
|
||||
});
|
||||
options.push({
|
||||
id: "last_7days",
|
||||
label: "Last 7 Days",
|
||||
from: startOfDay(new Date(now.getTime() - 86400000 * 7)),
|
||||
to: endOfDay(now),
|
||||
});
|
||||
|
||||
options.push({
|
||||
id: "this_month",
|
||||
label: "This Month",
|
||||
from: current,
|
||||
to: endOfMonth(current),
|
||||
});
|
||||
if (!noFuture) {
|
||||
options.push({
|
||||
id: "next_month",
|
||||
label: "Next Month",
|
||||
from: nextMonth(current),
|
||||
to: endOfMonth(nextMonth(current)),
|
||||
});
|
||||
options.push({
|
||||
id: "next_30days",
|
||||
label: "Next 30 Days",
|
||||
from: startOfDay(now),
|
||||
to: endOfDay(new Date(now.getTime() + 86400000 * 30)),
|
||||
});
|
||||
options.push({
|
||||
id: "next_90days",
|
||||
label: "Next 90 Days",
|
||||
from: startOfDay(now),
|
||||
to: endOfDay(new Date(now.getTime() + 86400000 * 90)),
|
||||
});
|
||||
}
|
||||
options.push({
|
||||
id: "last_month",
|
||||
label: "Last Month",
|
||||
from: lastMonth(current),
|
||||
to: endOfMonth(lastMonth(current)),
|
||||
});
|
||||
options.push({
|
||||
id: "last_30days",
|
||||
label: "Last 30 Days",
|
||||
from: startOfDay(new Date(now.getTime() - 86400000 * 30)),
|
||||
to: endOfDay(now),
|
||||
});
|
||||
options.push({
|
||||
id: "last_90days",
|
||||
label: "Last 90 Days",
|
||||
from: startOfDay(new Date(now.getTime() - 86400000 * 90)),
|
||||
to: endOfDay(now),
|
||||
});
|
||||
|
||||
options.push({
|
||||
id: "this_year",
|
||||
label: "This Year",
|
||||
from: startOfYear(now),
|
||||
to: endOfYear(now),
|
||||
});
|
||||
if (!noFuture) {
|
||||
options.push({
|
||||
id: "next_year",
|
||||
label: "Next Year",
|
||||
from: startOfYear(nextYear(now)),
|
||||
to: endOfYear(nextYear(now, 2)),
|
||||
});
|
||||
options.push({
|
||||
id: "next_1year",
|
||||
label: "Next 1 Year",
|
||||
from: startOfDay(now),
|
||||
to: endOfDay(nextYear(now)),
|
||||
});
|
||||
}
|
||||
options.push({
|
||||
id: "last_year",
|
||||
label: "Last Year",
|
||||
from: startOfYear(lastYear(now)),
|
||||
to: endOfYear(lastYear(now)),
|
||||
});
|
||||
options.push({
|
||||
id: "last_1year",
|
||||
label: "Last 1 Year",
|
||||
from: startOfDay(lastYear(now)),
|
||||
to: endOfDay(now),
|
||||
});
|
||||
|
||||
options.push({
|
||||
id: "custom",
|
||||
label: "Specific Dates",
|
||||
from: null,
|
||||
to: null,
|
||||
});
|
||||
|
||||
console.log(options);
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if (selected !== "custom") {
|
||||
const option = options.find(o => o.id === selected);
|
||||
if (option != null) {
|
||||
fromValue = formatFormTime(option.from);
|
||||
toValue = formatFormTime(option.to);
|
||||
if (selected === "Specific Dates") {
|
||||
value = customDateRange(new Date(customMin), new Date(customMax))
|
||||
} else {
|
||||
value = rangeOptions.find(v => v.name === selected);
|
||||
if (value != null) {
|
||||
let [from, to] = value.calculate(new Date()).map(d => formatFormTime(d));
|
||||
customMin = from;
|
||||
customMax = to;
|
||||
} else {
|
||||
selected = rangeOptions[0].name;
|
||||
value = rangeOptions[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<EveryMinute bind:now={now} />
|
||||
<div class:styled>
|
||||
<div>
|
||||
<label for="timeRange">{label}</label>
|
||||
<select name="timeRange" disabled={disabled} bind:value={selected}>
|
||||
{#each options as option (option.id)}
|
||||
<option value={option.id}>{option.label}</option>
|
||||
{#each rangeOptions as option (option.name)}
|
||||
<option value={option.name}>{option.name}</option>
|
||||
{/each}
|
||||
<option value="Specific Dates">Specific Dates</option>
|
||||
</select>
|
||||
</div>
|
||||
{#if selected === "custom"}
|
||||
{#if value.name === "Specific Dates"}
|
||||
<div>
|
||||
<label for="startTime">Start Time</label>
|
||||
<input disabled={disabled} name="startTime" type="datetime-local" bind:value={fromValue} />
|
||||
<input disabled={disabled} name="startTime" type="datetime-local" bind:value={customMin} />
|
||||
</div>
|
||||
<div>
|
||||
<label for="endTime">End Time</label>
|
||||
<input disabled={disabled} name="endTime" type="datetime-local" bind:value={toValue} />
|
||||
<input disabled={disabled} name="endTime" type="datetime-local" bind:value={customMax} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import OptionRow from "./OptionRow.svelte";
|
||||
import ParentEntry from "./ParentEntry.svelte";
|
||||
import Progress from "./Progress.svelte";
|
||||
import ProgressNumbers from "./ProgressNumbers.svelte";
|
||||
import ProgressNumbers from "./ProgressNumbers.svelte";
|
||||
import TimeProgress from "./TimeProgress.svelte";
|
||||
|
||||
export let goal: GoalResult = null;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import type { ProjectResult } from "../models/project";
|
||||
import type { GoalResult } from "../models/goal";
|
||||
|
||||
export let project: ProjectResult | undefined | null;
|
||||
export let goal: GoalResult | undefined | null;
|
||||
export let project: ProjectResult | undefined | null = void(0);
|
||||
export let goal: GoalResult | undefined | null = void(0);
|
||||
|
||||
let progressAmount: number = 0;
|
||||
let progressTarget: number = 0;
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
import Modal from "../components/Modal.svelte";
|
||||
import modalStore from "../stores/modal";
|
||||
import type { GoalResult } from "../models/goal";
|
||||
import { formatFormTime, nextMonth } from "../utils/time";
|
||||
import { nextMonth } from "../utils/time";
|
||||
import GroupSelect from "../components/GroupSelect.svelte";
|
||||
import markStale from "../stores/markStale";
|
||||
import Checkbox from "../components/Checkbox.svelte";
|
||||
import GroupItemSelect from "../components/GroupItemSelect.svelte";
|
||||
import groupStore from "../stores/group";
|
||||
import type { GroupResult } from "../models/group";
|
||||
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
import Checkbox from "../components/Checkbox.svelte";
|
||||
import GroupItemSelect from "../components/GroupItemSelect.svelte";
|
||||
import groupStore from "../stores/group";
|
||||
import type { GroupResult } from "../models/group";
|
||||
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
import { allOffsets, rangeFromDates } from "../utils/date-range";
|
||||
|
||||
export let deletion = false;
|
||||
export let creation = false;
|
||||
@@ -48,8 +49,7 @@ import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
let unweighted = goal.unweighted;
|
||||
let itemId = goal.itemId || "";
|
||||
let compositionMode = goal.compositionMode;
|
||||
let startTime = formatFormTime(goal.startTime);
|
||||
let endTime = formatFormTime(goal.endTime);
|
||||
let range = rangeFromDates(new Date(goal.startTime), new Date(goal.endTime), allOffsets);
|
||||
let taskFilter = goal.taskFilter || "";
|
||||
let itemFilter = goal.itemFilter || "";
|
||||
|
||||
@@ -59,11 +59,11 @@ import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
|
||||
function onSubmit() {
|
||||
loading = true;
|
||||
const [startTime, endTime] = range.calculate(new Date());
|
||||
|
||||
if (creation) {
|
||||
stuffLogClient.createGoal({
|
||||
startTime: new Date(startTime),
|
||||
endTime: new Date(endTime),
|
||||
startTime, endTime,
|
||||
itemId: itemId || null,
|
||||
taskFilter: taskFilter.toLowerCase() || null,
|
||||
itemFilter: itemFilter.toLowerCase() || null,
|
||||
@@ -87,8 +87,7 @@ import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
})
|
||||
} else {
|
||||
stuffLogClient.updateGoal(goal.id, {
|
||||
startTime: new Date(startTime),
|
||||
endTime: new Date(endTime),
|
||||
startTime, endTime,
|
||||
itemId: itemId || null,
|
||||
clearItemId: itemId === "",
|
||||
taskFilter: taskFilter.toLowerCase() || null,
|
||||
@@ -134,7 +133,7 @@ import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
<option value="task" selected={"task" === compositionMode}>Task</option>
|
||||
<option value="project" selected={"project" === compositionMode}>Project</option>
|
||||
</select>
|
||||
<DateRangeSelect disabled={deletion} bind:fromValue={startTime} bind:toValue={endTime} />
|
||||
<DateRangeSelect disabled={deletion} bind:value={range} />
|
||||
<label for="taskFilter">Task Filter (Optional)</label>
|
||||
<input disabled={deletion} name="taskFilter" type="text" bind:value={taskFilter} />
|
||||
<label for="itemFilter">Item Filter (Optional)</label>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<script lang="ts">
|
||||
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
|
||||
import EmptyList from "../components/EmptyList.svelte";
|
||||
import EmptyParentEntry from "../components/EmptyParentEntry.svelte";
|
||||
import EveryMinute from "../components/EveryMinute.svelte";
|
||||
import GoalEntry from "../components/GoalEntry.svelte";
|
||||
import LogEntry from "../components/LogEntry.svelte";
|
||||
import ParentEntry from "../components/ParentEntry.svelte";
|
||||
@@ -11,18 +14,19 @@ import ParentEntry from "../components/ParentEntry.svelte";
|
||||
import { fpLogStore } from "../stores/logs";
|
||||
import { fpProjectStore, fpProjectStore2 } from "../stores/project";
|
||||
import { fpTaskStore } from "../stores/tasks";
|
||||
import { RelativeDateRange } from "../utils/date-range";
|
||||
import { endOfDay, startOfDay } from "../utils/time";
|
||||
|
||||
let fakeMap: {[projectId: string]: boolean} = {}
|
||||
let fakeProjects: ProjectResult[]
|
||||
let sortedProjects: ProjectResult[]
|
||||
let now = new Date();
|
||||
|
||||
$: {
|
||||
if ($fpGoalStore.stale && !$fpGoalStore.loading) {
|
||||
fpGoalStore.load({
|
||||
maxTime: new Date(Date.now() + (86400000 * 3)),
|
||||
minTime: new Date(),
|
||||
});
|
||||
const [minTime, maxTime] = (new RelativeDateRange(3, "day")).calculate(now);
|
||||
|
||||
fpGoalStore.load({minTime, maxTime});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +61,8 @@ import ParentEntry from "../components/ParentEntry.svelte";
|
||||
$: {
|
||||
if ($fpLogStore.stale && !$fpLogStore.loading) {
|
||||
fpLogStore.load({
|
||||
maxTime: endOfDay(new Date()),
|
||||
minTime: startOfDay(new Date()),
|
||||
maxTime: endOfDay(now),
|
||||
minTime: startOfDay(now),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -100,6 +104,7 @@ import ParentEntry from "../components/ParentEntry.svelte";
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<EveryMinute bind:now={now} />
|
||||
<div class="left">
|
||||
{#if !$fpGoalStore.loading || $fpGoalStore.goals.length > 0}
|
||||
<h1>Active Goals</h1>
|
||||
|
||||
@@ -4,17 +4,20 @@
|
||||
import type { ModalData } from "../stores/modal";
|
||||
import goalStore from "../stores/goal";
|
||||
import RefreshSelection from "../components/RefreshSelection.svelte";
|
||||
import { endOfWeek, formatFormTime, startOfWeek } from "../utils/time";
|
||||
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
import { allOffsets, pastOffsets } from "../utils/date-range";
|
||||
import EveryMinute from "../components/EveryMinute.svelte";
|
||||
|
||||
const lsValue = localStorage.getItem("sl2.goalspage.range")
|
||||
|
||||
const mdGoalAdd: ModalData = {name: "goal.add"};
|
||||
let range = allOffsets.find(o => o.name === lsValue) || pastOffsets[0];
|
||||
let now = new Date();
|
||||
|
||||
let minTime = formatFormTime($goalStore.filter.minTime || startOfWeek(new Date()));
|
||||
let maxTime = formatFormTime($goalStore.filter.maxTime || endOfWeek(new Date()));
|
||||
$: localStorage.setItem("sl2.goalspage.range", range.name);
|
||||
|
||||
$: {
|
||||
const min = new Date(minTime);
|
||||
const max = new Date(maxTime);
|
||||
const [min, max] = range.calculate(now);
|
||||
|
||||
if (!$goalStore.loading) {
|
||||
if ($goalStore.stale || $goalStore.filter.minTime?.getTime() != min.getTime() || $goalStore.filter.maxTime?.getTime() != max.getTime()) {
|
||||
@@ -28,7 +31,7 @@
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<DateRangeSelect label="Time Filter" styled bind:fromValue={minTime} bind:toValue={maxTime} />
|
||||
<DateRangeSelect label="Time Filter" styled bind:value={range} />
|
||||
<div class="goal-list" class:loading={$goalStore.loading}>
|
||||
{#each $goalStore.goals as goal (goal.id)}
|
||||
<GoalEntry showAllOptions goal={goal} />
|
||||
@@ -37,6 +40,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<RefreshSelection />
|
||||
<EveryMinute now={now} />
|
||||
|
||||
<style>
|
||||
div.page {
|
||||
|
||||
@@ -7,18 +7,24 @@
|
||||
import RefreshSelection from "../components/RefreshSelection.svelte";
|
||||
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||
import EveryMinute from "../components/EveryMinute.svelte";
|
||||
import { allOffsets, RelativeDateRange } from "../utils/date-range";
|
||||
|
||||
const lsValue = localStorage.getItem("sl2.logspage.range")
|
||||
|
||||
let groupedLogs: {day: Date, text: string, logs: LogResult[]}[] = [];
|
||||
let minTime = formatFormTime($logStore.filter.minTime || startOfDay(new Date(Date.now() - 86400000 * 7)));
|
||||
let maxTime = formatFormTime($logStore.filter.maxTime || endOfDay(new Date()));
|
||||
let emptyMessage = `No logs since ${formatWeekdayDate(minTime)}.`;
|
||||
let error = "";
|
||||
let range = allOffsets.find(o => o.name === lsValue) || new RelativeDateRange(-7, "day");
|
||||
let now = new Date();
|
||||
let error = "";
|
||||
let emptyMessage = `No logs since ${formatWeekdayDate(range.calculate(now)[0])}.`;
|
||||
|
||||
let min: Date;
|
||||
let max: Date;
|
||||
|
||||
$: [min, max] = range.calculate(now);
|
||||
|
||||
$: localStorage.setItem("sl2.logspage.range", range.name);
|
||||
|
||||
$: {
|
||||
const min = new Date(minTime);
|
||||
const max = new Date(maxTime);
|
||||
|
||||
error = "";
|
||||
|
||||
if (!Number.isNaN(min.getTime()) && !Number.isNaN(max.getTime())) {
|
||||
@@ -41,7 +47,7 @@
|
||||
|
||||
$: {
|
||||
if (!$logStore.loading && !$logStore.stale) {
|
||||
emptyMessage = `No logs between ${formatWeekdayDate(minTime)} and ${formatWeekdayDate(maxTime)}.`;
|
||||
emptyMessage = `No logs between ${formatWeekdayDate(min)} and ${formatWeekdayDate(max)}.`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +100,7 @@
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<DateRangeSelect label="Time Filter" noFuture styled bind:fromValue={minTime} bind:toValue={maxTime} />
|
||||
<DateRangeSelect label="Time Filter" noFuture styled bind:value={range} />
|
||||
<div class="error">{error}</div>
|
||||
<div class="log-list" class:loading={$logStore.loading}>
|
||||
{#each groupedLogs as logGroup (logGroup.day.getTime())}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import pluralize from "pluralize";
|
||||
|
||||
import {
|
||||
addDays, addMonths, addYears,
|
||||
endOfDay, endOfMonth, endOfWeek, endOfYear,
|
||||
startOfDay, startOfMonth, startOfWeek, startOfYear
|
||||
} from "./time";
|
||||
|
||||
export interface DateRange {
|
||||
name: string
|
||||
calculate(date: Date): [Date, Date]
|
||||
}
|
||||
|
||||
function dateRangeCallback(name: string, calculate: (date: Date) => [Date, Date]): DateRange {
|
||||
return {name, calculate};
|
||||
}
|
||||
|
||||
export class RelativeDateRange {
|
||||
private duration: number
|
||||
private unit: "day" | "month" | "year"
|
||||
public name: string
|
||||
|
||||
constructor(duration: number, unit: "day" | "month" | "year") {
|
||||
this.duration = duration;
|
||||
this.unit = unit;
|
||||
|
||||
if (this.duration < 0) {
|
||||
this.name = `Last ${-this.duration} ${pluralize(this.unit, -this.duration)}`;
|
||||
} else {
|
||||
this.name = `Next ${this.duration} ${pluralize(this.unit, this.duration)}`;
|
||||
}
|
||||
}
|
||||
|
||||
calculate(date: Date): [Date, Date] {
|
||||
switch (this.unit) {
|
||||
case "day": {
|
||||
return this.duration < 0
|
||||
? [ startOfDay(addDays(date, this.duration)), endOfDay(date) ]
|
||||
: [ startOfDay(date), endOfDay(addDays(date, this.duration)) ];
|
||||
}
|
||||
case "month": {
|
||||
return this.duration < 0
|
||||
? [ startOfDay(addMonths(date, this.duration)), endOfDay(date) ]
|
||||
: [ startOfDay(date), endOfDay(addMonths(date, this.duration)) ];
|
||||
}
|
||||
case "year": {
|
||||
return this.duration < 0
|
||||
? [ startOfDay(addYears(date, this.duration)), endOfDay(date) ]
|
||||
: [ startOfDay(date), endOfDay(addYears(date, this.duration)) ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function customDateRange(from: Date, to: Date): DateRange {
|
||||
return {name: "Specific Dates", calculate: () => [from, to]}
|
||||
}
|
||||
|
||||
const thisWeek = dateRangeCallback("This week", date => [startOfWeek(date), endOfWeek(date)]);
|
||||
const nextWeek = dateRangeCallback("Next week", date => [startOfWeek(addDays(date, 7)), endOfWeek(addDays(date, 7))]);
|
||||
const lastWeek = dateRangeCallback("Last week", date => [startOfWeek(addDays(date, -7)), endOfWeek(addDays(date, -7))]);
|
||||
|
||||
const thisMonth = dateRangeCallback("This month", date => [startOfMonth(date), endOfMonth(date)]);
|
||||
const nextMonth = dateRangeCallback("Next month", date => [startOfMonth(addMonths(date, 1)), endOfMonth(addMonths(date, 1))]);
|
||||
const lastMonth = dateRangeCallback("Last month", date => [startOfMonth(addMonths(date, -1)), endOfMonth(addMonths(date, -1))]);
|
||||
|
||||
const thisYear = dateRangeCallback("This year", date => [startOfYear(date), endOfYear(date)]);
|
||||
const nextYear = dateRangeCallback("Next year", date => [startOfYear(addYears(date, 1)), endOfYear(addYears(date, 1))]);
|
||||
const lastYear = dateRangeCallback("Last year", date => [startOfYear(addYears(date, -1)), endOfYear(addYears(date, -1))]);
|
||||
|
||||
export const allOffsets: DateRange[] = [
|
||||
thisWeek,
|
||||
nextWeek,
|
||||
new RelativeDateRange(7, "day"),
|
||||
lastWeek,
|
||||
new RelativeDateRange(-7, "day"),
|
||||
thisMonth,
|
||||
nextMonth,
|
||||
new RelativeDateRange(30, "day"),
|
||||
new RelativeDateRange(90, "day"),
|
||||
lastMonth,
|
||||
new RelativeDateRange(-30, "day"),
|
||||
new RelativeDateRange(-90, "day"),
|
||||
thisYear,
|
||||
nextYear,
|
||||
new RelativeDateRange(1, "year"),
|
||||
lastYear,
|
||||
new RelativeDateRange(-1, "year"),
|
||||
];
|
||||
|
||||
export function rangeFromDates(from: Date, to: Date, options: DateRange[]): DateRange {
|
||||
for (const option of options) {
|
||||
const [from2, to2] = option.calculate(new Date());
|
||||
if (from2.getTime() == from.getTime() && to2.getTime() === to.getTime()) {
|
||||
return option;
|
||||
}
|
||||
}
|
||||
|
||||
return customDateRange(from, to);
|
||||
}
|
||||
|
||||
export const pastOffsets: DateRange[] = allOffsets.filter(r => !r.name.startsWith("Next"));
|
||||
@@ -110,4 +110,16 @@ export function addDays(date: Date, days: number): Date {
|
||||
const newDate = new Date(date.getTime());
|
||||
newDate.setDate(newDate.getDate() + days);
|
||||
return newDate;
|
||||
}
|
||||
|
||||
export function addMonths(date: Date, months: number): Date {
|
||||
const newDate = new Date(date.getTime());
|
||||
newDate.setMonth(newDate.getMonth() + months);
|
||||
return newDate;
|
||||
}
|
||||
|
||||
export function addYears(date: Date, years: number): Date {
|
||||
const newDate = new Date(date.getTime());
|
||||
newDate.setFullYear(newDate.getFullYear() + years);
|
||||
return newDate;
|
||||
}
|
||||
Reference in New Issue
Block a user