@aphexcms/cms-core 0.1.16 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +7 -1
- package/dist/api/types.d.ts +2 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cli/generate-types.js +62 -17
- package/dist/cli/index.js +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -1
- package/dist/components/AdminApp.svelte +278 -45
- package/dist/components/AdminApp.svelte.d.ts +2 -0
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentEditor.svelte +60 -13
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/ObjectModal.svelte +15 -4
- package/dist/components/admin/ObjectModal.svelte.d.ts +1 -0
- package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
- package/dist/components/admin/SchemaField.svelte +64 -5
- package/dist/components/admin/SchemaField.svelte.d.ts +1 -0
- package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +402 -111
- package/dist/components/admin/fields/ArrayField.svelte.d.ts +1 -0
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/DateField.svelte +145 -0
- package/dist/components/admin/fields/DateField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/DateField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/DateTimeField.svelte +225 -0
- package/dist/components/admin/fields/DateTimeField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/DateTimeField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ImageField.svelte +221 -110
- package/dist/components/admin/fields/ImageField.svelte.d.ts +2 -0
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +1 -1
- package/dist/components/admin/fields/SlugField.svelte +21 -13
- package/dist/components/admin/fields/SlugField.svelte.d.ts +2 -2
- package/dist/components/admin/fields/SlugField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/StringField.svelte +156 -12
- package/dist/components/admin/fields/StringField.svelte.d.ts +3 -2
- package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/URLField.svelte +41 -0
- package/dist/components/admin/fields/URLField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/URLField.svelte.d.ts.map +1 -0
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +0 -1
- package/dist/db/interfaces/asset.d.ts.map +1 -1
- package/dist/db/interfaces/document.d.ts +0 -2
- package/dist/db/interfaces/document.d.ts.map +1 -1
- package/dist/db/interfaces/index.d.ts +2 -1
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/user.d.ts +2 -0
- package/dist/db/interfaces/user.d.ts.map +1 -1
- package/dist/db/utils/reference-resolver.js +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -0
- package/dist/field-validation/date-utils.d.ts +30 -0
- package/dist/field-validation/date-utils.d.ts.map +1 -0
- package/dist/field-validation/date-utils.js +147 -0
- package/dist/field-validation/rule.d.ts +4 -0
- package/dist/field-validation/rule.d.ts.map +1 -1
- package/dist/field-validation/rule.js +170 -4
- package/dist/field-validation/utils.d.ts +7 -3
- package/dist/field-validation/utils.d.ts.map +1 -1
- package/dist/field-validation/utils.js +130 -38
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +38 -21
- package/dist/lib/field-validation/date-utils.js +147 -0
- package/dist/lib/field-validation/rule.js +170 -4
- package/dist/lib/field-validation/utils.js +130 -38
- package/dist/local-api/collection-api.d.ts +16 -4
- package/dist/local-api/collection-api.d.ts.map +1 -1
- package/dist/local-api/collection-api.js +51 -17
- package/dist/local-api/index.d.ts +1 -1
- package/dist/local-api/index.d.ts.map +1 -1
- package/dist/routes/assets-cdn.d.ts.map +1 -1
- package/dist/routes/assets-cdn.js +14 -7
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +6 -1
- package/dist/routes/documents-by-id.d.ts.map +1 -1
- package/dist/routes/documents-by-id.js +18 -7
- package/dist/routes/documents-publish.js +2 -2
- package/dist/routes/documents-query.d.ts +3 -1
- package/dist/routes/documents-query.d.ts.map +1 -1
- package/dist/routes/documents-query.js +6 -2
- package/dist/routes/documents.d.ts.map +1 -1
- package/dist/routes/documents.js +20 -4
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -0
- package/dist/routes/user-preferences.d.ts +4 -0
- package/dist/routes/user-preferences.d.ts.map +1 -0
- package/dist/routes/user-preferences.js +77 -0
- package/dist/schema-utils/utils.d.ts +4 -0
- package/dist/schema-utils/utils.d.ts.map +1 -1
- package/dist/schema-utils/utils.js +23 -2
- package/dist/schema-utils/validator.d.ts +4 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +120 -0
- package/dist/types/filters.d.ts +13 -0
- package/dist/types/filters.d.ts.map +1 -1
- package/dist/types/organization.d.ts +3 -0
- package/dist/types/organization.d.ts.map +1 -1
- package/dist/types/schemas.d.ts +67 -7
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/default-orderings.d.ts +10 -0
- package/dist/utils/default-orderings.d.ts.map +1 -0
- package/dist/utils/default-orderings.js +63 -0
- package/dist/utils/field-defaults.d.ts +8 -0
- package/dist/utils/field-defaults.d.ts.map +1 -0
- package/dist/utils/field-defaults.js +20 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/initial-value-helpers.d.ts +50 -0
- package/dist/utils/initial-value-helpers.d.ts.map +1 -0
- package/dist/utils/initial-value-helpers.js +70 -0
- package/package.json +6 -4
- package/dist/components/admin/DocumentTypesList.svelte +0 -97
- package/dist/components/admin/DocumentTypesList.svelte.d.ts +0 -14
- package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CalendarIcon from '@lucide/svelte/icons/calendar';
|
|
3
|
+
import { type DateValue, parseDate } from '@internationalized/date';
|
|
4
|
+
import { Input } from '@aphexcms/ui/shadcn/input';
|
|
5
|
+
import { Calendar } from '@aphexcms/ui/shadcn/calendar';
|
|
6
|
+
import * as Popover from '@aphexcms/ui/shadcn/popover';
|
|
7
|
+
import type { DateField } from '../../../types/schemas';
|
|
8
|
+
import dayjs from 'dayjs';
|
|
9
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
10
|
+
|
|
11
|
+
// Enable strict parsing
|
|
12
|
+
dayjs.extend(customParseFormat);
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
field: DateField;
|
|
16
|
+
value: string | null; // Always stored as ISO YYYY-MM-DD
|
|
17
|
+
onUpdate: (value: string | null) => void;
|
|
18
|
+
validationClasses?: string;
|
|
19
|
+
onBlur?: (event: any) => void;
|
|
20
|
+
onFocus?: (event: any) => void;
|
|
21
|
+
readonly?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
field,
|
|
26
|
+
value,
|
|
27
|
+
onUpdate,
|
|
28
|
+
validationClasses,
|
|
29
|
+
onBlur,
|
|
30
|
+
onFocus,
|
|
31
|
+
readonly = false
|
|
32
|
+
}: Props = $props();
|
|
33
|
+
|
|
34
|
+
// Get date format from options or use default
|
|
35
|
+
const dateFormat = $derived(field.options?.dateFormat || 'YYYY-MM-DD');
|
|
36
|
+
|
|
37
|
+
// Track local input value for display
|
|
38
|
+
let inputValue = $state('');
|
|
39
|
+
|
|
40
|
+
// Convert stored ISO value to display format
|
|
41
|
+
// Only update if the formatted value is different to avoid overwriting user input
|
|
42
|
+
$effect(() => {
|
|
43
|
+
if (!value || value === '') {
|
|
44
|
+
if (inputValue !== '') {
|
|
45
|
+
inputValue = '';
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
// Convert ISO (YYYY-MM-DD) to display format
|
|
49
|
+
const date = dayjs(value, 'YYYY-MM-DD', true);
|
|
50
|
+
if (date.isValid()) {
|
|
51
|
+
const formatted = date.format(dateFormat);
|
|
52
|
+
// Only update if different to avoid overwriting user's in-progress typing
|
|
53
|
+
if (inputValue !== formatted) {
|
|
54
|
+
inputValue = formatted;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
// Value is not ISO (might be user's in-progress input or invalid)
|
|
58
|
+
if (inputValue !== value) {
|
|
59
|
+
inputValue = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Convert string value to DateValue for calendar
|
|
66
|
+
const dateValue = $derived.by(() => {
|
|
67
|
+
if (!value || value === '') return undefined;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
// Value is stored as ISO date string (YYYY-MM-DD)
|
|
71
|
+
return parseDate(value);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.error('Failed to parse date:', value, err);
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Handle date selection from calendar
|
|
79
|
+
function handleDateChange(newValue: DateValue | undefined) {
|
|
80
|
+
if (!newValue) {
|
|
81
|
+
onUpdate(null);
|
|
82
|
+
} else {
|
|
83
|
+
// Convert DateValue to ISO string (YYYY-MM-DD) for storage
|
|
84
|
+
const isoString = newValue.toString();
|
|
85
|
+
onUpdate(isoString);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Handle manual input changes
|
|
90
|
+
function handleInputChange(event: Event) {
|
|
91
|
+
const target = event.target as HTMLInputElement;
|
|
92
|
+
const displayValue = target.value;
|
|
93
|
+
inputValue = displayValue;
|
|
94
|
+
|
|
95
|
+
if (displayValue === '') {
|
|
96
|
+
onUpdate(null);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Parse according to the chosen format
|
|
101
|
+
const parsed = dayjs(displayValue, dateFormat, true);
|
|
102
|
+
|
|
103
|
+
if (parsed.isValid()) {
|
|
104
|
+
// Convert to ISO for storage
|
|
105
|
+
const isoString = parsed.format('YYYY-MM-DD');
|
|
106
|
+
onUpdate(isoString);
|
|
107
|
+
} else {
|
|
108
|
+
// Still update with the invalid value so autosave triggers
|
|
109
|
+
// Validation will catch the error
|
|
110
|
+
onUpdate(displayValue);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<div class="space-y-2">
|
|
116
|
+
<div class="flex w-full gap-2">
|
|
117
|
+
<Input
|
|
118
|
+
id={field.name}
|
|
119
|
+
type="text"
|
|
120
|
+
placeholder={dateFormat}
|
|
121
|
+
value={inputValue}
|
|
122
|
+
oninput={handleInputChange}
|
|
123
|
+
onblur={onBlur}
|
|
124
|
+
onfocus={onFocus}
|
|
125
|
+
class="flex-1 {validationClasses}"
|
|
126
|
+
disabled={readonly}
|
|
127
|
+
/>
|
|
128
|
+
<Popover.Root>
|
|
129
|
+
<Popover.Trigger
|
|
130
|
+
class="border-input bg-background ring-offset-background hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring inline-flex h-10 w-10 items-center justify-center whitespace-nowrap rounded-md border text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
|
|
131
|
+
disabled={readonly}
|
|
132
|
+
>
|
|
133
|
+
<CalendarIcon class="h-4 w-4" />
|
|
134
|
+
</Popover.Trigger>
|
|
135
|
+
<Popover.Content class="w-auto p-0">
|
|
136
|
+
<Calendar
|
|
137
|
+
type="single"
|
|
138
|
+
value={dateValue}
|
|
139
|
+
onValueChange={handleDateChange}
|
|
140
|
+
captionLayout="dropdown"
|
|
141
|
+
/>
|
|
142
|
+
</Popover.Content>
|
|
143
|
+
</Popover.Root>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DateField } from '../../../types/schemas.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
field: DateField;
|
|
4
|
+
value: string | null;
|
|
5
|
+
onUpdate: (value: string | null) => void;
|
|
6
|
+
validationClasses?: string;
|
|
7
|
+
onBlur?: (event: any) => void;
|
|
8
|
+
onFocus?: (event: any) => void;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const DateField: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type DateField = ReturnType<typeof DateField>;
|
|
13
|
+
export default DateField;
|
|
14
|
+
//# sourceMappingURL=DateField.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/DateField.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKvD,UAAU,KAAK;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AA0HF,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CalendarIcon from '@lucide/svelte/icons/calendar';
|
|
3
|
+
import { type DateValue, parseDate } from '@internationalized/date';
|
|
4
|
+
import { Input } from '@aphexcms/ui/shadcn/input';
|
|
5
|
+
import { Button } from '@aphexcms/ui/shadcn/button';
|
|
6
|
+
import { Calendar } from '@aphexcms/ui/shadcn/calendar';
|
|
7
|
+
import * as Popover from '@aphexcms/ui/shadcn/popover';
|
|
8
|
+
import type { DateTimeField } from '../../../types/schemas';
|
|
9
|
+
import dayjs from 'dayjs';
|
|
10
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
11
|
+
import utc from 'dayjs/plugin/utc';
|
|
12
|
+
|
|
13
|
+
// Enable strict parsing and UTC
|
|
14
|
+
dayjs.extend(customParseFormat);
|
|
15
|
+
dayjs.extend(utc);
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
field: DateTimeField;
|
|
19
|
+
value: string | null; // Always stored as ISO datetime UTC YYYY-MM-DDTHH:mm:ssZ
|
|
20
|
+
onUpdate: (value: string | null) => void;
|
|
21
|
+
validationClasses?: string;
|
|
22
|
+
onBlur?: (event: any) => void;
|
|
23
|
+
onFocus?: (event: any) => void;
|
|
24
|
+
readonly?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let {
|
|
28
|
+
field,
|
|
29
|
+
value,
|
|
30
|
+
onUpdate,
|
|
31
|
+
validationClasses,
|
|
32
|
+
onBlur,
|
|
33
|
+
onFocus,
|
|
34
|
+
readonly = false
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
// Get date and time formats from options or use defaults
|
|
38
|
+
const dateFormat = $derived(field.options?.dateFormat || 'YYYY-MM-DD');
|
|
39
|
+
const timeFormat = $derived(field.options?.timeFormat || 'HH:mm');
|
|
40
|
+
const displayFormat = $derived(`${dateFormat} ${timeFormat}`);
|
|
41
|
+
|
|
42
|
+
// Track local input value for display
|
|
43
|
+
let inputValue = $state('');
|
|
44
|
+
let timeValue = $state('00:00');
|
|
45
|
+
|
|
46
|
+
// Convert stored ISO value to display format
|
|
47
|
+
// Only update if the formatted value is different to avoid overwriting user input
|
|
48
|
+
$effect(() => {
|
|
49
|
+
if (!value || value === '') {
|
|
50
|
+
if (inputValue !== '') {
|
|
51
|
+
inputValue = '';
|
|
52
|
+
timeValue = '00:00';
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
// Parse the datetime value
|
|
56
|
+
const datetime = dayjs(value);
|
|
57
|
+
if (datetime.isValid()) {
|
|
58
|
+
const formatted = datetime.format(displayFormat);
|
|
59
|
+
const time = datetime.format('HH:mm');
|
|
60
|
+
// Only update if different to avoid overwriting user's in-progress typing
|
|
61
|
+
if (inputValue !== formatted) {
|
|
62
|
+
inputValue = formatted;
|
|
63
|
+
}
|
|
64
|
+
if (timeValue !== time) {
|
|
65
|
+
timeValue = time;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Value is not ISO (might be user's in-progress input or invalid)
|
|
69
|
+
if (inputValue !== value) {
|
|
70
|
+
inputValue = value;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Convert string value to DateValue for calendar
|
|
77
|
+
const dateValue = $derived.by(() => {
|
|
78
|
+
if (!value || value === '') return undefined;
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
// Parse datetime and extract just the date part
|
|
82
|
+
const datetime = dayjs(value);
|
|
83
|
+
if (datetime.isValid()) {
|
|
84
|
+
return parseDate(datetime.format('YYYY-MM-DD'));
|
|
85
|
+
}
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.error('Failed to parse datetime:', value, err);
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Handle date selection from calendar
|
|
93
|
+
function handleDateChange(newValue: DateValue | undefined) {
|
|
94
|
+
if (!newValue) {
|
|
95
|
+
onUpdate(null);
|
|
96
|
+
} else {
|
|
97
|
+
// Combine selected date with current time and convert to UTC
|
|
98
|
+
const dateStr = newValue.toString(); // YYYY-MM-DD
|
|
99
|
+
const localDatetime = dayjs(`${dateStr} ${timeValue}`, 'YYYY-MM-DD HH:mm');
|
|
100
|
+
const utcDatetime = localDatetime.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
101
|
+
onUpdate(utcDatetime);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Handle manual input changes
|
|
106
|
+
function handleInputChange(event: Event) {
|
|
107
|
+
const target = event.target as HTMLInputElement;
|
|
108
|
+
const displayValue = target.value;
|
|
109
|
+
inputValue = displayValue;
|
|
110
|
+
|
|
111
|
+
if (displayValue === '') {
|
|
112
|
+
onUpdate(null);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Parse according to the chosen format (date + time)
|
|
117
|
+
const parsed = dayjs(displayValue, displayFormat, true);
|
|
118
|
+
|
|
119
|
+
if (parsed.isValid()) {
|
|
120
|
+
// Convert to ISO datetime UTC
|
|
121
|
+
const utcDatetime = parsed.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
122
|
+
onUpdate(utcDatetime);
|
|
123
|
+
// Update time value for picker
|
|
124
|
+
timeValue = parsed.format('HH:mm');
|
|
125
|
+
} else {
|
|
126
|
+
// Still update with the invalid value so autosave triggers
|
|
127
|
+
// Validation will catch the error
|
|
128
|
+
onUpdate(displayValue);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Handle time input changes
|
|
133
|
+
function handleTimeChange(event: Event) {
|
|
134
|
+
const target = event.target as HTMLInputElement;
|
|
135
|
+
const newTime = target.value; // HH:mm format
|
|
136
|
+
timeValue = newTime;
|
|
137
|
+
|
|
138
|
+
// If we have a date, update the datetime
|
|
139
|
+
if (value && value !== '') {
|
|
140
|
+
const datetime = dayjs(value);
|
|
141
|
+
if (datetime.isValid()) {
|
|
142
|
+
// Get the local date and combine with new time, then convert to UTC
|
|
143
|
+
const dateStr = datetime.format('YYYY-MM-DD');
|
|
144
|
+
const localDatetime = dayjs(`${dateStr} ${newTime}`, 'YYYY-MM-DD HH:mm');
|
|
145
|
+
const utcDatetime = localDatetime.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
146
|
+
onUpdate(utcDatetime);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Set to current time
|
|
152
|
+
function setToCurrentTime() {
|
|
153
|
+
const now = dayjs();
|
|
154
|
+
timeValue = now.format('HH:mm');
|
|
155
|
+
|
|
156
|
+
// If we have a date, update the datetime
|
|
157
|
+
if (value && value !== '') {
|
|
158
|
+
const datetime = dayjs(value);
|
|
159
|
+
if (datetime.isValid()) {
|
|
160
|
+
// Get the local date and combine with current time, then convert to UTC
|
|
161
|
+
const dateStr = datetime.format('YYYY-MM-DD');
|
|
162
|
+
const localDatetime = dayjs(`${dateStr} ${timeValue}`, 'YYYY-MM-DD HH:mm');
|
|
163
|
+
const utcDatetime = localDatetime.utc().format('YYYY-MM-DDTHH:mm:ss[Z]');
|
|
164
|
+
onUpdate(utcDatetime);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
</script>
|
|
169
|
+
|
|
170
|
+
<div class="space-y-2">
|
|
171
|
+
<div class="flex w-full gap-2">
|
|
172
|
+
<Input
|
|
173
|
+
id={field.name}
|
|
174
|
+
type="text"
|
|
175
|
+
placeholder={displayFormat}
|
|
176
|
+
value={inputValue}
|
|
177
|
+
oninput={handleInputChange}
|
|
178
|
+
onblur={onBlur}
|
|
179
|
+
onfocus={onFocus}
|
|
180
|
+
class="flex-1 {validationClasses}"
|
|
181
|
+
disabled={readonly}
|
|
182
|
+
/>
|
|
183
|
+
<Popover.Root>
|
|
184
|
+
<Popover.Trigger
|
|
185
|
+
class="border-input bg-background ring-offset-background hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring inline-flex h-10 w-10 items-center justify-center whitespace-nowrap rounded-md border text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
|
|
186
|
+
disabled={readonly}
|
|
187
|
+
>
|
|
188
|
+
<CalendarIcon class="h-4 w-4" />
|
|
189
|
+
</Popover.Trigger>
|
|
190
|
+
<Popover.Content class="w-auto p-0">
|
|
191
|
+
<Calendar
|
|
192
|
+
type="single"
|
|
193
|
+
value={dateValue}
|
|
194
|
+
onValueChange={handleDateChange}
|
|
195
|
+
captionLayout="dropdown"
|
|
196
|
+
/>
|
|
197
|
+
|
|
198
|
+
<!-- Time Picker Section -->
|
|
199
|
+
<div class="border-border border-t">
|
|
200
|
+
<div class="flex items-center gap-2 p-3">
|
|
201
|
+
<div class="flex-1">
|
|
202
|
+
<Input
|
|
203
|
+
type="time"
|
|
204
|
+
value={timeValue}
|
|
205
|
+
oninput={handleTimeChange}
|
|
206
|
+
aria-label="Select time"
|
|
207
|
+
disabled={readonly}
|
|
208
|
+
class="w-full"
|
|
209
|
+
/>
|
|
210
|
+
</div>
|
|
211
|
+
<Button
|
|
212
|
+
variant="outline"
|
|
213
|
+
size="sm"
|
|
214
|
+
onclick={setToCurrentTime}
|
|
215
|
+
disabled={readonly}
|
|
216
|
+
type="button"
|
|
217
|
+
>
|
|
218
|
+
Set to now
|
|
219
|
+
</Button>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</Popover.Content>
|
|
223
|
+
</Popover.Root>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DateTimeField } from '../../../types/schemas.js';
|
|
2
|
+
interface Props {
|
|
3
|
+
field: DateTimeField;
|
|
4
|
+
value: string | null;
|
|
5
|
+
onUpdate: (value: string | null) => void;
|
|
6
|
+
validationClasses?: string;
|
|
7
|
+
onBlur?: (event: any) => void;
|
|
8
|
+
onFocus?: (event: any) => void;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const DateTimeField: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type DateTimeField = ReturnType<typeof DateTimeField>;
|
|
13
|
+
export default DateTimeField;
|
|
14
|
+
//# sourceMappingURL=DateTimeField.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateTimeField.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/admin/fields/DateTimeField.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAM3D,UAAU,KAAK;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AA6LF,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|