From 81f9f4e49a52de592550b8bd7a98b90c4c1f1e27 Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Wed, 8 Feb 2023 22:46:49 -0600 Subject: [PATCH] SPRINT-20: updated getTablePath to no longer require input param, added some permission checks to widget links, added utils to get zoned starts of day, year, month --- .../dashboard/AbstractHTMLWidgetRenderer.java | 122 +++++++++++++++--- .../widgets/ChildRecordListRenderer.java | 2 +- .../model/dashboard/widgets/QWidgetData.java | 36 +++++- .../dashboard/widgets/StatisticsData.java | 9 ++ .../model/dashboard/widgets/TableData.java | 9 ++ .../model/dashboard/widgets/WidgetType.java | 1 - .../core/model/metadata/QInstance.java | 2 +- .../qqq/backend/core/utils/ValueUtils.java | 77 +++++++++++ 8 files changed, 238 insertions(+), 20 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java index c5854dc6..35786724 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java @@ -26,6 +26,7 @@ import java.io.Serializable; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -119,7 +120,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String linkTableBulkLoad(RenderWidgetInput input, String tableName) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); return (tablePath + "/" + tableName + ".bulkInsert"); } @@ -128,8 +129,14 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer /******************************************************************************* ** *******************************************************************************/ - public static String linkTableBulkLoadChildren(String tableName) throws QException + public static String linkTableBulkLoadChildren(RenderWidgetInput input, String tableName) throws QException { + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (null); + } + return ("#/launchProcess=" + tableName + ".bulkInsert"); } @@ -140,7 +147,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String linkTableCreate(RenderWidgetInput input, String tableName) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); return (tablePath + "/create"); } @@ -151,18 +158,71 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String linkTableCreateWithDefaultValues(RenderWidgetInput input, String tableName, Map defaultValues) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); return (tablePath + "/create?defaultValues=" + URLEncoder.encode(JsonUtils.toJson(defaultValues), Charset.defaultCharset())); } + /******************************************************************************* + ** + *******************************************************************************/ + public static String getCountLink(RenderWidgetInput input, String tableName, QQueryFilter filter, int count) throws QException + { + String totalString = QValueFormatter.formatValue(DisplayFormat.COMMAS, count); + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null || filter == null) + { + return (totalString); + } + return ("" + totalString + ""); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static void addTableFilterToListIfPermissed(RenderWidgetInput input, String tableName, List urls, QQueryFilter filter) throws QException + { + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return; + } + + urls.add(tablePath + "?filter=" + JsonUtils.toJson(filter)); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static String linkTableFilterUnencoded(RenderWidgetInput input, String tableName, QQueryFilter filter) throws QException + { + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (null); + } + + return (tablePath + "?filter=" + JsonUtils.toJson(filter)); + } + + + /******************************************************************************* ** *******************************************************************************/ public static String linkTableFilter(RenderWidgetInput input, String tableName, QQueryFilter filter) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (null); + } + return (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset())); } @@ -173,8 +233,15 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String aHrefTableFilterNoOfRecords(RenderWidgetInput input, String tableName, QQueryFilter filter, Integer noOfRecords, String singularLabel, String pluralLabel) throws QException { + String displayText = QValueFormatter.formatValue(DisplayFormat.COMMAS, noOfRecords) + " " + StringUtils.plural(noOfRecords, singularLabel, pluralLabel); + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (displayText); + } + String href = linkTableFilter(input, tableName, filter); - return ("" + QValueFormatter.formatValue(DisplayFormat.COMMAS, noOfRecords) + " " + StringUtils.plural(noOfRecords, singularLabel, pluralLabel) + ""); + return ("" + displayText + ""); } @@ -184,6 +251,12 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String aHrefViewRecord(RenderWidgetInput input, String tableName, Serializable id, String linkText) throws QException { + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (linkText); + } + return ("" + linkText + ""); } @@ -194,7 +267,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String linkRecordEdit(AbstractActionInput input, String tableName, Serializable recordId) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); return (tablePath + "/" + recordId + "/edit"); } @@ -205,7 +278,12 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer *******************************************************************************/ public static String linkRecordView(AbstractActionInput input, String tableName, Serializable recordId) throws QException { - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); + if(tablePath == null) + { + return (null); + } + return (tablePath + "/" + recordId); } @@ -218,7 +296,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer { QProcessMetaData process = input.getInstance().getProcess(processName); String tableName = process.getTableName(); - String tablePath = input.getInstance().getTablePath(input, tableName); + String tablePath = input.getInstance().getTablePath(tableName); return (tablePath + "/" + recordId + "/" + processName); } @@ -227,9 +305,9 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer /******************************************************************************* ** *******************************************************************************/ - public static String linkTableCreateChild(String childTableName, Map defaultValues) + public static String linkTableCreateChild(RenderWidgetInput input, String childTableName, Map defaultValues) throws QException { - return (linkTableCreateChild(childTableName, defaultValues, defaultValues.keySet())); + return (linkTableCreateChild(input, childTableName, defaultValues, defaultValues.keySet())); } @@ -237,9 +315,9 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer /******************************************************************************* ** *******************************************************************************/ - public static String aHrefTableCreateChild(String childTableName, Map defaultValues) + public static String aHrefTableCreateChild(RenderWidgetInput input, String childTableName, Map defaultValues) throws QException { - return (aHrefTableCreateChild(childTableName, defaultValues, defaultValues.keySet())); + return (aHrefTableCreateChild(input, childTableName, defaultValues, defaultValues.keySet())); } @@ -247,8 +325,14 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer /******************************************************************************* ** *******************************************************************************/ - public static String linkTableCreateChild(String childTableName, Map defaultValues, Set disabledFields) + public static String linkTableCreateChild(RenderWidgetInput input, String childTableName, Map defaultValues, Set disabledFields) throws QException { + String tablePath = input.getInstance().getTablePath(childTableName); + if(tablePath == null) + { + return (null); + } + Map disabledFieldsMap = disabledFields.stream().collect(Collectors.toMap(k -> k, k -> 1)); return ("#/createChild=" + childTableName @@ -261,9 +345,15 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer /******************************************************************************* ** *******************************************************************************/ - public static String aHrefTableCreateChild(String childTableName, Map defaultValues, Set disabledFields) + public static String aHrefTableCreateChild(RenderWidgetInput input, String childTableName, Map defaultValues, Set disabledFields) throws QException { - return ("Create new"); + String tablePath = input.getInstance().getTablePath(childTableName); + if(tablePath == null) + { + return (null); + } + + return ("Create new"); } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ChildRecordListRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ChildRecordListRenderer.java index ce9f1e4a..6f5f5b5e 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ChildRecordListRenderer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ChildRecordListRenderer.java @@ -185,7 +185,7 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer QueryOutput queryOutput = new QueryAction().execute(queryInput); QTableMetaData table = input.getInstance().getTable(join.getRightTable()); - String tablePath = input.getInstance().getTablePath(input, table.getName()); + String tablePath = input.getInstance().getTablePath(table.getName()); String viewAllLink = tablePath == null ? null : (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset())); ChildRecordListData widgetData = new ChildRecordListData(widgetLabel, queryOutput, table, tablePath, viewAllLink); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/QWidgetData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/QWidgetData.java index cccd3242..99ceb4ff 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/QWidgetData.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/QWidgetData.java @@ -32,10 +32,10 @@ import java.util.Map; *******************************************************************************/ public abstract class QWidgetData { - private String label; private List dropdownNameList; private List dropdownLabelList; + private Boolean hasPermission; ///////////////////////////////////////////////////////////////////////////////////////// // this is a list of lists, the outer list corresponds to each dropdown (parallel list // @@ -222,4 +222,38 @@ public abstract class QWidgetData return (this); } + + + /******************************************************************************* + ** Getter for hasPermission + ** + *******************************************************************************/ + public Boolean getHasPermission() + { + return hasPermission; + } + + + + /******************************************************************************* + ** Setter for hasPermission + ** + *******************************************************************************/ + public void setHasPermission(Boolean hasPermission) + { + this.hasPermission = hasPermission; + } + + + + /******************************************************************************* + ** Fluent setter for hasPermission + ** + *******************************************************************************/ + public QWidgetData withHasPermission(Boolean hasPermission) + { + this.hasPermission = hasPermission; + return (this); + } + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/StatisticsData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/StatisticsData.java index cec10f9a..13a47931 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/StatisticsData.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/StatisticsData.java @@ -38,6 +38,15 @@ public class StatisticsData extends QWidgetData + /******************************************************************************* + ** + *******************************************************************************/ + public StatisticsData() + { + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/TableData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/TableData.java index 1cd3f334..b9674c74 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/TableData.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/TableData.java @@ -41,6 +41,15 @@ public class TableData extends QWidgetData + /******************************************************************************* + ** + *******************************************************************************/ + public TableData() + { + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java index f2f39d21..76b8f918 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/WidgetType.java @@ -44,7 +44,6 @@ public enum WidgetType PROCESS("process"), QUICK_SIGHT_CHART("quickSightChart"), STATISTICS("statistics"), - SIMPLE_STATISTICS("simpleStatistics"), STACKED_BAR_CHART("stackedBarChart"), STEPPER("stepper"), TABLE("table"), diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java index fdf2aeb8..10ae4c5e 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/QInstance.java @@ -188,7 +188,7 @@ public class QInstance /******************************************************************************* ** Get the full path to a table *******************************************************************************/ - public String getTablePath(AbstractActionInput actionInput, String tableName) throws QException + public String getTablePath(String tableName) throws QException { if(!memoizedTablePaths.containsKey(tableName)) { diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java index 3fa4d1f1..ef670d59 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/ValueUtils.java @@ -34,6 +34,8 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.util.Calendar; import java.util.List; import java.util.TimeZone; @@ -50,6 +52,8 @@ public class ValueUtils private static final DateTimeFormatter dateTimeFormatter_MdyyyyWithSlashes = DateTimeFormatter.ofPattern("M/d/yyyy"); private static final DateTimeFormatter dateTimeFormatter_yyyyMMdd = DateTimeFormatter.ofPattern("yyyyMMdd"); + public static final String COMPANY_TIMEZONE_ID = "America/New_York"; + /******************************************************************************* @@ -653,4 +657,77 @@ public class ValueUtils case BLOB -> getValueAsByteArray(value); }; } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static Instant getStartOfTodayInZoneId(String zoneId) + { + /////////////////////////// + // get the instant 'now' // + /////////////////////////// + ZoneId zone = ZoneId.of(zoneId); + Instant computerTime = Instant.now(); + + ////////////////////////////////////////////////////////////////////////////// + // get date time for now in given zone, truncate it and add offset from utc // + ////////////////////////////////////////////////////////////////////////////// + LocalDateTime givenZonesNow = LocalDateTime.ofInstant(Instant.now(), zone); + LocalDateTime startOfDay = givenZonesNow.truncatedTo(ChronoUnit.DAYS); + return (startOfDay.toInstant(zone.getRules().getOffset(computerTime))); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static Instant getStartOfMonthInZoneId(String zoneId) + { + /////////////////////////// + // get the instant 'now' // + /////////////////////////// + ZoneId zone = ZoneId.of(zoneId); + Instant computerTime = Instant.now(); + + ////////////////////////////////////////////////////////////////////////////// + // get date time for now in given zone, truncate it and add offset from utc // + ////////////////////////////////////////////////////////////////////////////// + LocalDateTime givenZonesNow = LocalDateTime.ofInstant(Instant.now(), zone); + LocalDateTime startOfMonth = givenZonesNow + .withDayOfMonth(1) + .with(ChronoField.HOUR_OF_DAY, 0) + .with(ChronoField.MINUTE_OF_DAY, 0) + .with(ChronoField.SECOND_OF_DAY, 0) + .with(ChronoField.NANO_OF_DAY, 0); + return (startOfMonth.toInstant(zone.getRules().getOffset(computerTime))); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static Instant getStartOfYearInZoneId(String zoneId) + { + /////////////////////////// + // get the instant 'now' // + /////////////////////////// + ZoneId zone = ZoneId.of(zoneId); + Instant computerTime = Instant.now(); + + ////////////////////////////////////////////////////////////////////////////// + // get date time for now in given zone, truncate it and add offset from utc // + ////////////////////////////////////////////////////////////////////////////// + LocalDateTime givenZonesNow = LocalDateTime.ofInstant(Instant.now(), zone); + LocalDateTime startOfMonth = givenZonesNow + .withDayOfYear(1) + .with(ChronoField.HOUR_OF_DAY, 0) + .with(ChronoField.MINUTE_OF_DAY, 0) + .with(ChronoField.SECOND_OF_DAY, 0) + .with(ChronoField.NANO_OF_DAY, 0); + return (startOfMonth.toInstant(zone.getRules().getOffset(computerTime))); + } }