diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java
new file mode 100644
index 00000000..e20bdafc
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/queues/GetQueueSize.java
@@ -0,0 +1,84 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2023. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.actions.queues;
+
+
+import java.util.List;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.sqs.AmazonSQS;
+import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
+import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.logging.QLogger;
+import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.queues.SQSQueueProviderMetaData;
+import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class GetQueueSize
+{
+ private static final QLogger LOG = QLogger.getLogger(GetQueueSize.class);
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public Integer getQueueSize(QQueueProviderMetaData queueProviderMetaData, QQueueMetaData queueMetaData) throws QException
+ {
+ try
+ {
+ //////////////////////////////////////////////////////////////////
+ // todo - handle other queue provider types, somewhere, somehow //
+ //////////////////////////////////////////////////////////////////
+ SQSQueueProviderMetaData queueProvider = (SQSQueueProviderMetaData) queueProviderMetaData;
+
+ BasicAWSCredentials credentials = new BasicAWSCredentials(queueProvider.getAccessKey(), queueProvider.getSecretKey());
+ final AmazonSQS sqs = AmazonSQSClientBuilder.standard()
+ .withRegion(queueProvider.getRegion())
+ .withCredentials(new AWSStaticCredentialsProvider(credentials))
+ .build();
+
+ String queueUrl = queueProvider.getBaseURL();
+ if(!queueUrl.endsWith("/"))
+ {
+ queueUrl += "/";
+ }
+ queueUrl += queueMetaData.getQueueName();
+
+ GetQueueAttributesResult queueAttributes = sqs.getQueueAttributes(queueUrl, List.of("ApproximateNumberOfMessages"));
+ String approximateNumberOfMessages = queueAttributes.getAttributes().get("ApproximateNumberOfMessages");
+ return (Integer.parseInt(approximateNumberOfMessages));
+ }
+ catch(Exception e)
+ {
+ LOG.warn("Error getting queue size", e, logPair("queueName", queueMetaData == null ? "null" : queueMetaData.getName()));
+ throw (new QException("Error getting queue size", e));
+ }
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java
index f3ab6ab2..f6b065fc 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/AbstractWidgetValueSource.java
@@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode;
+import java.io.Serializable;
import java.util.Map;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
@@ -35,6 +36,8 @@ public abstract class AbstractWidgetValueSource
protected String name;
protected String type;
+ protected Map inputValues;
+
/*******************************************************************************
@@ -116,4 +119,35 @@ public abstract class AbstractWidgetValueSource
////////////////////////
}
+
+
+ /*******************************************************************************
+ ** Getter for inputValues
+ *******************************************************************************/
+ public Map getInputValues()
+ {
+ return (this.inputValues);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for inputValues
+ *******************************************************************************/
+ public void setInputValues(Map inputValues)
+ {
+ this.inputValues = inputValues;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for inputValues
+ *******************************************************************************/
+ public AbstractWidgetValueSource withInputValues(Map inputValues)
+ {
+ this.inputValues = inputValues;
+ return (this);
+ }
+
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java
new file mode 100644
index 00000000..3e354936
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/QueueSizeWidgetValue.java
@@ -0,0 +1,100 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2023. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode;
+
+
+import java.util.Map;
+import com.kingsrook.qqq.backend.core.actions.queues.GetQueueSize;
+import com.kingsrook.qqq.backend.core.context.QContext;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.logging.QLogger;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
+import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaData;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class QueueSizeWidgetValue extends AbstractWidgetValueSource
+{
+ private static final QLogger LOG = QLogger.getLogger(QueueSizeWidgetValue.class);
+
+ private String queueName;
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public Object evaluate(Map context, RenderWidgetInput input) throws QException
+ {
+ QQueueMetaData queue = QContext.getQInstance().getQueue(queueName);
+ QQueueProviderMetaData queueProvider = QContext.getQInstance().getQueueProvider(queue.getProviderName());
+ return (new GetQueueSize().getQueueSize(queueProvider, queue));
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public QueueSizeWidgetValue withName(String name)
+ {
+ setName(name);
+ return (this);
+ }
+
+
+
+ /*******************************************************************************
+ ** Getter for queueName
+ *******************************************************************************/
+ public String getQueueName()
+ {
+ return (this.queueName);
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for queueName
+ *******************************************************************************/
+ public void setQueueName(String queueName)
+ {
+ this.queueName = queueName;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for queueName
+ *******************************************************************************/
+ public QueueSizeWidgetValue withQueueName(String queueName)
+ {
+ this.queueName = queueName;
+ return (this);
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java
new file mode 100644
index 00000000..384dd684
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/dashboard/nocode/WidgetAdHocValue.java
@@ -0,0 +1,125 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2023. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.backend.core.model.metadata.dashboard.nocode;
+
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Function;
+import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput;
+import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class WidgetAdHocValue extends AbstractWidgetValueSource
+{
+ private QCodeReference codeReference;
+
+
+
+ /*******************************************************************************
+ ** Constructor
+ **
+ *******************************************************************************/
+ public WidgetAdHocValue()
+ {
+ setType(getClass().getSimpleName());
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public Object evaluate(Map context, RenderWidgetInput input) throws QException
+ {
+ if(inputValues != null)
+ {
+ context.putAll(inputValues);
+ }
+
+ Function