This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 293328ab96 ISIS-3085: adds logic for TO_LOCAL_TIMEZONE rendering mode
293328ab96 is described below
commit 293328ab96ebd52100e38a2c2f9d2e540e7e3a04
Author: andi-huber <[email protected]>
AuthorDate: Fri Jul 22 11:29:42 2022 +0200
ISIS-3085: adds logic for TO_LOCAL_TIMEZONE rendering mode
---
.../applib/annotation/TimeZoneTranslation.java | 44 +++++++++++++
.../isis/applib/annotation/ValueSemantics.java | 12 ++++
.../valuesemantics/temporal/BadgeRenderer.java | 54 +++++++++++++++
.../temporal/TemporalValueSemanticsProvider.java | 77 ++++++++++++++--------
4 files changed, 159 insertions(+), 28 deletions(-)
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
b/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
new file mode 100644
index 0000000000..5178c39569
--- /dev/null
+++
b/api/applib/src/main/java/org/apache/isis/applib/annotation/TimeZoneTranslation.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.applib.annotation;
+
+/**
+ * Rendering mode for temporals (<i>time instants</i>) with time-zone or
time-offset information.
+ *
+ * @since 2.0 {@index}
+ */
+public enum TimeZoneTranslation {
+
+ UNSPECIFIED,
+
+ /**
+ * Renders temporals(<i>time instants</i>) - that have time-zone or
time-offset information
+ * - transformed to the user's local/current time-zone,
+ * optionally with a tooltip providing information on the originating (non
transformed) <i>time instant</i>.
+ */
+ TO_LOCAL_TIMEZONE,
+
+ /**
+ * Renders temporals (<i>time instants</i>) - that have time-zone or
time-offset information - as is,
+ * optionally with a tooltip providing information on the <i>time
instant</i>
+ * as transformed to the user's local/current time-zone.
+ */
+ NONE;
+
+}
diff --git
a/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
b/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
index 5c956ac555..b99be4e732 100644
---
a/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
+++
b/api/applib/src/main/java/org/apache/isis/applib/annotation/ValueSemantics.java
@@ -129,6 +129,18 @@ public @interface ValueSemantics {
TimePrecision timePrecision()
default TimePrecision.SECOND;
+
+ /**
+ * If associated with a temporal value,
+ * that has time-zone or time-offset information,
+ * the rendering mode, as to whether to transform the rendered value
+ * to the user's local/current time-zone or not.<br>
+ * default = {@link TimeZoneTranslation#TO_LOCAL_TIMEZONE}
+ * @see TimeZoneTranslation
+ */
+ TimeZoneTranslation timeZoneTranslation()
+ default TimeZoneTranslation.TO_LOCAL_TIMEZONE;
+
/**
* eg. @ValueSemantics(dateRenderAdjustDays =
ValueSemantics.AS_DAY_BEFORE)
*/
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
new file mode 100644
index 0000000000..ef662ae5a6
--- /dev/null
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/BadgeRenderer.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.core.metamodel.valuesemantics.temporal;
+
+import java.util.function.Supplier;
+
+/**
+ * Provides html rendering for temporals with time-zone or time-offset
information.
+ *
+ * @since 2.0
+ */
+public interface BadgeRenderer {
+
+ String render(String text, Supplier<String> tooltipProvider);
+
+ // -- FACTORIES
+
+ /**
+ * non-html, text only; ignoring tooltip
+ */
+ public static BadgeRenderer textual() {
+ return (text, tooltipProvider)->text;
+ }
+
+ /**
+ * Depends on presence of <i>Bootstrap</i>.
+ */
+ public static BadgeRenderer bootstrapBadgeWithTooltip() {
+ return (text, tooltipProvider)->String.format("<span "
+ + "class=\"badge bg-secondary\" "
+ + "data-bs-container=\"body\" "
+ + "data-bs-toggle=\"tooltip\" "
+ + "title=\"%s\">"
+ + "%s"
+ + "</span>", tooltipProvider.get(), text);
+ }
+
+}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
index ed426a78e8..a095f66c51 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/temporal/TemporalValueSemanticsProvider.java
@@ -31,7 +31,6 @@ import java.time.temporal.Temporal;
import java.time.temporal.TemporalQuery;
import java.util.Optional;
import java.util.function.BiFunction;
-import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.UnaryOperator;
@@ -40,6 +39,7 @@ import javax.inject.Inject;
import org.springframework.lang.Nullable;
import org.apache.isis.applib.annotation.TimePrecision;
+import org.apache.isis.applib.annotation.TimeZoneTranslation;
import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
import org.apache.isis.applib.util.schema.CommonDtoUtils;
import org.apache.isis.applib.value.semantics.TemporalValueSemantics;
@@ -150,27 +150,14 @@ implements TemporalValueSemantics<T> {
public final String titlePresentation(
final ValueSemanticsProvider.Context context,
final T value) {
- return renderTitle(value, getRenderingFormatter(context, (text,
tooltip)->text));
+ return renderTitle(value, getRenderingFormatter(context,
BadgeRenderer.textual()));
}
@Override
public final String htmlPresentation(
final ValueSemanticsProvider.Context context,
final T value) {
- return renderHtml(value, getRenderingFormatter(context,
this::toBootstrapBadgeWithTooltip));
- }
-
- /**
- * @apiNote Ideally this logic would move to Wicket Viewer, as it depends
on presence of <i>Bootstrap</i>.
- */
- private String toBootstrapBadgeWithTooltip(final String text, final String
tooltip) {
- return String.format("<span "
- + "class=\"badge bg-secondary\" "
- + "data-bs-container=\"body\" "
- + "data-bs-toggle=\"tooltip\" "
- + "title=\"%s\">"
- + "%s"
- + "</span>", tooltip, text);
+ return renderHtml(value, getRenderingFormatter(context,
BadgeRenderer.bootstrapBadgeWithTooltip()));
}
// -- PARSER
@@ -213,7 +200,7 @@ implements TemporalValueSemantics<T> {
*/
protected Function<T, String> getRenderingFormatter(
final ValueSemanticsProvider.Context context,
- final BinaryOperator<String> timeZoneDecorator) {
+ final BadgeRenderer badgeRenderer) {
val dateAndTimeFormatStyle = DateAndTimeFormatStyle.forContext(mmc,
context);
@@ -225,20 +212,54 @@ implements TemporalValueSemantics<T> {
dateAndTimeFormatStyle.getTimeFormatStyle());
final var temporalZoneOnlyRenderingFormat =
getTemporalZoneOnlyRenderingFormat(
- context, temporalCharacteristic, offsetCharacteristic);
+ context, temporalCharacteristic,
offsetCharacteristic).orElse(null);
final var sb = new StringBuffer();
- sb.append(temporalNoZoneRenderingFormat.format(time));
-
- temporalZoneOnlyRenderingFormat
- .ifPresent(zoneOnlyFormat->{
- sb.append(' ').append(timeZoneDecorator.apply(
- zoneOnlyFormat.format(time),
- translate("your local time: ")
- + " "
- +
temporalNoZoneRenderingFormat.format(toLocalTime(context, time))));
- });
+ //FIXME[ISIS-3085] use as provided via ValueSemantics
annotation ...
+ final var timeZoneTranslation =
TimeZoneTranslation.TO_LOCAL_TIMEZONE;
+
+ final var asLocalTime = toLocalTime(context, time);
+
+ switch (timeZoneTranslation) {
+ case TO_LOCAL_TIMEZONE:
+ if(offsetCharacteristic.isLocal()) {
+ // start rendering with the time as is (no offset/zone
info)
+ sb.append(temporalNoZoneRenderingFormat.format(time));
+ } else {
+ // start rendering with the (to-local) translated time
(no offset/zone info)
+
sb.append(temporalNoZoneRenderingFormat.format(asLocalTime));
+
+ // we have offset/zone information, so we append it
(properly formatted) ...
+ sb.append(' ');
+
+ sb.append(badgeRenderer.render(
+ translate("local"),
+ ()->translate("time instant")
+ + ": "
+ +
temporalNoZoneRenderingFormat.format(time)
+ + " "
+ +
temporalZoneOnlyRenderingFormat.format(time)));
+
+ }
+ break;
+ case NONE:
+ default:
+ // start rendering with the time as is (no offset/zone
info)
+ sb.append(temporalNoZoneRenderingFormat.format(time));
+
+ if(!offsetCharacteristic.isLocal()) {
+ // we have offset/zone information, so we append it
(properly formatted) ...
+ sb.append(' ');
+
+ sb.append(badgeRenderer.render(
+ temporalZoneOnlyRenderingFormat.format(time),
+ ()->translate("your local time")
+ + ": "
+ +
temporalNoZoneRenderingFormat.format(asLocalTime)));
+ }
+ break;
+ }
return sb.toString();
};