From 020aa9adddf6a310ee54a65e9248272ec12b72d4 Mon Sep 17 00:00:00 2001 From: Eric P Green Date: Thu, 29 Feb 2024 14:08:52 -0800 Subject: [PATCH 1/4] Handle incomplete criteria --- .../src/features/alerts/PreviewEmpty.svelte | 16 ++++ .../AlertDialogCriteriaTab.svelte | 4 +- .../alerts/criteria-tab/AlertPreview.svelte | 55 ++++++++++++ .../alerts/data-tab/AlertDialogDataTab.svelte | 6 +- .../DataPreview.svelte} | 23 ++--- .../dashboards/stores/filter-utils.spec.ts | 85 +++++++++++++++++++ .../dashboards/stores/filter-utils.ts | 47 +++++++++- 7 files changed, 215 insertions(+), 21 deletions(-) create mode 100644 web-common/src/features/alerts/PreviewEmpty.svelte create mode 100644 web-common/src/features/alerts/criteria-tab/AlertPreview.svelte rename web-common/src/features/alerts/{AlertDataPreview.svelte => data-tab/DataPreview.svelte} (62%) create mode 100644 web-common/src/features/dashboards/stores/filter-utils.spec.ts diff --git a/web-common/src/features/alerts/PreviewEmpty.svelte b/web-common/src/features/alerts/PreviewEmpty.svelte new file mode 100644 index 00000000000..1f69e656f72 --- /dev/null +++ b/web-common/src/features/alerts/PreviewEmpty.svelte @@ -0,0 +1,16 @@ + + +
+ +
+
{topLine}
+
+ {bottomLine} +
+
+
diff --git a/web-common/src/features/alerts/criteria-tab/AlertDialogCriteriaTab.svelte b/web-common/src/features/alerts/criteria-tab/AlertDialogCriteriaTab.svelte index fb00303de64..a7cfc7ceccb 100644 --- a/web-common/src/features/alerts/criteria-tab/AlertDialogCriteriaTab.svelte +++ b/web-common/src/features/alerts/criteria-tab/AlertDialogCriteriaTab.svelte @@ -1,8 +1,8 @@ + +{#if $alertPreviewQuery.isFetching} +
+ +
+{:else if isCriteriaEmpty || !$alertPreviewQuery.data} + +{:else if $alertPreviewQuery.data.rows.length > 0} +
+ +
+{:else} +
+ Given the above criteria, this alert will not trigger for the current time + range. +
+{/if} diff --git a/web-common/src/features/alerts/data-tab/AlertDialogDataTab.svelte b/web-common/src/features/alerts/data-tab/AlertDialogDataTab.svelte index 77b65dfa49a..e81b19502d8 100644 --- a/web-common/src/features/alerts/data-tab/AlertDialogDataTab.svelte +++ b/web-common/src/features/alerts/data-tab/AlertDialogDataTab.svelte @@ -1,7 +1,6 @@ @@ -33,15 +33,10 @@ {:else if !$alertPreviewQuery.data} -
- -
-
No data to preview
-
- To see preview, select measures above. -
-
-
+ {:else}
{ + testCases.forEach((testCase, index) => { + it(`Test case ${index + 1}: ${testCase.description}`, () => { + const result = isExpressionIncomplete(testCase.criteria); + expect(result).toBe(testCase.incomplete); + }); + }); +}); diff --git a/web-common/src/features/dashboards/stores/filter-utils.ts b/web-common/src/features/dashboards/stores/filter-utils.ts index 5a74ec7f903..53a3c0b7de8 100644 --- a/web-common/src/features/dashboards/stores/filter-utils.ts +++ b/web-common/src/features/dashboards/stores/filter-utils.ts @@ -1,6 +1,7 @@ import { - type V1Expression, + V1Condition, V1Operation, + type V1Expression, } from "@rilldata/web-common/runtime-client"; export function createLikeExpression( @@ -253,3 +254,47 @@ export const sanitiseExpression = ( if (!where?.cond?.exprs?.length) return undefined; return where; }; + +export function isExpressionIncomplete(expression: V1Expression): boolean { + // Check if the operation is unspecified at any level of the condition. + function isOperationUnspecified(cond: V1Condition): boolean { + if ( + cond.op === V1Operation.OPERATION_UNSPECIFIED || + cond.op === undefined + ) { + return true; + } + // Check nested conditions + return ( + cond.exprs?.some( + (expr) => expr.cond && isOperationUnspecified(expr.cond), + ) ?? false + ); + } + + // Check if the val is defined and non-empty at any level of the nested expressions. + function isValDefinedAndNonEmpty(expr: V1Expression): boolean { + if (expr.val !== undefined && expr.val !== "") { + return true; // val is defined and non-empty + } + // If there is a nested condition, check if any nested expression has a defined and non-empty val + return ( + expr.cond?.exprs?.some((nestedExpr) => + isValDefinedAndNonEmpty(nestedExpr), + ) ?? false + ); + } + + // Check the top-level expression's operation + if (expression.cond && isOperationUnspecified(expression.cond)) { + return true; // The top-level operation is unspecified, thus incomplete + } + + // If there's no val at the top level, check nested expressions + if (!isValDefinedAndNonEmpty(expression)) { + return true; // No defined and non-empty val found in any expressions, thus incomplete + } + + // If the operation is specified and a defined, non-empty val is found, the expression is complete + return false; +} From cbbdb438a5618bcae38bf1c985091690cb6a86aa Mon Sep 17 00:00:00 2001 From: Eric P Green Date: Thu, 29 Feb 2024 14:09:04 -0800 Subject: [PATCH 2/4] Capitalization --- .../src/features/alerts/criteria-tab/CriteriaForm.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web-common/src/features/alerts/criteria-tab/CriteriaForm.svelte b/web-common/src/features/alerts/criteria-tab/CriteriaForm.svelte index ac24ab31f14..d5dae1fb942 100644 --- a/web-common/src/features/alerts/criteria-tab/CriteriaForm.svelte +++ b/web-common/src/features/alerts/criteria-tab/CriteriaForm.svelte @@ -2,9 +2,9 @@ import InputV2 from "@rilldata/web-common/components/forms/InputV2.svelte"; import Select from "@rilldata/web-common/components/forms/Select.svelte"; import { CriteriaOperationOptions } from "@rilldata/web-common/features/alerts/criteria-tab/operations"; - import { runtime } from "../../../runtime-client/runtime-store"; import { useMetricsView } from "@rilldata/web-common/features/dashboards/selectors"; import { debounce } from "@rilldata/web-common/lib/create-debouncer"; + import { runtime } from "../../../runtime-client/runtime-store"; export let formState: any; // svelte-forms-lib's FormState export let index: number; @@ -51,9 +51,9 @@