diff --git a/core/pom.xml b/core/pom.xml
index 139bffc8..98d832f8 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -248,6 +248,12 @@ DynamicImport-Package: *
com.fasterxml.jackson.core
provided
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ 2.17.2
+ provided
+
com.day.cq
cq-replication
diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentType.java b/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentType.java
index eeb3badf..c160d469 100644
--- a/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentType.java
+++ b/core/src/main/java/com/vml/es/aem/acm/core/code/ArgumentType.java
@@ -2,6 +2,7 @@
public enum ArgumentType {
BOOL,
+ DATETIME,
INTEGER,
DECIMAL,
STRING,
diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java
index f2d23b20..32564dd5 100644
--- a/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java
+++ b/core/src/main/java/com/vml/es/aem/acm/core/code/Arguments.java
@@ -86,6 +86,16 @@ public void bool(String name, Closure options) {
add(argument);
}
+ public void dateTime(String name) {
+ dateTime(name, null);
+ }
+
+ public void dateTime(String name, Closure options) {
+ DateTimeArgument argument = new DateTimeArgument(name);
+ GroovyUtils.with(argument, options);
+ add(argument);
+ }
+
public void string(String name) {
string(name, null);
}
diff --git a/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java b/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java
new file mode 100644
index 00000000..8f497575
--- /dev/null
+++ b/core/src/main/java/com/vml/es/aem/acm/core/code/arg/DateTimeArgument.java
@@ -0,0 +1,81 @@
+package com.vml.es.aem.acm.core.code.arg;
+
+import com.vml.es.aem.acm.core.code.Argument;
+import com.vml.es.aem.acm.core.code.ArgumentType;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+
+public class DateTimeArgument extends Argument {
+ private DateTimeArgument.Variant variant = DateTimeArgument.Variant.DATETIME;
+
+ private LocalDateTime min;
+
+ private LocalDateTime max;
+
+ public DateTimeArgument(String name) {
+ super(name, ArgumentType.DATETIME);
+ }
+
+ public LocalDateTime getMin() {
+ return min;
+ }
+
+ public void setMin(LocalDateTime min) {
+ this.min = min;
+ }
+
+ public void setMin(LocalDate min) {
+ this.min = min.atStartOfDay();
+ }
+
+ public LocalDateTime getMax() {
+ return max;
+ }
+
+ public void setMax(LocalDateTime max) {
+ this.max = max;
+ }
+
+ public void setMax(LocalDate max) {
+ this.max = max.atStartOfDay();
+ }
+
+ public DateTimeArgument.Variant getVariant() {
+ return variant;
+ }
+
+ public void setVariant(String variant) {
+ this.variant = DateTimeArgument.Variant.of(variant);
+ }
+
+ public void setVariant(DateTimeArgument.Variant render) {
+ this.variant = render;
+ }
+
+ // Cast LocalDate to LocalDateTime in case of DATE variant
+ public void setValue(LocalDate value) {
+ setValue(value.atStartOfDay());
+ }
+
+ public void date() {
+ this.variant = DateTimeArgument.Variant.DATE;
+ }
+
+ public void dateTime() {
+ this.variant = DateTimeArgument.Variant.DATETIME;
+ }
+
+ public enum Variant {
+ DATE,
+ DATETIME;
+
+ public static DateTimeArgument.Variant of(String name) {
+ return Arrays.stream(DateTimeArgument.Variant.values())
+ .filter(r -> r.name().equalsIgnoreCase(name))
+ .findFirst()
+ .orElseThrow(() -> new IllegalArgumentException(
+ String.format("Datetime variant '%s' is not supported!", name)));
+ }
+ }
+}
diff --git a/core/src/main/java/com/vml/es/aem/acm/core/util/JsonUtils.java b/core/src/main/java/com/vml/es/aem/acm/core/util/JsonUtils.java
index 37d6d133..0160f209 100644
--- a/core/src/main/java/com/vml/es/aem/acm/core/util/JsonUtils.java
+++ b/core/src/main/java/com/vml/es/aem/acm/core/util/JsonUtils.java
@@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -17,7 +18,8 @@ public final class JsonUtils {
public static final ObjectMapper MAPPER = new ObjectMapper()
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
- .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+ .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
+ .registerModule(new JavaTimeModule());
public static final ObjectWriter COMPACT_WRITER = MAPPER.writer();
diff --git a/pom.xml b/pom.xml
index 97bfa5ff..a8b67ae1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -233,6 +233,7 @@ Bundle-Category: acm
Bundle-DocURL:
-plugin org.apache.sling.caconfig.bndplugin.ConfigurationClassScannerPlugin
-plugin org.apache.sling.bnd.models.ModelsScannerPlugin
+Private-Package: com.fasterxml.jackson.datatype.jsr310
]]>
@@ -254,6 +255,11 @@ Bundle-DocURL:
scriptingbundle-maven-plugin
0.5.0
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ 2.17.2
+
diff --git a/ui.frontend/src/components/CodeArgumentInput.module.css b/ui.frontend/src/components/CodeArgumentInput.module.css
index 15dfe7e1..4e1556a1 100644
--- a/ui.frontend/src/components/CodeArgumentInput.module.css
+++ b/ui.frontend/src/components/CodeArgumentInput.module.css
@@ -1,9 +1,9 @@
/*Custom error state since react spectrum doesn't provide one for switch and checkbox component*/
.error {
- color: var(--spectrum-red-900);
- font-size: var(--spectrum-global-dimension-font-size-75);
- line-height: var(--spectrum-global-font-line-height-small);
- letter-spacing: var(--spectrum-global-font-letter-spacing-none);
- margin-inline-end: var(--spectrum-global-dimension-size-100);
- font-family: var(--spectrum-global-font-family-base), sans-serif;
-}
\ No newline at end of file
+ color: var(--spectrum-red-900);
+ font-size: var(--spectrum-global-dimension-font-size-75);
+ line-height: var(--spectrum-global-font-line-height-small);
+ letter-spacing: var(--spectrum-global-font-letter-spacing-none);
+ margin-inline-end: var(--spectrum-global-dimension-size-100);
+ font-family: var(--spectrum-global-font-family-base), sans-serif;
+}
diff --git a/ui.frontend/src/components/CodeArgumentInput.tsx b/ui.frontend/src/components/CodeArgumentInput.tsx
index 226d8a4f..7324f858 100644
--- a/ui.frontend/src/components/CodeArgumentInput.tsx
+++ b/ui.frontend/src/components/CodeArgumentInput.tsx
@@ -1,12 +1,13 @@
-import { Checkbox, CheckboxGroup, Flex, Item, ListView, NumberField, Picker, Radio, RadioGroup, Switch, TextArea, TextField, View } from '@adobe/react-spectrum';
+import { Checkbox, CheckboxGroup, DatePicker, Flex, Item, ListView, NumberField, Picker, Radio, RadioGroup, Switch, TextArea, TextField, View } from '@adobe/react-spectrum';
import { Editor } from '@monaco-editor/react';
import { Field } from '@react-spectrum/label';
import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import useFormCrossFieldValidation from '../hooks/form.ts';
-import { Argument, ArgumentValue, isBoolArgument, isMultiSelectArgument, isNumberArgument, isSelectArgument, isStringArgument, isTextArgument } from '../utils/api.types.ts';
+import { Argument, ArgumentValue, isBoolArgument, isDateTimeArgument, isMultiSelectArgument, isNumberArgument, isSelectArgument, isStringArgument, isTextArgument } from '../utils/api.types.ts';
+import { Dates } from '../utils/dates.ts';
import { Strings } from '../utils/strings.ts';
-import styles from "./CodeArgumentInput.module.css"
+import styles from './CodeArgumentInput.module.css';
interface CodeArgumentInputProps {
arg: Argument;
@@ -63,6 +64,31 @@ const CodeArgumentInput: React.FC = ({ arg }) => {
)}
/>
);
+ } else if (isDateTimeArgument(arg)) {
+ return (
+ (
+
+ field.onChange(dateValue?.toString())}
+ granularity={arg.variant === 'DATETIME' ? 'second' : 'day'}
+ label={argLabel(arg)}
+ errorMessage={fieldState.error ? fieldState.error.message : undefined}
+ validationState={fieldState.error ? 'invalid' : 'valid'}
+ aria-label={`Argument '${arg.name}'`}
+ width="100%"
+ />
+
+ )}
+ />
+ );
} else if (isStringArgument(arg)) {
return (
;
@@ -43,6 +43,12 @@ export type BoolArgument = Argument & {
display: 'SWITCHER' | 'CHECKBOX';
};
+export type DateTimeArgument = Argument & {
+ variant: 'DATE' | 'DATETIME';
+ min: string;
+ max: string;
+};
+
export type TextArgument = Argument & {
language?: string;
};
@@ -70,6 +76,10 @@ export function isBoolArgument(arg: Argument): arg is BoolArgumen
return arg.type === 'BOOL';
}
+export function isDateTimeArgument(arg: Argument): arg is DateTimeArgument {
+ return arg.type === 'DATETIME';
+}
+
export function isTextArgument(arg: Argument): arg is TextArgument {
return arg.type === 'TEXT';
}