diff --git a/frontend/package.json b/frontend/package.json index 4da7074e..78ef5480 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -46,6 +46,7 @@ }, "dependencies": { "@fortawesome/free-solid-svg-icons": "^6.6.0", + "cron-parser": "^4.9.0", "date-fns": "^3.6.0", "npm-run-all": "^4.1.5", "pocketbase": "^0.21.5", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index eedfa991..f6dc06e7 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@fortawesome/free-solid-svg-icons': specifier: ^6.6.0 version: 6.6.0 + cron-parser: + specifier: ^4.9.0 + version: 4.9.0 date-fns: specifier: ^3.6.0 version: 3.6.0 @@ -720,6 +723,10 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} @@ -1273,6 +1280,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + luxon@3.5.0: + resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + engines: {node: '>=12'} + magic-string@0.30.11: resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} @@ -2594,6 +2605,10 @@ snapshots: cookie@0.6.0: {} + cron-parser@4.9.0: + dependencies: + luxon: 3.5.0 + cross-spawn@6.0.5: dependencies: nice-try: 1.0.5 @@ -3235,6 +3250,8 @@ snapshots: lru-cache@10.4.3: {} + luxon@3.5.0: {} + magic-string@0.30.11: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 diff --git a/frontend/src/lib/components/DeviceCard.svelte b/frontend/src/lib/components/DeviceCard.svelte index edd55695..7a4b9d3e 100644 --- a/frontend/src/lib/components/DeviceCard.svelte +++ b/frontend/src/lib/components/DeviceCard.svelte @@ -11,8 +11,9 @@ faPen, faRotateLeft } from '@fortawesome/free-solid-svg-icons'; + import cronParser from 'cron-parser'; import type { Locale } from 'date-fns'; - import { formatDistance, parseISO } from 'date-fns'; + import { formatDistance, formatRelative, parseISO } from 'date-fns'; import { de } from 'date-fns/locale/de'; import { enUS } from 'date-fns/locale/en-US'; import { es } from 'date-fns/locale/es'; @@ -128,6 +129,13 @@ toast.error(err.message); }); } + + function getNextCronRelativeTime(expression: string, now: number) { + const cron = cronParser.parseExpression(expression); + return formatRelative(cron.next().toISOString(), now, { + locale: dateFnsLocale + }); + }
@@ -144,18 +152,21 @@ {#if device.wake_cron_enabled || device.shutdown_cron_enabled || device.password} -
+
{#if device.wake_cron_enabled}
{device.wake_cron}{getNextCronRelativeTime(device.wake_cron, now)}
{/if} {#if device.shutdown_cron_enabled}
{device.shutdown_cron}{getNextCronRelativeTime( + device.shutdown_cron, + now + )}
{/if}