Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae030ea7f5 | ||
|
|
8007468abd | ||
|
|
f3cd3b8086 | ||
|
|
c91fc10f9f | ||
|
|
ffab02a3f9 | ||
|
|
aeeabe81c7 | ||
|
|
87eff715f6 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tout-doux",
|
||||
"version": "1.7.5",
|
||||
"version": "1.7.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "tout-doux"
|
||||
version = "1.7.5"
|
||||
version = "1.7.8"
|
||||
description = ""
|
||||
requires-python = ">=3.14"
|
||||
dependencies = [
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import { parseDateInput, formatDateInput } from "@/lib/dates";
|
||||
|
||||
const emit = defineEmits<(e: "input"|"change", value: Date) => void>();
|
||||
|
||||
const date = defineModel<Date>({ required: true });
|
||||
|
||||
|
||||
function onInput(event: Event) {
|
||||
const inputValue = (event.target as HTMLInputElement).value;
|
||||
date.value = new Date(inputValue);
|
||||
date.value = parseDateInput(inputValue);
|
||||
|
||||
emit('input', date.value);
|
||||
}
|
||||
|
||||
function onChange(event: Event) {
|
||||
const inputValue = (event.target as HTMLInputElement).value;
|
||||
date.value = new Date(inputValue);
|
||||
date.value = parseDateInput(inputValue);
|
||||
emit('change', date.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
:value="date.toISOString().substring(0, 10)"
|
||||
:value="formatDateInput(date)"
|
||||
type="date"
|
||||
@input="onInput"
|
||||
@change="onChange"
|
||||
|
||||
@@ -173,7 +173,7 @@ watch(task, () => {
|
||||
:class="showMissed && missed ? 'text-error' : ''"
|
||||
@click.prevent="onOpen"
|
||||
>
|
||||
<div>{{ task.name }}</div>
|
||||
<div :class="isOneTime(task.reset_cron) ? 'italic' : ''">{{ task.name }}</div>
|
||||
<div
|
||||
v-if="showLastChecked && !checked && task.check_date"
|
||||
class="font-light text-xs italic"
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
import { enUS, fr } from "date-fns/locale";
|
||||
|
||||
export function parseDateInput(rawDate: string): Date {
|
||||
const parts = rawDate.split('-').map(part => parseInt(part, 10));
|
||||
if (!parts[0] || !parts[1] || !parts[2]) {
|
||||
return new Date(new Date().setHours(0, 0, 0, 0))
|
||||
}
|
||||
return new Date(parts[0], parts[1] - 1, parts[2]);
|
||||
}
|
||||
|
||||
export function formatDateInput(date: Date): string {
|
||||
return [
|
||||
date.getFullYear().toFixed(0),
|
||||
(date.getMonth() + 1).toFixed(0).padStart(2, '0'),
|
||||
(date.getDate()).toFixed(0).padStart(2, '0'),
|
||||
].join('-');
|
||||
}
|
||||
|
||||
export function relativeTime(date: Date, locale: string): string {
|
||||
return formatDistanceToNow(date, {
|
||||
addSuffix: true,
|
||||
|
||||
@@ -22,7 +22,7 @@ export function parseCron(cron: string | null): {
|
||||
value: 0,
|
||||
date: null,
|
||||
};
|
||||
} else if (cron.startsWith("RRULE:") || cron.startsWith("DTSTART:")) {
|
||||
} else if (isRrule(cron)) {
|
||||
return parseRrule(cron);
|
||||
} else if ((value = /^0 (\d+) \* \* \*$/i.exec(cron)) !== null) {
|
||||
return {
|
||||
@@ -75,6 +75,10 @@ export function parseCron(cron: string | null): {
|
||||
}
|
||||
}
|
||||
|
||||
function isRrule(cron: string): boolean {
|
||||
return cron.startsWith("RRULE:") || cron.startsWith("DTSTART:");
|
||||
}
|
||||
|
||||
export function parseRrule(rule: string): {
|
||||
type: CronType;
|
||||
value: number;
|
||||
@@ -193,11 +197,10 @@ export function nextCronReset(
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (cron.startsWith("RRULE:")) {
|
||||
if (isRrule(cron)) {
|
||||
try {
|
||||
const rule = new RRule({
|
||||
...RRule.parseString(cron),
|
||||
count: 2,
|
||||
});
|
||||
|
||||
return rule.after(date) ?? null;
|
||||
|
||||
Reference in New Issue
Block a user