From 69512a4f1d9db5feec6ec6cba8972205309cb71f Mon Sep 17 00:00:00 2001 From: Klemek Date: Tue, 21 Jul 2026 10:23:56 +0200 Subject: [PATCH] feat: better monthly select --- resources/lang/en.json | 12 ++++-- resources/lang/fr.json | 12 ++++-- resources/ts/components/CronInput.vue | 53 +++++++++++++++++---------- resources/ts/lib/recurrence.ts | 24 ++++++++++++ 4 files changed, 74 insertions(+), 27 deletions(-) diff --git a/resources/lang/en.json b/resources/lang/en.json index d489cb0..cd90fdb 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -22,10 +22,14 @@ "Sunday" ], "month": { - "st": "st", - "nd": "nd", - "rd": "rd", - "th": "th" + "st": "The {0}st", + "nd": "The {0}nd", + "rd": "The {0}rd", + "th": "The {0}th", + "first_day": "First day of month", + "last_day": "Last day of month", + "last": "Last", + "first": "First" }, "year": [ "January", diff --git a/resources/lang/fr.json b/resources/lang/fr.json index 5b34b42..461e21f 100644 --- a/resources/lang/fr.json +++ b/resources/lang/fr.json @@ -22,10 +22,14 @@ "Dimanche" ], "month": { - "st": "", - "nd": "", - "rd": "", - "th": "" + "st": "Le {0}", + "nd": "Le {0}", + "rd": "Le {0}", + "th": "Le {0}", + "first_day": "Premier jour du mois", + "last_day": "Dernier jour du mois", + "last": "Dernier", + "first": "Premier" }, "year": [ "Janvier", diff --git a/resources/ts/components/CronInput.vue b/resources/ts/components/CronInput.vue index 73198a8..fe65c7a 100644 --- a/resources/ts/components/CronInput.vue +++ b/resources/ts/components/CronInput.vue @@ -11,23 +11,23 @@ const valid = ref(true); const props = defineProps<{ editMode: boolean }>(); const cronType = ref(CronType.MANUAL); -const cronValue = ref(0); +const cronValue = ref('0'); function onCronChanged() { const data = parseCron(cron.value); rawCron.value = cron.value ?? DEFAULT_CRON; cronType.value = data.type; - cronValue.value = data.value; + cronValue.value = data.value.toFixed(0); } function updateCron() { - cron.value = getCron(cronType.value, cronValue.value, rawCron.value); + cron.value = getCron(cronType.value, parseInt(cronValue.value), rawCron.value); } function onChangeCronType() { switch (cronType.value) { case CronType.EVERY_DAY: - cronValue.value = 0; + cronValue.value = '0'; break; case CronType.EVERY_WEEK: case CronType.EVERY_MONTH: @@ -35,7 +35,7 @@ function onChangeCronType() { case CronType.EVERY_N_DAYS: case CronType.EVERY_N_WEEKS: case CronType.EVERY_N_MONTHS: - cronValue.value = 1; + cronValue.value = '1'; break; case CronType.CUSTOM: cron.value ??= DEFAULT_CRON; @@ -106,7 +106,7 @@ watch(cron, () => { > + + + diff --git a/resources/ts/lib/recurrence.ts b/resources/ts/lib/recurrence.ts index d4fb41f..75ab251 100644 --- a/resources/ts/lib/recurrence.ts +++ b/resources/ts/lib/recurrence.ts @@ -36,6 +36,21 @@ export function parseCron(cron: string | null): { type: CronType.EVERY_MONTH, value: parseInt(value[1] ?? ""), }; + } else if ((value = /^0 0 L \* \*$/i.exec(cron)) !== null) { + return { + type: CronType.EVERY_MONTH, + value: 32, + }; + } else if ((value = /^0 0 \* \* (\d+)\#1$/i.exec(cron)) !== null) { + return { + type: CronType.EVERY_MONTH, + value: -parseInt(value[1] ?? ""), + }; + } else if ((value = /^0 0 \* \* (\d+)L$/i.exec(cron)) !== null) { + return { + type: CronType.EVERY_MONTH, + value: -parseInt(value[1] ?? "")-7, + }; } else if ((value = /^0 0 1 (\d+) \*$/i.exec(cron)) !== null) { return { type: CronType.EVERY_YEAR, @@ -99,6 +114,15 @@ export function getCron( case CronType.EVERY_WEEK: return `0 0 * * ${value.toFixed(0)}`; case CronType.EVERY_MONTH: + if (value === 32) { + return `0 0 L * *`; + } + if (value < 0 && value >= -7) { + return `0 0 * * ${(-value).toFixed(0)}#1`; + } + if (value < -7 && value >= -14) { + return `0 0 * * ${(-value-7).toFixed(0)}L`; + } return `0 0 ${value.toFixed(0)} * *`; case CronType.EVERY_YEAR: return `0 0 1 ${value.toFixed(0)} *`;