diff --git a/Cargo.lock b/Cargo.lock index aaa6632..55a1559 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -551,7 +551,7 @@ dependencies = [ "derive_builder", "diligent-date-parser", "never", - "quick-xml", + "quick-xml 0.37.5", "serde", ] @@ -1922,6 +1922,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_builder" version = "0.20.2" @@ -2332,11 +2343,12 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fancy-regex" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" +checksum = "d6215aee357f8c7c989ebb4b8466ca4d7dc93b3957039f2fc3ea2ade8ea5f279" dependencies = [ "bit-set", + "derivative", "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -4394,7 +4406,7 @@ dependencies = [ "futures", "httparse", "network-interface", - "quick-xml", + "quick-xml 0.37.5", "reqwest", "serde", "tokio", @@ -5166,7 +5178,7 @@ dependencies = [ "itertools 0.14.0", "parking_lot 0.12.4", "percent-encoding", - "quick-xml", + "quick-xml 0.37.5", "rand 0.9.1", "reqwest", "ring", @@ -5219,7 +5231,7 @@ dependencies = [ "log", "md-5", "percent-encoding", - "quick-xml", + "quick-xml 0.37.5", "reqwest", "serde", "serde_json", @@ -6505,6 +6517,16 @@ dependencies = [ "serde", ] +[[package]] +name = "quick-xml" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8927b0664f5c5a98265138b7e3f90aa19a6b21353182469ace36d4ac527b7b1b" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quinn" version = "0.11.8" @@ -6798,7 +6820,7 @@ dependencies = [ "paste", "percent-encoding", "polars", - "quick-xml", + "quick-xml 0.38.0", "quirks_path", "rand 0.9.1", "regex", @@ -7233,7 +7255,7 @@ dependencies = [ "atom_syndication", "derive_builder", "never", - "quick-xml", + "quick-xml 0.37.5", "serde", ] diff --git a/apps/recorder/Cargo.toml b/apps/recorder/Cargo.toml index bef7b93..b156520 100644 --- a/apps/recorder/Cargo.toml +++ b/apps/recorder/Cargo.toml @@ -109,7 +109,7 @@ sea-orm = { version = "1.1", features = [ figment = { version = "0.10", features = ["toml", "json", "env", "yaml"] } sea-orm-migration = { version = "1.1", features = ["runtime-tokio"] } rss = { version = "2", features = ["builders", "with-serde"] } -fancy-regex = "0.14" +fancy-regex = "0.15" lightningcss = "1.0.0-alpha.66" html-escape = "0.2.13" opendal = { version = "0.53", features = ["default", "services-fs"] } @@ -126,6 +126,7 @@ seaography = { version = "1.1", features = [ "with-postgres-array", "with-json-as-scalar", "with-custom-as-json", + "with-chrono-datetime-utc-as-timestamp", ] } tower = { version = "0.5.2", features = ["util"] } tower-http = { version = "0.6", features = [ @@ -160,7 +161,7 @@ polars = { version = "0.49.1", features = [ "lazy", "diagonal_concat", ], optional = true } -quick-xml = { version = "0.37.5", features = [ +quick-xml = { version = "0.38", features = [ "serialize", "serde-types", "serde", diff --git a/apps/webui/src/components/domains/cron/README.md b/apps/webui/src/components/ui/cron/README.md similarity index 100% rename from apps/webui/src/components/domains/cron/README.md rename to apps/webui/src/components/ui/cron/README.md diff --git a/apps/webui/src/components/domains/cron/cron-builder.tsx b/apps/webui/src/components/ui/cron/cron-builder.tsx similarity index 73% rename from apps/webui/src/components/domains/cron/cron-builder.tsx rename to apps/webui/src/components/ui/cron/cron-builder.tsx index 55b27ba..6b9ddd4 100644 --- a/apps/webui/src/components/domains/cron/cron-builder.tsx +++ b/apps/webui/src/components/ui/cron/cron-builder.tsx @@ -1,5 +1,5 @@ -import { getFutureMatches } from '@datasert/cronjs-matcher'; -import { Calendar, Clock, Info, Settings, Zap } from 'lucide-react'; +import { getFutureMatches } from "@datasert/cronjs-matcher"; +import { Calendar, Clock, Info, Settings, Zap } from "lucide-react"; import { type CSSProperties, type FC, @@ -8,109 +8,109 @@ import { useEffect, useMemo, useState, -} from 'react'; -import { Badge } from '@/components/ui/badge'; -import { Button } from '@/components/ui/button'; +} from "react"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, -} from '@/components/ui/card'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; +} from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, -} from '@/components/ui/select'; -import { Separator } from '@/components/ui/separator'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; -import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; -import { cn } from '@/presentation/utils'; +} from "@/components/ui/select"; +import { Separator } from "@/components/ui/separator"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; +import { cn } from "@/presentation/utils"; import { type CronBuilderProps, CronField, type CronFieldConfig, CronPeriod, type CronPreset, -} from './types'; +} from "./types.js"; const CRON_PRESETS: CronPreset[] = [ { - label: 'Every minute', - value: '0 * * * * *', - description: 'Runs every minute', - category: 'common', + label: "Every minute", + value: "0 * * * * *", + description: "Runs every minute", + category: "common", }, { - label: 'Every 5 minutes', - value: '0 */5 * * * *', - description: 'Runs every 5 minutes', - category: 'common', + label: "Every 5 minutes", + value: "0 */5 * * * *", + description: "Runs every 5 minutes", + category: "common", }, { - label: 'Every 15 minutes', - value: '0 */15 * * * *', - description: 'Runs every 15 minutes', - category: 'common', + label: "Every 15 minutes", + value: "0 */15 * * * *", + description: "Runs every 15 minutes", + category: "common", }, { - label: 'Every 30 minutes', - value: '0 */30 * * * *', - description: 'Runs every 30 minutes', - category: 'common', + label: "Every 30 minutes", + value: "0 */30 * * * *", + description: "Runs every 30 minutes", + category: "common", }, { - label: 'Every hour', - value: '0 0 * * * *', - description: 'Runs at the top of every hour', - category: 'common', + label: "Every hour", + value: "0 0 * * * *", + description: "Runs at the top of every hour", + category: "common", }, { - label: 'Every 6 hours', - value: '0 0 */6 * * *', - description: 'Runs every 6 hours', - category: 'common', + label: "Every 6 hours", + value: "0 0 */6 * * *", + description: "Runs every 6 hours", + category: "common", }, { - label: 'Daily at midnight', - value: '0 0 0 * * *', - description: 'Runs once daily at 00:00', - category: 'daily', + label: "Daily at midnight", + value: "0 0 0 * * *", + description: "Runs once daily at 00:00", + category: "daily", }, { - label: 'Daily at 9 AM', - value: '0 0 9 * * *', - description: 'Runs daily at 9:00 AM', - category: 'daily', + label: "Daily at 9 AM", + value: "0 0 9 * * *", + description: "Runs daily at 9:00 AM", + category: "daily", }, { - label: 'Weekdays at 9 AM', - value: '0 0 9 * * 1-5', - description: 'Runs Monday to Friday at 9:00 AM', - category: 'weekly', + label: "Weekdays at 9 AM", + value: "0 0 9 * * 1-5", + description: "Runs Monday to Friday at 9:00 AM", + category: "weekly", }, { - label: 'Every Sunday', - value: '0 0 0 * * 0', - description: 'Runs every Sunday at midnight', - category: 'weekly', + label: "Every Sunday", + value: "0 0 0 * * 0", + description: "Runs every Sunday at midnight", + category: "weekly", }, { - label: 'First day of month', - value: '0 0 0 1 * *', - description: 'Runs on the 1st day of every month', - category: 'monthly', + label: "First day of month", + value: "0 0 0 1 * *", + description: "Runs on the 1st day of every month", + category: "monthly", }, { - label: 'Every year', - value: '0 0 0 1 1 *', - description: 'Runs on January 1st every year', - category: 'yearly', + label: "Every year", + value: "0 0 0 1 1 *", + description: "Runs on January 1st every year", + category: "yearly", }, ]; @@ -119,98 +119,98 @@ const FIELD_CONFIGS: Record = { min: 0, max: 59, step: 1, - allowSpecial: ['*', '?'], + allowSpecial: ["*", "?"], }, minutes: { min: 0, max: 59, step: 1, - allowSpecial: ['*', '?'], + allowSpecial: ["*", "?"], }, hours: { min: 0, max: 23, step: 1, - allowSpecial: ['*', '?'], + allowSpecial: ["*", "?"], }, dayOfMonth: { min: 1, max: 31, step: 1, - allowSpecial: ['*', '?', 'L', 'W'], + allowSpecial: ["*", "?", "L", "W"], options: [ - { label: 'Any day', value: '*' }, - { label: 'No specific day', value: '?' }, - { label: 'Last day', value: 'L' }, - { label: 'Weekday', value: 'W' }, + { label: "Any day", value: "*" }, + { label: "No specific day", value: "?" }, + { label: "Last day", value: "L" }, + { label: "Weekday", value: "W" }, ], }, month: { min: 1, max: 12, step: 1, - allowSpecial: ['*'], + allowSpecial: ["*"], options: [ - { label: 'January', value: 1 }, - { label: 'February', value: 2 }, - { label: 'March', value: 3 }, - { label: 'April', value: 4 }, - { label: 'May', value: 5 }, - { label: 'June', value: 6 }, - { label: 'July', value: 7 }, - { label: 'August', value: 8 }, - { label: 'September', value: 9 }, - { label: 'October', value: 10 }, - { label: 'November', value: 11 }, - { label: 'December', value: 12 }, + { label: "January", value: 1 }, + { label: "February", value: 2 }, + { label: "March", value: 3 }, + { label: "April", value: 4 }, + { label: "May", value: 5 }, + { label: "June", value: 6 }, + { label: "July", value: 7 }, + { label: "August", value: 8 }, + { label: "September", value: 9 }, + { label: "October", value: 10 }, + { label: "November", value: 11 }, + { label: "December", value: 12 }, ], }, dayOfWeek: { min: 0, max: 6, step: 1, - allowSpecial: ['*', '?'], + allowSpecial: ["*", "?"], options: [ - { label: 'Sunday', value: 0 }, - { label: 'Monday', value: 1 }, - { label: 'Tuesday', value: 2 }, - { label: 'Wednesday', value: 3 }, - { label: 'Thursday', value: 4 }, - { label: 'Friday', value: 5 }, - { label: 'Saturday', value: 6 }, + { label: "Sunday", value: 0 }, + { label: "Monday", value: 1 }, + { label: "Tuesday", value: 2 }, + { label: "Wednesday", value: 3 }, + { label: "Thursday", value: 4 }, + { label: "Friday", value: 5 }, + { label: "Saturday", value: 6 }, ], }, year: { min: 0, max: 9999, step: 1, - allowSpecial: ['*', '?'], + allowSpecial: ["*", "?"], }, }; const PERIOD_CONFIGS = { minute: { label: CronPeriod.Minute, - description: 'Run every minute', - template: '0 * * * * *', + description: "Run every minute", + template: "0 * * * * *", fields: [CronField.Minutes], }, hourly: { label: CronPeriod.Hourly, - description: 'Run every hour', - template: '0 0 * * * *', + description: "Run every hour", + template: "0 0 * * * *", fields: [CronField.Minutes, CronField.Hours], }, daily: { label: CronPeriod.Daily, - description: 'Run every day', - template: '0 0 0 * * *', + description: "Run every day", + template: "0 0 0 * * *", fields: [CronField.Seconds, CronField.Minutes, CronField.Hours], }, weekly: { label: CronPeriod.Weekly, - description: 'Run every week', - template: '0 0 0 * * 0', + description: "Run every week", + template: "0 0 0 * * 0", fields: [ CronField.Seconds, CronField.Minutes, @@ -220,8 +220,8 @@ const PERIOD_CONFIGS = { }, monthly: { label: CronPeriod.Monthly, - description: 'Run every month', - template: '0 0 0 1 * *', + description: "Run every month", + template: "0 0 0 1 * *", fields: [ CronField.Seconds, CronField.Minutes, @@ -231,8 +231,8 @@ const PERIOD_CONFIGS = { }, yearly: { label: CronPeriod.Yearly, - description: 'Run every year', - template: '0 0 0 1 1 *', + description: "Run every year", + template: "0 0 0 1 1 *", fields: [ CronField.Seconds, CronField.Minutes, @@ -243,8 +243,8 @@ const PERIOD_CONFIGS = { }, custom: { label: CronPeriod.Custom, - description: 'Custom expression', - template: '0 0 * * * *', + description: "Custom expression", + template: "0 0 * * * *", fields: [ CronField.Seconds, CronField.Minutes, @@ -257,8 +257,8 @@ const PERIOD_CONFIGS = { } as const; const CronBuilder: FC = ({ - timezone = 'UTC', - value = '0 0 * * * *', + timezone = "UTC", + value = "0 0 * * * *", onChange, className, disabled = false, @@ -301,7 +301,7 @@ const CronBuilder: FC = ({ }); return matches.map((match) => new Date(match)); } catch (error) { - console.error('Failed to get future matched runs', error); + console.error("Failed to get future matched runs", error); return []; } }, [currentExpression, showPreview, timezone]); @@ -327,7 +327,7 @@ const CronBuilder: FC = ({ const handlePeriodChange = useCallback((period: CronPeriod) => { setActiveTab(period); - if (period !== 'custom') { + if (period !== "custom") { const config = PERIOD_CONFIGS[period]; setCronFields(parseCronExpression(config.template)); } @@ -335,7 +335,7 @@ const CronBuilder: FC = ({ const filteredPresets = useMemo(() => { return presets.filter((preset) => { - if (activeTab === 'custom') { + if (activeTab === "custom") { return true; } return preset.category === activeTab; @@ -343,7 +343,7 @@ const CronBuilder: FC = ({ }, [presets, activeTab]); return ( -
+
handlePeriodChange(v as CronPeriod)} @@ -353,11 +353,11 @@ const CronBuilder: FC = ({ className="grid w-(--all-grids-width) grid-cols-7 whitespace-nowrap lg:w-full" style={ { - '--my-grid-cols': `grid-template-columns: repeat(${displayPeriods.length}, minmax(0, 1fr))`, - '--all-grids-width': + "--my-grid-cols": `grid-template-columns: repeat(${displayPeriods.length}, minmax(0, 1fr))`, + "--all-grids-width": displayPeriods.length > 4 ? `${displayPeriods.length * 25 - 20}%` - : '100%', + : "100%", } as CSSProperties } > @@ -377,10 +377,10 @@ const CronBuilder: FC = ({ - - + + @@ -391,7 +391,7 @@ const CronBuilder: FC = ({ {PERIOD_CONFIGS[period].description} - + = ({ {showPresets && filteredPresets.length > 0 && ( - - + + Quick Presets @@ -412,7 +412,7 @@ const CronBuilder: FC = ({ Common cron expressions for quick setup - +
{filteredPresets.map((preset, index) => (