This commit is contained in:
@@ -0,0 +1,127 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { endOfMonth, endOfWeek, endOfYear, formatFormTime, lastMonth, monthName, nextMonth, startOfMonth, startOfWeek, startOfYear } from "../utils/time";
|
||||||
|
import EveryMinute from "./EveryMinute.svelte";
|
||||||
|
|
||||||
|
interface DateOption {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
from: Date
|
||||||
|
to: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
export let fromValue: string;
|
||||||
|
export let toValue: string;
|
||||||
|
export let disabled: boolean;
|
||||||
|
export let styled: boolean;
|
||||||
|
|
||||||
|
let selected: string = "custom";
|
||||||
|
let options: DateOption[] = [];
|
||||||
|
let now: Date = new Date();
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
for (const option of options) {
|
||||||
|
if (formatFormTime(option.from) === fromValue && formatFormTime(option.to) === toValue) {
|
||||||
|
selected = option.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (options.length === 0) {
|
||||||
|
let current = startOfMonth(now);
|
||||||
|
const nextWeek = new Date(Date.now() + (86400000 * 7));
|
||||||
|
const lastWeek = new Date(Date.now() - (86400000 * 7));
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_week",
|
||||||
|
label: "This Week",
|
||||||
|
from: startOfWeek(now),
|
||||||
|
to: endOfWeek(now),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_week",
|
||||||
|
label: "Next Week",
|
||||||
|
from: startOfWeek(nextWeek),
|
||||||
|
to: endOfWeek(nextWeek),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_week",
|
||||||
|
label: "Last Week",
|
||||||
|
from: startOfWeek(lastWeek),
|
||||||
|
to: endOfWeek(lastWeek),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_month",
|
||||||
|
label: "This Month",
|
||||||
|
from: current,
|
||||||
|
to: endOfMonth(current),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_month",
|
||||||
|
label: "Next Month",
|
||||||
|
from: nextMonth(current),
|
||||||
|
to: endOfMonth(nextMonth(current)),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_month",
|
||||||
|
label: "Last Month",
|
||||||
|
from: lastMonth(current),
|
||||||
|
to: endOfMonth(lastMonth(current)),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_year",
|
||||||
|
label: "This Year",
|
||||||
|
from: startOfYear(now),
|
||||||
|
to: endOfYear(now),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_year",
|
||||||
|
label: "Next Year",
|
||||||
|
from: startOfYear(new Date(Date.now() + (366.25 * 86400000))),
|
||||||
|
to: endOfYear(new Date(Date.now() + (365.25 * 86400000))),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_year",
|
||||||
|
label: "Last Year",
|
||||||
|
from: startOfYear(new Date(Date.now() - (365.25 * 86400000))),
|
||||||
|
to: endOfYear(new Date(Date.now() - (365.25 * 86400000))),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "custom",
|
||||||
|
label: "Specific Dates",
|
||||||
|
from: null,
|
||||||
|
to: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (selected !== "custom") {
|
||||||
|
const option = options.find(o => o.id === selected);
|
||||||
|
if (option != null) {
|
||||||
|
fromValue = formatFormTime(option.from);
|
||||||
|
toValue = formatFormTime(option.to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<EveryMinute bind:now={now} />
|
||||||
|
<div class:styled>
|
||||||
|
<label for="timeRange">Time Period</label>
|
||||||
|
<select name="timeRange" disabled={disabled} bind:value={selected}>
|
||||||
|
{#each options as option (option.id)}
|
||||||
|
<option value={option.id}>{option.label}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{#if selected === "custom"}
|
||||||
|
<label for="startTime">Start Time</label>
|
||||||
|
<input disabled={disabled} name="startTime" type="datetime-local" bind:value={fromValue} />
|
||||||
|
<label for="endTime">End Time</label>
|
||||||
|
<input disabled={disabled} name="endTime" type="datetime-local" bind:value={toValue} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import { endOfMonth, endOfWeek, endOfYear, formatFormTime, lastMonth, monthName, nextMonth, startOfMonth, startOfWeek, startOfYear } from "../utils/time";
|
||||||
|
import EveryMinute from "./EveryMinute.svelte";
|
||||||
|
|
||||||
|
interface DateOption {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
value: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
export let value: string;
|
||||||
|
export let disabled: boolean;
|
||||||
|
|
||||||
|
let selected: string = "custom";
|
||||||
|
let options: DateOption[] = [];
|
||||||
|
let now: Date = new Date();
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (value === "") {
|
||||||
|
selected = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const option of options) {
|
||||||
|
if (formatFormTime(option.value) === value) {
|
||||||
|
selected = option.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: {
|
||||||
|
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: "none",
|
||||||
|
label: "No deadline",
|
||||||
|
value: new Date(Number.NaN),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_week",
|
||||||
|
label: "End of this Week",
|
||||||
|
value: endOfWeek(now),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_week",
|
||||||
|
label: "End of next Week",
|
||||||
|
value: endOfWeek(nextWeek),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_week",
|
||||||
|
label: "End of last Week",
|
||||||
|
value: endOfWeek(lastWeek),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_month",
|
||||||
|
label: "End of this month",
|
||||||
|
value: endOfMonth(current),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_month",
|
||||||
|
label: "End of next month",
|
||||||
|
value: endOfMonth(nextMonth(current)),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_month",
|
||||||
|
label: "End of last month",
|
||||||
|
value: endOfMonth(lastMonth(current)),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "this_year",
|
||||||
|
label: "This Year",
|
||||||
|
value: endOfYear(now),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "next_year",
|
||||||
|
label: "Next Year",
|
||||||
|
value: endOfYear(new Date(Date.now() + (365.25 * 86400000))),
|
||||||
|
});
|
||||||
|
options.push({
|
||||||
|
id: "last_year",
|
||||||
|
label: "Last Year",
|
||||||
|
value: endOfYear(new Date(Date.now() - (365.25 * 86400000))),
|
||||||
|
});
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
id: "custom",
|
||||||
|
label: "Specific Dates",
|
||||||
|
value: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
if (selected !== "custom") {
|
||||||
|
const option = options.find(o => o.id === selected);
|
||||||
|
if (option != null) {
|
||||||
|
value = formatFormTime(option.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<EveryMinute bind:now={now} />
|
||||||
|
<select name="endTime" disabled={disabled} bind:value={selected}>
|
||||||
|
{#each options as option (option.id)}
|
||||||
|
<option value={option.id}>{option.label}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{#if selected === "custom"}
|
||||||
|
<input disabled={disabled} name="value" type="datetime-local" bind:value={value} />
|
||||||
|
{/if}
|
||||||
@@ -107,7 +107,7 @@ import TimeProgress from "./TimeProgress.svelte";
|
|||||||
padding: 0 0.5ch;
|
padding: 0 0.5ch;
|
||||||
width: 2ch;
|
width: 2ch;
|
||||||
padding-top: 0.125em;
|
padding-top: 0.125em;
|
||||||
color: #333;
|
color: #444;
|
||||||
}
|
}
|
||||||
div.icon.completed {
|
div.icon.completed {
|
||||||
color: #484;
|
color: #484;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
let completedTasks: TaskResult[] = [];
|
let completedTasks: TaskResult[] = [];
|
||||||
let onholdTasks: TaskResult[] = [];
|
let onholdTasks: TaskResult[] = [];
|
||||||
let failedTasks: TaskResult[] = [];
|
let failedTasks: TaskResult[] = [];
|
||||||
|
let nonHiddenTasks: TaskResult[] = [];
|
||||||
|
|
||||||
$: mdAddTask = {name:"task.add", project};
|
$: mdAddTask = {name:"task.add", project};
|
||||||
$: mdProjectEdit = {name:"project.edit", project};
|
$: mdProjectEdit = {name:"project.edit", project};
|
||||||
@@ -33,25 +34,18 @@
|
|||||||
|
|
||||||
$: {
|
$: {
|
||||||
activeTasks = project.tasks.filter(t => t.active);
|
activeTasks = project.tasks.filter(t => t.active);
|
||||||
|
inactiveTasks = project.tasks.filter(t => !t.active);
|
||||||
|
|
||||||
if (!hideInactive) {
|
todoTasks = inactiveTasks.filter(t => t.statusTag === "to do" || t.statusTag === "idea");
|
||||||
inactiveTasks = project.tasks.filter(t => !t.active);
|
onholdTasks = inactiveTasks.filter(t => t.statusTag === "on hold");
|
||||||
|
completedTasks = inactiveTasks.filter(t => t.statusTag === "completed" || t.statusTag == null);
|
||||||
|
failedTasks = inactiveTasks.filter(t => t.statusTag === "failed" || t.statusTag === "declined");
|
||||||
|
|
||||||
todoTasks = inactiveTasks.filter(t => t.statusTag === "to do" || t.statusTag === "idea");
|
nonHiddenTasks = [...activeTasks, ...todoTasks, ...onholdTasks];
|
||||||
completedTasks = inactiveTasks.filter(t => t.statusTag === "completed" || t.statusTag == null);
|
|
||||||
onholdTasks = inactiveTasks.filter(t => t.statusTag === "on hold" || t.statusTag === "postponed");
|
|
||||||
failedTasks = inactiveTasks.filter(t => t.statusTag === "failed" || t.statusTag === "declined" || t.statusTag === "wont do");
|
|
||||||
} else {
|
|
||||||
inactiveTasks = [];
|
|
||||||
todoTasks = [];
|
|
||||||
completedTasks = [];
|
|
||||||
onholdTasks = [];
|
|
||||||
failedTasks = [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<StatusColor affects="project" selected entry={project}>
|
<StatusColor affects="project" entry={project}>
|
||||||
<ParentEntry
|
<ParentEntry
|
||||||
full={showAllOptions}
|
full={showAllOptions}
|
||||||
entry={project}
|
entry={project}
|
||||||
@@ -69,12 +63,12 @@
|
|||||||
</OptionRow>
|
</OptionRow>
|
||||||
{/if}
|
{/if}
|
||||||
{#if hideInactive}
|
{#if hideInactive}
|
||||||
<TaskList header="" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
|
<TaskList header="" tasks={nonHiddenTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
{:else}
|
{:else}
|
||||||
<TaskList header="Active" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
|
<TaskList header="Active" tasks={activeTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
<TaskList header="To Do" tasks={todoTasks} project={project} showAllOptions={showAllOptions} />
|
<TaskList header="To Do" tasks={todoTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
<TaskList header="Completed" tasks={completedTasks} project={project} showAllOptions={showAllOptions} />
|
|
||||||
<TaskList header="On Hold" tasks={onholdTasks} project={project} showAllOptions={showAllOptions} />
|
<TaskList header="On Hold" tasks={onholdTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
|
<TaskList header="Completed" tasks={completedTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
<TaskList header="Failed" tasks={failedTasks} project={project} showAllOptions={showAllOptions} />
|
<TaskList header="Failed" tasks={failedTasks} project={project} showAllOptions={showAllOptions} />
|
||||||
{/if}
|
{/if}
|
||||||
</ParentEntry>
|
</ParentEntry>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { tick } from "svelte";
|
||||||
|
|
||||||
|
import stuffLogClient from "../clients/stufflog";
|
||||||
import type Project from "../models/project";
|
import type Project from "../models/project";
|
||||||
import type { TaskResult } from "../models/task";
|
import type { TaskResult, TaskUpdate } from "../models/task";
|
||||||
|
import markStale from "../stores/markStale";
|
||||||
import type { ModalData } from "../stores/modal";
|
import type { ModalData } from "../stores/modal";
|
||||||
import ChildEntry from "./ChildEntry.svelte";
|
import ChildEntry from "./ChildEntry.svelte";
|
||||||
import DateSpan from "./DateSpan.svelte";
|
import DateSpan from "./DateSpan.svelte";
|
||||||
@@ -19,11 +23,42 @@
|
|||||||
let mdLogAdd: ModalData;
|
let mdLogAdd: ModalData;
|
||||||
let mdTaskEdit: ModalData;
|
let mdTaskEdit: ModalData;
|
||||||
let mdTaskDelete: ModalData;
|
let mdTaskDelete: ModalData;
|
||||||
|
let isMoving = false;
|
||||||
|
|
||||||
function toggleShowLogs() {
|
function toggleShowLogs() {
|
||||||
showLogs = !showLogs;
|
showLogs = !showLogs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateTask(update: TaskUpdate) {
|
||||||
|
isMoving = true;
|
||||||
|
stuffLogClient.updateTask(task.id, update).finally(() => {
|
||||||
|
markStale("task", "project");
|
||||||
|
tick().then(() => {
|
||||||
|
isMoving = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToActive() {
|
||||||
|
updateTask({clearStatusTag: true, active: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToToDo() {
|
||||||
|
updateTask({statusTag: "to do", active: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToOnHold() {
|
||||||
|
updateTask({statusTag: "on hold", active: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToFailed() {
|
||||||
|
updateTask({statusTag: "failed", active: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveToDeclined() {
|
||||||
|
updateTask({statusTag: "declined", active: false});
|
||||||
|
}
|
||||||
|
|
||||||
$: mdLogAdd = {name: "log.add", task: {...task, project}};
|
$: mdLogAdd = {name: "log.add", task: {...task, project}};
|
||||||
$: mdTaskEdit = {name: "task.edit", task: {...task, project}};
|
$: mdTaskEdit = {name: "task.edit", task: {...task, project}};
|
||||||
$: mdTaskDelete = {name: "task.delete", task: {...task, project}};
|
$: mdTaskDelete = {name: "task.delete", task: {...task, project}};
|
||||||
@@ -43,6 +78,22 @@
|
|||||||
{#if showAllOptions}
|
{#if showAllOptions}
|
||||||
<Option open={mdTaskEdit}>Edit</Option>
|
<Option open={mdTaskEdit}>Edit</Option>
|
||||||
<Option open={mdTaskDelete}>Delete</Option>
|
<Option open={mdTaskDelete}>Delete</Option>
|
||||||
|
·
|
||||||
|
{#if !isMoving && (!task.active) }
|
||||||
|
<Option on:click={moveToActive}>Active</Option>
|
||||||
|
{/if}
|
||||||
|
{#if !isMoving && (task.statusTag !== "to do") }
|
||||||
|
<Option on:click={moveToToDo}>To Do</Option>
|
||||||
|
{/if}
|
||||||
|
{#if !isMoving && (task.statusTag !== "on hold") }
|
||||||
|
<Option on:click={moveToOnHold}>On Hold</Option>
|
||||||
|
{/if}
|
||||||
|
{#if !isMoving && (task.statusTag !== "declined") }
|
||||||
|
<Option on:click={moveToDeclined}>Won't Do</Option>
|
||||||
|
{/if}
|
||||||
|
{#if !isMoving && (task.statusTag !== "failed") }
|
||||||
|
<Option on:click={moveToFailed}>Failed</Option>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</OptionRow>
|
</OptionRow>
|
||||||
{#if showLogs && task.logs.length > 0}
|
{#if showLogs && task.logs.length > 0}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Checkbox from "../components/Checkbox.svelte";
|
|||||||
import GroupItemSelect from "../components/GroupItemSelect.svelte";
|
import GroupItemSelect from "../components/GroupItemSelect.svelte";
|
||||||
import groupStore from "../stores/group";
|
import groupStore from "../stores/group";
|
||||||
import type { GroupResult } from "../models/group";
|
import type { GroupResult } from "../models/group";
|
||||||
|
import DateRangeSelect from "../components/DateRangeSelect.svelte";
|
||||||
|
|
||||||
export let deletion = false;
|
export let deletion = false;
|
||||||
export let creation = false;
|
export let creation = false;
|
||||||
@@ -132,10 +133,7 @@ import type { GroupResult } from "../models/group";
|
|||||||
<option value="item" selected={"item" === compositionMode}>Item</option>
|
<option value="item" selected={"item" === compositionMode}>Item</option>
|
||||||
<option value="task" selected={"task" === compositionMode}>Task</option>
|
<option value="task" selected={"task" === compositionMode}>Task</option>
|
||||||
</select>
|
</select>
|
||||||
<label for="startTime">Start Time</label>
|
<DateRangeSelect disabled={deletion} bind:fromValue={startTime} bind:toValue={endTime} />
|
||||||
<input disabled={deletion} name="startTime" type="datetime-local" bind:value={startTime} />
|
|
||||||
<label for="endTime">End Time</label>
|
|
||||||
<input disabled={deletion} name="endTime" type="datetime-local" bind:value={endTime} />
|
|
||||||
<label for="taskFilter">Task Filter (Optional)</label>
|
<label for="taskFilter">Task Filter (Optional)</label>
|
||||||
<input disabled={deletion} name="taskFilter" type="text" bind:value={taskFilter} />
|
<input disabled={deletion} name="taskFilter" type="text" bind:value={taskFilter} />
|
||||||
<label for="itemFilter">Item Filter (Optional)</label>
|
<label for="itemFilter">Item Filter (Optional)</label>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import stuffLogClient from "../clients/stufflog";
|
import stuffLogClient from "../clients/stufflog";
|
||||||
|
import DeadlineSelect from "../components/DeadlineSelect.svelte";
|
||||||
import ItemSelect from "../components/ItemSelect.svelte";
|
import ItemSelect from "../components/ItemSelect.svelte";
|
||||||
import Modal from "../components/Modal.svelte";
|
import Modal from "../components/Modal.svelte";
|
||||||
import StatusTagSelect from "../components/StatusTagSelect.svelte";
|
import StatusTagSelect from "../components/StatusTagSelect.svelte";
|
||||||
@@ -117,10 +118,10 @@
|
|||||||
<label for="itemAmount">Amount</label>
|
<label for="itemAmount">Amount</label>
|
||||||
<input disabled={deletion} name="itemAmount" type="number" bind:value={itemAmount} />
|
<input disabled={deletion} name="itemAmount" type="number" bind:value={itemAmount} />
|
||||||
<label for="endTime">Deadline (Optional)</label>
|
<label for="endTime">Deadline (Optional)</label>
|
||||||
<input disabled={deletion} name="endTime" type="datetime-local" bind:value={endTime} />
|
<DeadlineSelect disabled={deletion} bind:value={endTime} />
|
||||||
<label for="statusTag">Status</label>
|
<label for="statusTag">Status</label>
|
||||||
<StatusTagSelect disabled={deletion} bind:value={statusTag} />
|
<StatusTagSelect disabled={deletion} bind:value={statusTag} />
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<button disabled={loading} type="submit">{verb} Task</button>
|
<button disabled={loading} type="submit">{verb} Task</button>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const pad = (n:number) => n < 10 ? '0'+n : n.toString();
|
const pad = (n:number) => n < 10 ? '0'+n : n.toString();
|
||||||
const weekDay = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
|
const weekDay = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"];
|
||||||
|
const monthNames = ["January","February","March","April","June","july","August","September","October","November","December"]
|
||||||
|
|
||||||
export function formatTime(time: Date | string): string {
|
export function formatTime(time: Date | string): string {
|
||||||
if (!(time instanceof Date)) {
|
if (!(time instanceof Date)) {
|
||||||
@@ -39,6 +40,22 @@ export function formatFormTime(time: Date | string): string {
|
|||||||
return `${time.getFullYear()}-${pad(time.getMonth()+1)}-${pad(time.getDate())}T${pad(time.getHours())}:${pad(time.getMinutes())}`;
|
return `${time.getFullYear()}-${pad(time.getMonth()+1)}-${pad(time.getDate())}T${pad(time.getHours())}:${pad(time.getMinutes())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function startOfMonth(now: Date): Date {
|
||||||
|
return new Date(now.getFullYear(), now.getMonth(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startOfYear(now: Date): Date {
|
||||||
|
return new Date(now.getFullYear(), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function endOfYear(now: Date): Date {
|
||||||
|
return new Date(new Date(now.getFullYear() + 1, 0, 1).getTime() - 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function endOfMonth(now: Date): Date {
|
||||||
|
return new Date(nextMonth(now).getTime() - 60000)
|
||||||
|
}
|
||||||
|
|
||||||
export function nextMonth(now: Date): Date {
|
export function nextMonth(now: Date): Date {
|
||||||
let result: Date;
|
let result: Date;
|
||||||
if (now.getMonth() == 11) {
|
if (now.getMonth() == 11) {
|
||||||
@@ -48,4 +65,27 @@ export function nextMonth(now: Date): Date {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Date(result.getTime());
|
return new Date(result.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lastMonth(now: Date): Date {
|
||||||
|
let result: Date;
|
||||||
|
if (now.getMonth() == 0) {
|
||||||
|
result = new Date(now.getFullYear() - 1, 11, 1);
|
||||||
|
} else {
|
||||||
|
result = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Date(result.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startOfWeek(now: Date): Date {
|
||||||
|
return new Date(now.getTime() - ((now.getTimezoneOffset() * -60000) + ((now.getTime() + (86400000 * 3)) % (86400000 * 7))));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function endOfWeek(now: Date): Date {
|
||||||
|
return new Date(startOfWeek(now).getTime() + (86400000 * 6) + (3600000 * 23) + (60000 * 59))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function monthName(date: Date): string {
|
||||||
|
return monthNames[date.getMonth()]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user