From bccb280c27459ee23870ffd93931a9acc880d844 Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Wed, 30 Aug 2023 14:20:58 -0500 Subject: [PATCH 01/20] Add counts api to WorkflowCounts. WIP --- .../components/workflow/workflow-count.svelte | 15 ++-- .../workflow/workflow-counts.svelte | 77 +++++++++++++------ .../pages/workflows-with-new-search.svelte | 9 ++- 3 files changed, 67 insertions(+), 34 deletions(-) diff --git a/src/lib/components/workflow/workflow-count.svelte b/src/lib/components/workflow/workflow-count.svelte index 61b342f6e..dc706af21 100644 --- a/src/lib/components/workflow/workflow-count.svelte +++ b/src/lib/components/workflow/workflow-count.svelte @@ -1,13 +1,14 @@
onStatusClick(status)} >

{count.toLocaleString()}

- + {#if status === 'all'} +

All

+ {:else} + + {/if}
diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index f09d4fb43..4b3ae2daa 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -4,16 +4,23 @@ import type { WorkflowFilter } from '$lib/models/workflow-filters'; import { workflowStatuses } from '$lib/models/workflow-status'; import { workflowFilters } from '$lib/stores/filters'; + import { workflowsQuery } from '$lib/stores/workflows'; + import { decodePayload } from '$lib/utilities/decode-payload'; import { isStatusFilter } from '$lib/utilities/query/filter-search'; import { toListWorkflowQueryFromFilters } from '$lib/utilities/query/filter-workflow-query'; import { combineFilters } from '$lib/utilities/query/to-list-workflow-filters'; import { requestFromAPI } from '$lib/utilities/request-from-api'; import { routeForApi } from '$lib/utilities/route-for-api'; import { updateQueryParameters } from '$lib/utilities/update-query-parameters'; - import { noop } from 'svelte/internal'; import WorkflowCount from './workflow-count.svelte'; + let totalCount = 0; + let statusGroups = []; + + $: groupByEnabled = + $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus; + $: statusFilters = $workflowFilters.filter((filter) => isStatusFilter(filter.attribute), ); @@ -85,23 +92,38 @@ }); }; - const groupByClause = 'GROUP BY ExecutionStatus'; + const fetchCounts = async () => { + if (groupByEnabled) { + const groupByClause = 'GROUP BY ExecutionStatus'; + const countRoute = routeForApi('workflows.count', { + namespace: $page.params.namespace, + }); + const { count, groups } = await requestFromAPI<{ + count: string; + groups: unknown[]; + }>(countRoute, { + params: { query: `${groupByClause}` }, + notifyOnError: false, + }); + totalCount = parseInt(count); + statusGroups = groups.map((group) => { + const value = decodePayload(group?.groupValues[0]); + return { + value, + count: parseInt(group.count), + }; + }); + } + }; - const countRoute = routeForApi('workflows.count', { - namespace: $page.params.namespace, - }); - const countPromise = requestFromAPI<{ count: string }>(countRoute, { - params: { query: 'GROUP BY ExecutionStatus' }, - notifyOnError: false, - }); + $: $workflowsQuery, fetchCounts(); -{#await countPromise then { count, groups }} - {(console.log('Count and groups: ', count, groups), '')} +{#if groupByEnabled}
@@ -109,8 +131,9 @@ group.value === status)?.count ?? 0} active={statusFilters.some((filter) => filter.value === status)} /> {/each}
-{/await} +{/if} diff --git a/src/lib/pages/workflows-with-new-search.svelte b/src/lib/pages/workflows-with-new-search.svelte index 43e856bd4..be086193c 100644 --- a/src/lib/pages/workflows-with-new-search.svelte +++ b/src/lib/pages/workflows-with-new-search.svelte @@ -234,7 +234,7 @@
- {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility} + {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility && !$page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus}

{#if $loading || $updating} @@ -255,13 +255,11 @@ /> {/if}

- {/if} - {#if !$loading && !$updating && $workflows.length > 0}
- exportWorkflows($workflows)} - >{translate('download-json')} {/if} + exportWorkflows($workflows)} + >{translate('download-json')}
diff --git a/src/lib/services/settings-service.ts b/src/lib/services/settings-service.ts index 71889146a..9ade90711 100644 --- a/src/lib/services/settings-service.ts +++ b/src/lib/services/settings-service.ts @@ -1,6 +1,5 @@ import { BROWSER } from 'esm-env'; -import { settings } from '$lib/stores/settings'; import type { SettingsResponse } from '$lib/types'; import type { Settings } from '$lib/types/global'; import { getApiOrigin } from '$lib/utilities/get-api-origin'; @@ -62,7 +61,5 @@ export const fetchSettings = async (request = fetch): Promise => { version: settingsResponse?.Version, }; - settings.set(settingsInformation); - return settingsInformation; }; diff --git a/src/lib/stores/advanced-visibility.ts b/src/lib/stores/advanced-visibility.ts index cbc13cb17..419260cdc 100644 --- a/src/lib/stores/advanced-visibility.ts +++ b/src/lib/stores/advanced-visibility.ts @@ -7,6 +7,7 @@ import { advancedVisibilityEnabledWithOrderBy, } from '$lib/utilities/advanced-visibility-enabled'; +import { cluster } from './cluster'; import { temporalVersion } from './versions'; export const isCloud = derived( @@ -14,8 +15,6 @@ export const isCloud = derived( ([$page]) => $page.data?.settings?.runtimeEnvironment?.isCloud, ); -export const cluster = derived([page], ([$page]) => $page.data?.cluster); - export const supportsAdvancedVisibility = derived( [cluster, temporalVersion, isCloud], ([$cluster, $temporalVersion, $isCloud]) => diff --git a/src/lib/stores/cluster.ts b/src/lib/stores/cluster.ts index 8cadb61f9..297683249 100644 --- a/src/lib/stores/cluster.ts +++ b/src/lib/stores/cluster.ts @@ -1,5 +1,7 @@ -import { writable } from 'svelte/store'; +import { derived } from 'svelte/store'; -import type { GetClusterInfoResponse } from '$lib/types'; +import { page } from '$app/stores'; -export const cluster = writable({}); +export const cluster = derived([page], ([$page]) => { + return $page.data?.cluster; +}); diff --git a/src/lib/stores/settings.ts b/src/lib/stores/settings.ts index 90bd0f49d..15242ad54 100644 --- a/src/lib/stores/settings.ts +++ b/src/lib/stores/settings.ts @@ -1,33 +1,5 @@ -import { writable } from 'svelte/store'; +import { derived } from 'svelte/store'; -import type { Settings } from '$lib/types/global'; +import { page } from '$app/stores'; -export const settings = writable({ - auth: { - enabled: false, - options: null, - }, - baseUrl: '', - codec: { - endpoint: '', - passAccessToken: false, - includeCredentials: false, - }, - defaultNamespace: null, - disableWriteActions: false, - batchActionsDisabled: false, - workflowTerminateDisabled: false, - workflowCancelDisabled: false, - workflowSignalDisabled: false, - workflowResetDisabled: false, - hideWorkflowQueryErrors: false, - showTemporalSystemNamespace: false, - notifyOnNewVersion: false, - feedbackURL: '', - runtimeEnvironment: { - isCloud: false, - isLocal: true, - envOverride: true, - }, - version: '', -}); +export const settings = derived([page], ([$page]) => $page.data.settings); diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index 8b533d264..7dc31a47d 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -3,8 +3,6 @@ import { goto } from '$app/navigation'; import { page, updated } from '$app/stores'; - import type { PageData } from './$types'; - import DataEncoderSettings from '$lib/components/data-encoder-settings.svelte'; import SideNavigation from '$lib/components/side-nav.svelte'; import TopNavigation from '$lib/components/top-nav.svelte'; @@ -27,8 +25,6 @@ import type { DescribeNamespaceResponse as Namespace } from '$types'; - export let data: PageData; - let namespaceList: NamespaceListItem[]; $: isCloud = $page.data?.settings?.runtimeEnvironment?.isCloud; diff --git a/src/routes/(app)/namespaces/[namespace]/+page.svelte b/src/routes/(app)/namespaces/[namespace]/+page.svelte index 23f5e6c44..0788444da 100644 --- a/src/routes/(app)/namespaces/[namespace]/+page.svelte +++ b/src/routes/(app)/namespaces/[namespace]/+page.svelte @@ -1,8 +1,8 @@
{#if status === 'all'} -

- {hasNonStatusQuery ? 'Query' : 'All'} -

+ {#if hasNonStatusQuery} +
Filtered
+ {:else} +

All

+ {/if} {:else} {/if} diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index 3cf0b80a1..19694035b 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -5,6 +5,7 @@ import { workflowStatuses } from '$lib/models/workflow-status'; import { workflowFilters } from '$lib/stores/filters'; import { workflowsQuery } from '$lib/stores/workflows'; + import { workflows } from '$lib/stores/workflows'; import { decodePayload } from '$lib/utilities/decode-payload'; import { isStatusFilter } from '$lib/utilities/query/filter-search'; import { toListWorkflowQueryFromFilters } from '$lib/utilities/query/filter-workflow-query'; @@ -14,6 +15,7 @@ import { updateQueryParameters } from '$lib/utilities/update-query-parameters'; import WorkflowCount from './workflow-count.svelte'; + import WorkflowTypeCount from './workflow-type-count.svelte'; let totalCount = 0; let statusGroups = []; @@ -49,6 +51,28 @@ } } + const onTypeClick = (type: string) => { + $workflowFilters = [ + ...$workflowFilters.filter((f) => !isStatusFilter(f.attribute)), + { + attribute: 'WorkflowType', + value: type, + operator: 'AND', + parenthesis: '', + conditional: '=', + }, + ]; + const searchQuery = toListWorkflowQueryFromFilters( + combineFilters($workflowFilters), + ); + updateQueryParameters({ + url: $page.url, + parameter: 'query', + value: searchQuery, + allowEmpty: true, + }); + }; + const onStatusClick = (status: string) => { if (status === 'all') { $workflowFilters = $workflowFilters.filter( @@ -125,6 +149,20 @@ }; $: $workflowsQuery, fetchCounts(); + $: $workflows, getTopTypes(); + + let topTypes = []; + + const getTopTypes = () => { + const typeCounts: Record = {}; + const types = $workflows.map((w) => w.name); + types.forEach((t) => { + typeCounts[t] = (typeCounts[t] || 0) + 1; + }); + topTypes = Object.entries(typeCounts) + .sort((a, b) => b[1] - a[1]) + .slice(0, 5); + }; {#if groupByEnabled} @@ -144,4 +182,13 @@ /> {/each} +
+ {#each topTypes as [attribute, _count] (`${attribute}`)} + + {/each} +
{/if} diff --git a/src/lib/components/workflow/workflow-type-count.svelte b/src/lib/components/workflow/workflow-type-count.svelte new file mode 100644 index 000000000..5c22a92f1 --- /dev/null +++ b/src/lib/components/workflow/workflow-type-count.svelte @@ -0,0 +1,93 @@ + + + + + diff --git a/src/lib/pages/workflows-with-new-search.svelte b/src/lib/pages/workflows-with-new-search.svelte index be086193c..e8b992f6a 100644 --- a/src/lib/pages/workflows-with-new-search.svelte +++ b/src/lib/pages/workflows-with-new-search.svelte @@ -255,14 +255,13 @@ /> {/if}

-
{/if} - exportWorkflows($workflows)} - >{translate('download-json')}
-
+
+ exportWorkflows($workflows)} + >{translate('download-json')} Date: Wed, 6 Sep 2023 10:32:25 -0500 Subject: [PATCH 11/20] Split out all and status into their own WorkflowCount components --- server/proto/dependencies/api | 2 +- .../workflow/workflow-count-all.svelte | 45 +++++++++ ...nt.svelte => workflow-count-status.svelte} | 0 .../workflow/workflow-counts.svelte | 57 +----------- .../workflow/workflow-type-count.svelte | 93 ------------------- 5 files changed, 51 insertions(+), 146 deletions(-) create mode 100644 src/lib/components/workflow/workflow-count-all.svelte rename src/lib/components/workflow/{workflow-count.svelte => workflow-count-status.svelte} (100%) delete mode 100644 src/lib/components/workflow/workflow-type-count.svelte diff --git a/server/proto/dependencies/api b/server/proto/dependencies/api index 73db036f4..b1f361602 160000 --- a/server/proto/dependencies/api +++ b/server/proto/dependencies/api @@ -1 +1 @@ -Subproject commit 73db036f444d73359e161827c2163de0c21b3ee9 +Subproject commit b1f3616023fa6ef1c2001c5a6f71fea02468635b diff --git a/src/lib/components/workflow/workflow-count-all.svelte b/src/lib/components/workflow/workflow-count-all.svelte new file mode 100644 index 000000000..9a94e135b --- /dev/null +++ b/src/lib/components/workflow/workflow-count-all.svelte @@ -0,0 +1,45 @@ + + + + + diff --git a/src/lib/components/workflow/workflow-count.svelte b/src/lib/components/workflow/workflow-count-status.svelte similarity index 100% rename from src/lib/components/workflow/workflow-count.svelte rename to src/lib/components/workflow/workflow-count-status.svelte diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index 19694035b..1e73c61ba 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -5,7 +5,6 @@ import { workflowStatuses } from '$lib/models/workflow-status'; import { workflowFilters } from '$lib/stores/filters'; import { workflowsQuery } from '$lib/stores/workflows'; - import { workflows } from '$lib/stores/workflows'; import { decodePayload } from '$lib/utilities/decode-payload'; import { isStatusFilter } from '$lib/utilities/query/filter-search'; import { toListWorkflowQueryFromFilters } from '$lib/utilities/query/filter-workflow-query'; @@ -13,9 +12,9 @@ import { requestFromAPI } from '$lib/utilities/request-from-api'; import { routeForApi } from '$lib/utilities/route-for-api'; import { updateQueryParameters } from '$lib/utilities/update-query-parameters'; - - import WorkflowCount from './workflow-count.svelte'; - import WorkflowTypeCount from './workflow-type-count.svelte'; + + import WorkflowCountAll from './workflow-count-all.svelte'; + import WorkflowCountStatus from './workflow-count-status.svelte'; let totalCount = 0; let statusGroups = []; @@ -51,28 +50,6 @@ } } - const onTypeClick = (type: string) => { - $workflowFilters = [ - ...$workflowFilters.filter((f) => !isStatusFilter(f.attribute)), - { - attribute: 'WorkflowType', - value: type, - operator: 'AND', - parenthesis: '', - conditional: '=', - }, - ]; - const searchQuery = toListWorkflowQueryFromFilters( - combineFilters($workflowFilters), - ); - updateQueryParameters({ - url: $page.url, - parameter: 'query', - value: searchQuery, - allowEmpty: true, - }); - }; - const onStatusClick = (status: string) => { if (status === 'all') { $workflowFilters = $workflowFilters.filter( @@ -149,32 +126,17 @@ }; $: $workflowsQuery, fetchCounts(); - $: $workflows, getTopTypes(); - - let topTypes = []; - - const getTopTypes = () => { - const typeCounts: Record = {}; - const types = $workflows.map((w) => w.name); - types.forEach((t) => { - typeCounts[t] = (typeCounts[t] || 0) + 1; - }); - topTypes = Object.entries(typeCounts) - .sort((a, b) => b[1] - a[1]) - .slice(0, 5); - }; {#if groupByEnabled}
- {#each workflowStatuses as status} - group.value === status)?.count ?? 0} @@ -182,13 +144,4 @@ /> {/each}
-
- {#each topTypes as [attribute, _count] (`${attribute}`)} - - {/each} -
{/if} diff --git a/src/lib/components/workflow/workflow-type-count.svelte b/src/lib/components/workflow/workflow-type-count.svelte deleted file mode 100644 index 5c22a92f1..000000000 --- a/src/lib/components/workflow/workflow-type-count.svelte +++ /dev/null @@ -1,93 +0,0 @@ - - - - - From c6e30011df2818a1a88ad13209f045d4fd96ecfc Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Wed, 6 Sep 2023 11:53:44 -0500 Subject: [PATCH 12/20] Better enabled check for cloud --- src/lib/components/workflow/workflow-counts.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index 1e73c61ba..4116cc61d 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -12,7 +12,7 @@ import { requestFromAPI } from '$lib/utilities/request-from-api'; import { routeForApi } from '$lib/utilities/route-for-api'; import { updateQueryParameters } from '$lib/utilities/update-query-parameters'; - + import WorkflowCountAll from './workflow-count-all.svelte'; import WorkflowCountStatus from './workflow-count-status.svelte'; @@ -20,6 +20,8 @@ let statusGroups = []; $: groupByEnabled = + ($page.data?.settings?.runtimeEnvironment?.isCloud && + !$page.data?.systemInfo) || $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus; $: statusFilters = $workflowFilters.filter((filter) => From 143bedb212cd5736759eda1530fbacf98deb19a9 Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Wed, 6 Sep 2023 12:22:04 -0500 Subject: [PATCH 13/20] Update unit tests --- src/lib/stores/bulk-actions.test.ts | 69 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/src/lib/stores/bulk-actions.test.ts b/src/lib/stores/bulk-actions.test.ts index abf60b5d4..9d3dfc3f7 100644 --- a/src/lib/stores/bulk-actions.test.ts +++ b/src/lib/stores/bulk-actions.test.ts @@ -3,8 +3,6 @@ import { get, type writable as writableFunc } from 'svelte/store'; import { beforeEach, describe, expect, test, vi } from 'vitest'; import { supportsBulkActions } from './bulk-actions'; -import { cluster } from './cluster'; -import { settings } from './settings'; const mockedPageStore = await vi.hoisted(async () => { const { writable } = await vi.importActual<{ @@ -31,9 +29,14 @@ describe('supportsBulkActions store', () => { }); test('returns true when batch actions are enabled, and visibility store is elasticsearch regardless of server version', () => { - cluster.set({ serverVersion: '1.0.0', visibilityStore: 'elasticsearch' }); - settings.set({ - batchActionsDisabled: false, + mockedPageStore.mockSetSubscribeValue({ + data: { + settings: { + runtimeEnvironment: { isCloud: true }, + batchActionsDisabled: false, + }, + cluster: { serverVersion: '1.0.0', visibilityStore: 'elasticsearch' }, + }, }); expect(get(supportsBulkActions)).toBe(true); @@ -47,44 +50,62 @@ describe('supportsBulkActions store', () => { }); }); test('returns true when version is newer than 1.18.0, advanced visibility is supported, and batch actions are enabled', () => { - cluster.set({ - serverVersion: '1.19.0', - visibilityStore: 'elasticsearch', - }); - settings.set({ - batchActionsDisabled: false, + mockedPageStore.mockSetSubscribeValue({ + data: { + cluster: { + serverVersion: '1.19.0', + visibilityStore: 'elasticsearch', + }, + }, }); expect(get(supportsBulkActions)).toBe(true); }); test('returns false when version is older, even if visibility store is elasticsearch and batch actions are enabled', () => { - cluster.set({ - serverVersion: '1.17.0', - visibilityStore: 'elasticsearch', - }); - settings.set({ - batchActionsDisabled: false, + mockedPageStore.mockSetSubscribeValue({ + data: { + settings: { + runtimeEnvironment: { isCloud: false }, + batchActionsDisabled: false, + }, + cluster: { + serverVersion: '1.17.0', + visibilityStore: 'elasticsearch', + }, + }, }); expect(get(supportsBulkActions)).toBe(false); }); test('returns false when advanced visibility store is not elasticsearch, even if version is newer and batch actions are enabled', () => { - cluster.set({ serverVersion: '1.19.0', visibilityStore: 'mysql' }); - settings.set({ - batchActionsDisabled: false, + mockedPageStore.mockSetSubscribeValue({ + data: { + settings: { + runtimeEnvironment: { isCloud: false }, + batchActionsDisabled: false, + }, + cluster: { serverVersion: '1.19.0', visibilityStore: 'mysql' }, + }, }); expect(get(supportsBulkActions)).toBe(false); }); test('returns false when batch actions are not enabled, even if version is newer and advanced visibility is supported', () => { - cluster.set({ - serverVersion: '1.19.0', - visibilityStore: 'elasticsearch', + mockedPageStore.mockSetSubscribeValue({ + data: { + settings: { + runtimeEnvironment: { isCloud: false }, + batchActionsDisabled: true, + }, + cluster: { + serverVersion: '1.19.0', + visibilityStore: 'elasticsearch', + }, + }, }); - settings.set({ batchActionsDisabled: true }); expect(get(supportsBulkActions)).toBe(false); }); From 9c85d9989d33cdf12a5073ff7f4fce02b3bad074 Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Wed, 6 Sep 2023 18:06:58 -0500 Subject: [PATCH 14/20] Better check for enabled --- .../workflow/workflow-counts.svelte | 23 ++++++++++--------- .../pages/workflows-with-new-search.svelte | 3 ++- src/lib/stores/bulk-actions.test.ts | 17 ++++---------- src/lib/stores/group-by-enabled.ts | 10 ++++++++ src/lib/stores/workflows.ts | 3 ++- 5 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 src/lib/stores/group-by-enabled.ts diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index 4116cc61d..bc95c3629 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -4,7 +4,8 @@ import type { WorkflowFilter } from '$lib/models/workflow-filters'; import { workflowStatuses } from '$lib/models/workflow-status'; import { workflowFilters } from '$lib/stores/filters'; - import { workflowsQuery } from '$lib/stores/workflows'; + import { groupByCountEnabled } from '$lib/stores/group-by-enabled'; + import { workflowCount, workflowsQuery } from '$lib/stores/workflows'; import { decodePayload } from '$lib/utilities/decode-payload'; import { isStatusFilter } from '$lib/utilities/query/filter-search'; import { toListWorkflowQueryFromFilters } from '$lib/utilities/query/filter-workflow-query'; @@ -16,14 +17,11 @@ import WorkflowCountAll from './workflow-count-all.svelte'; import WorkflowCountStatus from './workflow-count-status.svelte'; + $: namespace = $page.params.namespace; + let totalCount = 0; let statusGroups = []; - $: groupByEnabled = - ($page.data?.settings?.runtimeEnvironment?.isCloud && - !$page.data?.systemInfo) || - $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus; - $: statusFilters = $workflowFilters.filter((filter) => isStatusFilter(filter.attribute), ); @@ -98,10 +96,10 @@ }; const fetchCounts = async () => { - if (groupByEnabled) { + if (groupByCountEnabled) { const groupByClause = 'GROUP BY ExecutionStatus'; const countRoute = routeForApi('workflows.count', { - namespace: $page.params.namespace, + namespace, }); const query = toListWorkflowQueryFromFilters( @@ -117,20 +115,23 @@ notifyOnError: false, }); totalCount = parseInt(count); + $workflowCount.totalCount = totalCount; statusGroups = groups.map((group) => { const value = decodePayload(group?.groupValues[0]); + const count = parseInt(group.count); + // if () return { value, - count: parseInt(group.count), + count, }; }); } }; - $: $workflowsQuery, fetchCounts(); + $: $workflowsQuery, namespace, fetchCounts(); -{#if groupByEnabled} +{#if groupByCountEnabled}
- {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility && !$page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus} + {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility && !groupByCountEnabled}

{#if $loading || $updating} diff --git a/src/lib/stores/bulk-actions.test.ts b/src/lib/stores/bulk-actions.test.ts index 9d3dfc3f7..aa4a8f2f1 100644 --- a/src/lib/stores/bulk-actions.test.ts +++ b/src/lib/stores/bulk-actions.test.ts @@ -1,6 +1,6 @@ import { get, type writable as writableFunc } from 'svelte/store'; -import { beforeEach, describe, expect, test, vi } from 'vitest'; +import { describe, expect, test, vi } from 'vitest'; import { supportsBulkActions } from './bulk-actions'; @@ -22,12 +22,6 @@ vi.mock('$app/stores', () => ({ describe('supportsBulkActions store', () => { describe('for Cloud', () => { - beforeEach(() => { - mockedPageStore.mockSetSubscribeValue({ - data: { settings: { runtimeEnvironment: { isCloud: true } } }, - }); - }); - test('returns true when batch actions are enabled, and visibility store is elasticsearch regardless of server version', () => { mockedPageStore.mockSetSubscribeValue({ data: { @@ -44,14 +38,13 @@ describe('supportsBulkActions store', () => { }); describe('for Local', () => { - beforeEach(() => { - mockedPageStore.mockSetSubscribeValue({ - data: { settings: { runtimeEnvironment: { isCloud: false } } }, - }); - }); test('returns true when version is newer than 1.18.0, advanced visibility is supported, and batch actions are enabled', () => { mockedPageStore.mockSetSubscribeValue({ data: { + settings: { + runtimeEnvironment: { isCloud: false }, + batchActionsDisabled: false, + }, cluster: { serverVersion: '1.19.0', visibilityStore: 'elasticsearch', diff --git a/src/lib/stores/group-by-enabled.ts b/src/lib/stores/group-by-enabled.ts new file mode 100644 index 000000000..3fc60aab0 --- /dev/null +++ b/src/lib/stores/group-by-enabled.ts @@ -0,0 +1,10 @@ +import { derived } from 'svelte/store'; + +import { page } from '$app/stores'; + +export const groupByCountEnabled = derived([page], ([$page]) => { + return ( + $page.data?.settings?.runtimeEnvironment?.isCloud || + $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus + ); +}); diff --git a/src/lib/stores/workflows.ts b/src/lib/stores/workflows.ts index 9a5c2a323..8d545844a 100644 --- a/src/lib/stores/workflows.ts +++ b/src/lib/stores/workflows.ts @@ -12,6 +12,7 @@ import type { FilterParameters, WorkflowExecution } from '$lib/types/workflows'; import { withLoading } from '$lib/utilities/stores/with-loading'; import { supportsAdvancedVisibility } from './advanced-visibility'; +import { groupByCountEnabled } from './group-by-enabled'; export const refresh = writable(0); export const hideWorkflowQueryErrors = derived( @@ -64,7 +65,7 @@ const updateWorkflows: StartStopNotifier = (set) => { }); set(workflows); - if (supportsAdvancedVisibility) { + if (supportsAdvancedVisibility && !groupByCountEnabled) { const workflowCount = await fetchWorkflowCount(namespace, query); setCounts(workflowCount); } From 94f0350fe79e0f38fe32973a9c262daa8dd8f32d Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Fri, 13 Oct 2023 13:40:09 -0500 Subject: [PATCH 15/20] Fix check for groupByCountEnabled --- .vscode/settings.json | 22 ++++++- go.work.sum | 11 ---- .../api/workflowservice/v1/service.proto | 2 +- .../workflow/filter-search/filter-list.svelte | 5 +- .../workflow/workflow-counts.svelte | 59 +++++++++---------- .../table-body-cell.test.ts.snap | 2 +- .../table-header-cell.test.ts.snap | 2 +- .../pages/workflows-with-new-search.svelte | 4 +- src/lib/stores/group-by-enabled.ts | 5 +- src/lib/stores/workflows.ts | 4 +- src/lib/utilities/route-for-api.ts | 2 +- 11 files changed, 59 insertions(+), 59 deletions(-) delete mode 100644 go.work.sum diff --git a/.vscode/settings.json b/.vscode/settings.json index a0f7c59d7..9c02c94e7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,25 @@ "tailwindCSS.experimental.classRegex": [ ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] - ] + ], + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#ff6433", + "activityBar.background": "#ff6433", + "activityBar.foreground": "#15202b", + "activityBar.inactiveForeground": "#15202b99", + "activityBarBadge.background": "#00ff3d", + "activityBarBadge.foreground": "#15202b", + "commandCenter.border": "#e7e7e799", + "sash.hoverBorder": "#ff6433", + "statusBar.background": "#ff3d00", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#ff6433", + "statusBarItem.remoteBackground": "#ff3d00", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#ff3d00", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#ff3d0099", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#ff3d00" } diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index 33e1c2a33..000000000 --- a/go.work.sum +++ /dev/null @@ -1,11 +0,0 @@ -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -google.golang.org/genproto v0.0.0-20230815205213-6bfd019c3878 h1:Iveh6tGCJkHAjJgEqUQYGDGgbwmhjoAOz8kO/ajxefY= -google.golang.org/genproto/googleapis/api v0.0.0-20230815205213-6bfd019c3878 h1:WGq4lvB/mlicysM/dUT3SBvijH4D3sm/Ny1A4wmt2CI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 h1:lv6/DhyiFFGsmzxbsUUTOkN29II+zeWHxvT8Lpdxsv0= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= diff --git a/server/proto/api/temporal/api/workflowservice/v1/service.proto b/server/proto/api/temporal/api/workflowservice/v1/service.proto index 5952e51ae..f6f7480b1 100644 --- a/server/proto/api/temporal/api/workflowservice/v1/service.proto +++ b/server/proto/api/temporal/api/workflowservice/v1/service.proto @@ -398,7 +398,7 @@ service WorkflowService { // GetSystemInfo returns information about the system. rpc GetSystemInfo(GetSystemInfoRequest) returns (GetSystemInfoResponse) { option (google.api.http) = { - get: "/api/v1/systemInfo" + get: "/api/v1/system-info" }; } diff --git a/src/lib/components/workflow/filter-search/filter-list.svelte b/src/lib/components/workflow/filter-search/filter-list.svelte index 0fbe0c2ec..ce88e9957 100644 --- a/src/lib/components/workflow/filter-search/filter-list.svelte +++ b/src/lib/components/workflow/filter-search/filter-list.svelte @@ -20,7 +20,6 @@ import { formatDate } from '$lib/utilities/format-date'; import { isDateTimeFilter, - isStatusFilter, isTextFilter, } from '$lib/utilities/query/filter-search'; import { emptyFilter } from '$lib/utilities/query/to-list-workflow-filters'; @@ -53,9 +52,7 @@ let totalFiltersInView = 5; - $: visibleFilters = $workflowFilters - .filter((f) => !isStatusFilter(f.attribute)) - .slice(0, totalFiltersInView); + $: visibleFilters = $workflowFilters.slice(0, totalFiltersInView); $: hasMoreFilters = totalFiltersInView < $workflowFilters.length; const viewMoreFilters = () => { diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index e9034bf52..ed2978ec5 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -2,7 +2,6 @@ import { page } from '$app/stores'; import { workflowFilters } from '$lib/stores/filters'; - import { groupByCountEnabled } from '$lib/stores/group-by-enabled'; import { workflowCount, workflowsQuery } from '$lib/stores/workflows'; import type { Payloads } from '$lib/types'; import type { WorkflowStatus } from '$lib/types/workflows'; @@ -20,37 +19,35 @@ let statusGroups: { status: WorkflowStatus; count: number }[] = []; const fetchCounts = async () => { - if (groupByCountEnabled) { - const groupByClause = 'GROUP BY ExecutionStatus'; - const countRoute = routeForApi('workflows.count', { - namespace, - }); + const groupByClause = 'GROUP BY ExecutionStatus'; + const countRoute = routeForApi('workflows.count', { + namespace, + }); - const query = toListWorkflowQueryFromFilters( - combineFilters($workflowFilters), - ); - const { count, groups } = await requestFromAPI<{ - count: string; - groups: { groupValues: Payloads; count: string }[]; - }>(countRoute, { - params: { query: `${query} ${groupByClause}` }, - notifyOnError: false, - }); - totalCount = parseInt(count); - $workflowCount.totalCount = totalCount; - statusGroups = groups - .map((group) => { - const status = decodePayload( - group?.groupValues[0], - ) as unknown as WorkflowStatus; - const count = parseInt(group.count); - return { - status, - count, - }; - }) - .filter((s) => s.count > 0); - } + const query = toListWorkflowQueryFromFilters( + combineFilters($workflowFilters), + ); + const { count, groups } = await requestFromAPI<{ + count: string; + groups: { groupValues: Payloads; count: string }[]; + }>(countRoute, { + params: { query: `${query} ${groupByClause}` }, + notifyOnError: false, + }); + totalCount = parseInt(count); + $workflowCount.totalCount = totalCount; + statusGroups = groups + .map((group) => { + const status = decodePayload( + group?.groupValues[0], + ) as unknown as WorkflowStatus; + const count = parseInt(group.count); + return { + status, + count, + }; + }) + .filter((s) => s.count > 0); }; $: $workflowsQuery, namespace, fetchCounts(); diff --git a/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-body-cell.test.ts.snap b/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-body-cell.test.ts.snap index 230042b79..050c84102 100644 --- a/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-body-cell.test.ts.snap +++ b/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-body-cell.test.ts.snap @@ -18,7 +18,7 @@ exports[`Table_body_cell$ > Start renders 1`] = `" State Transitions renders 1`] = `"12"`; -exports[`Table_body_cell$ > Status renders 1`] = `"

Running
"`; +exports[`Table_body_cell$ > Status renders 1`] = `"
Running
"`; exports[`Table_body_cell$ > Task Queue renders 1`] = `"task-queue"`; diff --git a/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-header-cell.test.ts.snap b/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-header-cell.test.ts.snap index 0bed8ad25..005cb1d06 100644 --- a/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-header-cell.test.ts.snap +++ b/src/lib/components/workflow/workflows-summary-configurable-table/tests/__snapshots__/table-header-cell.test.ts.snap @@ -18,7 +18,7 @@ exports[`Table_header_cell$ > Start renders 1`] = `" State Transitions renders 1`] = `"State Transitions"`; -exports[`Table_header_cell$ > Status renders 1`] = `"
"`; +exports[`Table_header_cell$ > Status renders 1`] = `"
"`; exports[`Table_header_cell$ > Task Queue renders 1`] = `"Task Queue"`; diff --git a/src/lib/pages/workflows-with-new-search.svelte b/src/lib/pages/workflows-with-new-search.svelte index 13140683a..5af630f16 100644 --- a/src/lib/pages/workflows-with-new-search.svelte +++ b/src/lib/pages/workflows-with-new-search.svelte @@ -218,7 +218,7 @@
- {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility && !groupByCountEnabled} + {#if $workflowCount?.totalCount >= 0 && $supportsAdvancedVisibility && !$groupByCountEnabled}

{#if $loading || $updating} @@ -253,7 +253,7 @@ />

- {#if groupByCountEnabled} + {#if $groupByCountEnabled} {/if} diff --git a/src/lib/stores/group-by-enabled.ts b/src/lib/stores/group-by-enabled.ts index 3fc60aab0..7f0195c3f 100644 --- a/src/lib/stores/group-by-enabled.ts +++ b/src/lib/stores/group-by-enabled.ts @@ -3,8 +3,5 @@ import { derived } from 'svelte/store'; import { page } from '$app/stores'; export const groupByCountEnabled = derived([page], ([$page]) => { - return ( - $page.data?.settings?.runtimeEnvironment?.isCloud || - $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus - ); + return $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus; }); diff --git a/src/lib/stores/workflows.ts b/src/lib/stores/workflows.ts index 8d545844a..23bd421fd 100644 --- a/src/lib/stores/workflows.ts +++ b/src/lib/stores/workflows.ts @@ -1,5 +1,5 @@ import type { StartStopNotifier } from 'svelte/store'; -import { derived, readable, writable } from 'svelte/store'; +import { derived, get, readable, writable } from 'svelte/store'; import { page } from '$app/stores'; @@ -65,7 +65,7 @@ const updateWorkflows: StartStopNotifier = (set) => { }); set(workflows); - if (supportsAdvancedVisibility && !groupByCountEnabled) { + if (supportsAdvancedVisibility && !get(groupByCountEnabled)) { const workflowCount = await fetchWorkflowCount(namespace, query); setCounts(workflowCount); } diff --git a/src/lib/utilities/route-for-api.ts b/src/lib/utilities/route-for-api.ts index f51d4be62..f5315bf31 100644 --- a/src/lib/utilities/route-for-api.ts +++ b/src/lib/utilities/route-for-api.ts @@ -100,7 +100,7 @@ export function pathForApi( const routes: { [K in APIRoutePath]: string } = { cluster: '/cluster', - systemInfo: '/systemInfo', + systemInfo: '/system-info', 'events.ascending': `/namespaces/${parameters?.namespace}/workflows/${parameters?.workflowId}/runs/${parameters?.runId}/events`, 'events.descending': `/namespaces/${parameters?.namespace}/workflows/${parameters?.workflowId}/runs/${parameters?.runId}/events/reverse`, namespaces: '/namespaces', From 8f5b17b816b4e51453903545ab7dadd95b3d2cec Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Fri, 13 Oct 2023 13:44:26 -0500 Subject: [PATCH 16/20] Remove peacock --- .vscode/settings.json | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9c02c94e7..a0f7c59d7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,25 +11,5 @@ "tailwindCSS.experimental.classRegex": [ ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], ["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] - ], - "workbench.colorCustomizations": { - "activityBar.activeBackground": "#ff6433", - "activityBar.background": "#ff6433", - "activityBar.foreground": "#15202b", - "activityBar.inactiveForeground": "#15202b99", - "activityBarBadge.background": "#00ff3d", - "activityBarBadge.foreground": "#15202b", - "commandCenter.border": "#e7e7e799", - "sash.hoverBorder": "#ff6433", - "statusBar.background": "#ff3d00", - "statusBar.foreground": "#e7e7e7", - "statusBarItem.hoverBackground": "#ff6433", - "statusBarItem.remoteBackground": "#ff3d00", - "statusBarItem.remoteForeground": "#e7e7e7", - "titleBar.activeBackground": "#ff3d00", - "titleBar.activeForeground": "#e7e7e7", - "titleBar.inactiveBackground": "#ff3d0099", - "titleBar.inactiveForeground": "#e7e7e799" - }, - "peacock.color": "#ff3d00" + ] } From aa25568bbf3b2133fce1e9533a93669f34eca8e9 Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Fri, 13 Oct 2023 14:47:55 -0500 Subject: [PATCH 17/20] Add translate() --- src/lib/components/workflow/workflow-count-all.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/components/workflow/workflow-count-all.svelte b/src/lib/components/workflow/workflow-count-all.svelte index f9112c978..47c21b981 100644 --- a/src/lib/components/workflow/workflow-count-all.svelte +++ b/src/lib/components/workflow/workflow-count-all.svelte @@ -1,5 +1,6 @@
- +

{#if $loading || $updating} {:else if count >= 0} {count.toLocaleString()} {translate('workflows').toLocaleLowerCase()} {/if} - +

diff --git a/src/lib/stores/group-by-enabled.ts b/src/lib/stores/group-by-enabled.ts index 7f0195c3f..173756a7f 100644 --- a/src/lib/stores/group-by-enabled.ts +++ b/src/lib/stores/group-by-enabled.ts @@ -3,5 +3,7 @@ import { derived } from 'svelte/store'; import { page } from '$app/stores'; export const groupByCountEnabled = derived([page], ([$page]) => { - return $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus; + return Boolean( + $page.data?.systemInfo?.capabilities?.countGroupByExecutionStatus, + ); }); diff --git a/tests/integration/workflows-count.spec.ts b/tests/integration/workflows-count.spec.ts new file mode 100644 index 000000000..2b7d7c748 --- /dev/null +++ b/tests/integration/workflows-count.spec.ts @@ -0,0 +1,55 @@ +import { expect, test } from '@playwright/test'; + +import { + mockClusterApi, + mockSystemInfoApi, + mockWorkflowApis, + mockWorkflowsApis, + waitForWorkflowsApis, +} from '~/test-utilities/mock-apis'; + +test.describe('Workflows List with Counts', () => { + test.beforeEach(async ({ page }) => { + await mockWorkflowsApis(page); + await mockWorkflowApis(page); + + await mockClusterApi(page, { + visibilityStore: 'elasticsearch', + persistenceStore: 'postgres,elasticsearch', + }); + + await mockSystemInfoApi(page, { + capabilities: { + countGroupByExecutionStatus: false, + }, + }); + + page.goto('/namespaces/default/workflows'); + + await waitForWorkflowsApis(page); + }); + + test.describe('Shows total count and result count', () => { + test('Changes the url and updates filters on manual search', async ({ + page, + }) => { + await page.fill('#manual-search', 'WorkflowType="ImportantWorkflowType"'); + await page.click('[data-testid="manual-search-button"]'); + + await expect(page).toHaveURL( + /WorkflowType%3D%22ImportantWorkflowType%22/, + ); + + await page.getByTestId('workflow-type-filter-button').click(); + const workflowTypeValue = await page.inputValue('#workflow-type'); + expect(workflowTypeValue).toBe('ImportantWorkflowType'); + await page.waitForSelector( + '[data-testid="workflow-count"][data-loaded="true"]', + ); + + await expect(page.getByTestId('workflow-count')).toHaveText( + 'Results 15 of 15 workflows', + ); + }); + }); +}); diff --git a/tests/test-utilities/mock-apis.ts b/tests/test-utilities/mock-apis.ts index b69fb44c4..765c6123f 100644 --- a/tests/test-utilities/mock-apis.ts +++ b/tests/test-utilities/mock-apis.ts @@ -14,6 +14,7 @@ import { mockNamespaceApi } from './mocks/namespace'; import { mockNamespacesApi, NAMESPACES_API } from './mocks/namespaces'; import { mockSearchAttributesApi } from './mocks/search-attributes'; import { mockSettingsApi, SETTINGS_API } from './mocks/settings'; +import { mockSystemInfoApi } from './mocks/system-info'; import { mockTaskQueuesApi, TASK_QUEUES_API } from './mocks/task-queues'; import { mockWorkflowApi, WORKFLOW_API } from './mocks/workflow'; import { mockWorkflowsApi, WORKFLOWS_API } from './mocks/workflows'; @@ -26,6 +27,7 @@ export { mockClusterApi, CLUSTER_API } from './mocks/cluster'; export { mockNamespaceApi, NAMESPACE_API } from './mocks/namespace'; export { mockNamespacesApi, NAMESPACES_API } from './mocks/namespaces'; export { mockSettingsApi, SETTINGS_API } from './mocks/settings'; + export { mockSearchAttributesApi, SEARCH_ATTRIBUTES_API, @@ -50,6 +52,7 @@ export const mockGlobalApis = (page: Page) => { mockClusterApi(page), mockNamespacesApi(page), mockSettingsApi(page), + mockSystemInfoApi(page), ]); }; diff --git a/tests/test-utilities/mocks/system-info.ts b/tests/test-utilities/mocks/system-info.ts new file mode 100644 index 000000000..a2ac1039a --- /dev/null +++ b/tests/test-utilities/mocks/system-info.ts @@ -0,0 +1,29 @@ +import type { Page } from '@playwright/test'; + +import { GetSystemInfoResponse } from '$src/lib/types'; + +export const SYSTEM_INFO_API = '**/api/v1/system-info**'; + +const defaultSystemInfo = { + serverVersion: '1.22.0', + capabilities: { + signalAndQueryHeader: true, + internalErrorDifferentiation: true, + activityFailureIncludeHeartbeat: true, + supportsSchedules: true, + encodedFailureAttributes: true, + buildIdBasedVersioning: true, + upsertMemo: true, + eagerWorkflowStart: true, + sdkMetadata: true, + countGroupByExecutionStatus: true, + }, +}; +export const mockSystemInfoApi = async ( + page: Page, + systemInfo: Partial = {}, +) => { + await page.route(SYSTEM_INFO_API, async (route) => { + route.fulfill({ json: { ...defaultSystemInfo, ...systemInfo } }); + }); +}; diff --git a/tests/test-utilities/mocks/workflows-count.ts b/tests/test-utilities/mocks/workflows-count.ts index 77dc1b268..a4f99fc05 100644 --- a/tests/test-utilities/mocks/workflows-count.ts +++ b/tests/test-utilities/mocks/workflows-count.ts @@ -7,3 +7,87 @@ export const mockWorkflowsCountApi = (page: Page) => { return route.fulfill({ json: { count: '15' } }); }); }; + +const groupByCountResponse = { + count: '31230', + groups: [ + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IlJ1bm5pbmci', + }, + ], + count: '6', + }, + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IkNvbXBsZXRlZCI=', + }, + ], + count: '21652', + }, + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IkZhaWxlZCI=', + }, + ], + count: '1932', + }, + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IkNhbmNlbGVkIg==', + }, + ], + count: '6215', + }, + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IlRlcm1pbmF0ZWQi', + }, + ], + count: '917', + }, + { + groupValues: [ + { + metadata: { + encoding: 'anNvbi9wbGFpbg==', + type: 'S2V5d29yZA==', + }, + data: 'IlRpbWVkT3V0Ig==', + }, + ], + count: '508', + }, + ], +}; + +export const mockWorkflowsGroupByCountApi = (page: Page) => { + return page.route(WORKFLOWS_COUNT_API, (route) => { + return route.fulfill({ json: groupByCountResponse }); + }); +}; From e0d7abd7e8489705310e2c3461e71556fe8fdce4 Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Mon, 16 Oct 2023 10:57:02 -0500 Subject: [PATCH 19/20] Add testid, add integration tests for new workflow counts --- package.json | 14 +- pnpm-lock.yaml | 125 ++++++++++-------- src/lib/components/workflow-status.svelte | 5 +- .../workflow/workflow-count-status.svelte | 7 +- .../workflow/workflow-counts.svelte | 27 +--- src/lib/services/workflow-counts.ts | 81 ++++++++++++ src/lib/services/workflow-service.ts | 48 ------- src/lib/stores/workflows.ts | 6 +- src/lib/types/workflows.ts | 7 +- tests/integration/workflows-count.spec.ts | 49 ++++++- ...lows-list-with-advanced-visibility.spec.ts | 8 -- tests/test-utilities/mock-apis.ts | 1 + 12 files changed, 229 insertions(+), 149 deletions(-) create mode 100644 src/lib/services/workflow-counts.ts diff --git a/package.json b/package.json index 3093ab1c3..fe94d2aa5 100644 --- a/package.json +++ b/package.json @@ -118,13 +118,13 @@ "@sveltejs/adapter-vercel": "^1.0.5", "@sveltejs/kit": "1.15.4", "@sveltejs/vite-plugin-svelte": "^2.0.2", - "@temporalio/activity": "^1.8.4", - "@temporalio/client": "^1.8.4", - "@temporalio/common": "^1.8.4", - "@temporalio/proto": "^1.8.4", - "@temporalio/testing": "^1.8.4", - "@temporalio/worker": "^1.8.4", - "@temporalio/workflow": "^1.8.4", + "@temporalio/activity": "^1.8.6", + "@temporalio/client": "^1.8.6", + "@temporalio/common": "^1.8.6", + "@temporalio/proto": "^1.8.6", + "@temporalio/testing": "^1.8.6", + "@temporalio/worker": "^1.8.6", + "@temporalio/workflow": "^1.8.6", "@types/base-64": "^1.0.0", "@types/cors": "^2.8.13", "@types/express": "^4.17.17", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62672cb3b..63b38ec2c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,26 +131,26 @@ devDependencies: specifier: ^2.0.2 version: 2.0.2(svelte@3.55.1)(vite@4.0.5) '@temporalio/activity': - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.8.6 + version: 1.8.6 '@temporalio/client': - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.8.6 + version: 1.8.6 '@temporalio/common': - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.8.6 + version: 1.8.6 '@temporalio/proto': - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.8.6 + version: 1.8.6 '@temporalio/testing': - specifier: ^1.8.4 - version: 1.8.4(esbuild@0.13.15) + specifier: ^1.8.6 + version: 1.8.6(esbuild@0.13.15) '@temporalio/worker': - specifier: ^1.8.4 - version: 1.8.4(esbuild@0.13.15) + specifier: ^1.8.6 + version: 1.8.6(esbuild@0.13.15) '@temporalio/workflow': - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.8.6 + version: 1.8.6 '@types/base-64': specifier: ^1.0.0 version: 1.0.0 @@ -1844,64 +1844,64 @@ packages: '@swc/core-win32-x64-msvc': 1.3.35 dev: true - /@temporalio/activity@1.8.4: - resolution: {integrity: sha512-B28cD4ncq51R9HAQVmTMTl/qOZQLuqfRQ4fDTS5thDssHEkV4ciamoPYLyD+57yriAGoN+aWi+r5aqyfLdTqdQ==} + /@temporalio/activity@1.8.6: + resolution: {integrity: sha512-xTPIWIR1mL51Ub45nWpix+ATzJz/8ZAp0cCp3qw+xnKD8pwd4z9L0b30lr3co5kaPlWhSesdhypQ7VwWEf7ZHA==} dependencies: - '@temporalio/common': 1.8.4 + '@temporalio/common': 1.8.6 abort-controller: 3.0.0 dev: true - /@temporalio/client@1.8.4: - resolution: {integrity: sha512-0QnEk0gNia98jS68m0euhswpkRvHd/1E5OkKMSIuIMfI4ODRSDO6uKm9ZPJLdwFVPOKanKLlqk6B6Qt5BqFUaA==} + /@temporalio/client@1.8.6: + resolution: {integrity: sha512-lcDy9YeNrHU1thGpfsvxxHOLj8VKEbEthkAWQfyZghvvjQ3K7NHS7qRzYfB9ZbYnaus+ZiodSqnKTyqW9gsJ6A==} dependencies: '@grpc/grpc-js': 1.7.3 - '@temporalio/common': 1.8.4 - '@temporalio/proto': 1.8.4 + '@temporalio/common': 1.8.6 + '@temporalio/proto': 1.8.6 abort-controller: 3.0.0 long: 5.2.1 uuid: 8.3.2 dev: true - /@temporalio/common@1.8.4: - resolution: {integrity: sha512-jZhOc/tAfqAMbAnZ53WDVUwXUvot1TyvNgtuLeDmIvWnwfw/Lk5v106YoqFscdwDZ/pFbPrrbfxbvqOGdfDq4A==} + /@temporalio/common@1.8.6: + resolution: {integrity: sha512-7Cu1ymGkgklJM5xoYgJbppM/K/Dmq6Lb9bQnJiSvp8sb/RxXz6DQbiWypl9iDmaocUyFzDDaB/brA6abIq9xOQ==} dependencies: '@opentelemetry/api': 1.4.1 - '@temporalio/proto': 1.8.4 + '@temporalio/proto': 1.8.6 long: 5.2.1 ms: 3.0.0-canary.1 proto3-json-serializer: 1.1.0 - protobufjs: 7.2.2 + protobufjs: 7.2.5 dev: true - /@temporalio/core-bridge@1.8.4: - resolution: {integrity: sha512-iDmAKDzIPbXcUxn+5EADytTl9Ck72MKV/avldneSvyBvXjMAPxFhdpjEcRpvpLvdFCvogeSEy0juXstHyXD81A==} + /@temporalio/core-bridge@1.8.6: + resolution: {integrity: sha512-YkoG03qG7gqBWOupuhK1kt9A//ossKW2lOY9T22ZOTv2JfVZNgQPm0N0Kcusw0s4YULdiSGlLjalvRo4YTDoyQ==} requiresBuild: true dependencies: '@opentelemetry/api': 1.4.1 - '@temporalio/common': 1.8.4 + '@temporalio/common': 1.8.6 arg: 5.0.2 cargo-cp-artifact: 0.1.7 which: 2.0.2 dev: true - /@temporalio/proto@1.8.4: - resolution: {integrity: sha512-r1QSZbLl1gKXelwhr3F+ccIk+BnhCIGuYvWz3Jgo1PVqhVf698dw4hGnLjvaXA8x3QF55ysmjucYvjz9Pul51w==} + /@temporalio/proto@1.8.6: + resolution: {integrity: sha512-32ADOGSGBRinikP/XRTmyPXlIRaWjg5oAn64zj5NJRESrQy6ifpXb8bYVoPK01K9NIvcCL8FewCCWRKxxNvKZg==} dependencies: long: 5.2.1 - protobufjs: 7.2.2 + protobufjs: 7.2.5 dev: true - /@temporalio/testing@1.8.4(esbuild@0.13.15): - resolution: {integrity: sha512-cUOG/W8+fMxoz0WtUnSuHMlfAb6urDzWAk7qV02FhrM+syHG9s9pKDKvbQTr76nB1iplAYgUCwzh1kJzs5veAA==} + /@temporalio/testing@1.8.6(esbuild@0.13.15): + resolution: {integrity: sha512-sbSMfn18PjYsdHJRiDnfpNI33KK6BJvmud5C/uhZdxjVk6C2KLc2mt3lTZ6YGQ+K9ICiwztxWvxYNC/X2dfGBg==} dependencies: '@grpc/grpc-js': 1.7.3 - '@temporalio/activity': 1.8.4 - '@temporalio/client': 1.8.4 - '@temporalio/common': 1.8.4 - '@temporalio/core-bridge': 1.8.4 - '@temporalio/proto': 1.8.4 - '@temporalio/worker': 1.8.4(esbuild@0.13.15) - '@temporalio/workflow': 1.8.4 + '@temporalio/activity': 1.8.6 + '@temporalio/client': 1.8.6 + '@temporalio/common': 1.8.6 + '@temporalio/core-bridge': 1.8.6 + '@temporalio/proto': 1.8.6 + '@temporalio/worker': 1.8.6(esbuild@0.13.15) + '@temporalio/workflow': 1.8.6 abort-controller: 3.0.0 transitivePeerDependencies: - esbuild @@ -1909,18 +1909,18 @@ packages: - webpack-cli dev: true - /@temporalio/worker@1.8.4(esbuild@0.13.15): - resolution: {integrity: sha512-lYuN0a+4wABS3w2T4Bc0s8zMXL2oEic0Sa6TJ4ZA+UAjRIc2YNh7C+0pl8+WDLwhHMAC33CPoNg7xLZen5gdKA==} + /@temporalio/worker@1.8.6(esbuild@0.13.15): + resolution: {integrity: sha512-1T7TTkJwFJxrtAjRzHWpEoMlSrFw4b45aPx5oD8gpJCzkytHtjYjFLyPIuNOiFwsTzOJzffKnl2YIGinnn8emA==} engines: {node: '>= 14.18.0'} dependencies: '@opentelemetry/api': 1.4.1 '@swc/core': 1.3.35 - '@temporalio/activity': 1.8.4 - '@temporalio/client': 1.8.4 - '@temporalio/common': 1.8.4 - '@temporalio/core-bridge': 1.8.4 - '@temporalio/proto': 1.8.4 - '@temporalio/workflow': 1.8.4 + '@temporalio/activity': 1.8.6 + '@temporalio/client': 1.8.6 + '@temporalio/common': 1.8.6 + '@temporalio/core-bridge': 1.8.6 + '@temporalio/proto': 1.8.6 + '@temporalio/workflow': 1.8.6 abort-controller: 3.0.0 cargo-cp-artifact: 0.1.7 heap-js: 2.2.0 @@ -1937,11 +1937,11 @@ packages: - webpack-cli dev: true - /@temporalio/workflow@1.8.4: - resolution: {integrity: sha512-LtX+fxgHyvwEGKao9y7iBgaKEc8KVL0rWw7U1+hwITUo5LXBWpQqip8aOkDZ0+n64r8jvnDQ7W8QOPXaWLcD5Q==} + /@temporalio/workflow@1.8.6: + resolution: {integrity: sha512-ltVIqjNyJ3HvkhdA8RvcID6ylKZK8Fggw4mOSNnpPXkhGiCxA0oXuidaZK+MW9lTJzbm5EDiOvt3YctchCWK0Q==} dependencies: - '@temporalio/common': 1.8.4 - '@temporalio/proto': 1.8.4 + '@temporalio/common': 1.8.6 + '@temporalio/proto': 1.8.6 dev: true /@tootallnate/once@2.0.0: @@ -8233,7 +8233,7 @@ packages: resolution: {integrity: sha512-SjXwUWe/vANGs/mJJTbw5++7U67nwsymg7qsoPtw6GiXqw3kUy8ByojrlEdVE2efxAdKreX8WkDafxvYW95ZQg==} engines: {node: '>=12.0.0'} dependencies: - protobufjs: 7.2.2 + protobufjs: 7.2.5 dev: true /protobufjs@6.11.4: @@ -8275,6 +8275,25 @@ packages: long: 5.2.1 dev: true + /protobufjs@7.2.5: + resolution: {integrity: sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==} + engines: {node: '>=12.0.0'} + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 16.18.11 + long: 5.2.1 + dev: true + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} diff --git a/src/lib/components/workflow-status.svelte b/src/lib/components/workflow-status.svelte index eb98beb03..8d36937b4 100644 --- a/src/lib/components/workflow-status.svelte +++ b/src/lib/components/workflow-status.svelte @@ -69,7 +69,10 @@ ); -
+
{#if loading} diff --git a/src/lib/components/workflow/workflow-count-status.svelte b/src/lib/components/workflow/workflow-count-status.svelte index dca2d4df3..d23fbde22 100644 --- a/src/lib/components/workflow/workflow-count-status.svelte +++ b/src/lib/components/workflow/workflow-count-status.svelte @@ -8,4 +8,9 @@ export let count = 0; - + diff --git a/src/lib/components/workflow/workflow-counts.svelte b/src/lib/components/workflow/workflow-counts.svelte index ed2978ec5..c65be5a4c 100644 --- a/src/lib/components/workflow/workflow-counts.svelte +++ b/src/lib/components/workflow/workflow-counts.svelte @@ -1,41 +1,24 @@
- + {#each statusGroups as { count, status } (status)} {/each} diff --git a/src/lib/services/workflow-counts.ts b/src/lib/services/workflow-counts.ts new file mode 100644 index 000000000..e7925aa69 --- /dev/null +++ b/src/lib/services/workflow-counts.ts @@ -0,0 +1,81 @@ +import { noop } from 'svelte/internal'; + +import type { WorkflowFilter } from '$lib/models/workflow-filters'; +import type { CountWorkflowExecutionsResponse } from '$lib/types/workflows'; +import { toListWorkflowQueryFromFilters } from '$lib/utilities/query/filter-workflow-query'; +import { combineFilters } from '$lib/utilities/query/to-list-workflow-filters'; +import { requestFromAPI } from '$lib/utilities/request-from-api'; +import { routeForApi } from '$lib/utilities/route-for-api'; + +export const fetchWorkflowCount = async ( + namespace: string, + query: string, + request = fetch, +): Promise<{ totalCount: number; count: number }> => { + let totalCount = 0; + let count = 0; + try { + const countRoute = routeForApi('workflows.count', { namespace }); + if (!query) { + const totalCountResult = await requestFromAPI<{ count: string }>( + countRoute, + { + params: {}, + onError: noop, + handleError: noop, + request, + }, + ); + totalCount = parseInt(totalCountResult?.count); + } else { + const countPromise = requestFromAPI<{ count: string }>(countRoute, { + params: { query }, + onError: noop, + handleError: noop, + request, + }); + const totalCountPromise = requestFromAPI<{ count: string }>(countRoute, { + params: { query: '' }, + onError: noop, + handleError: noop, + request, + }); + const [countResult, totalCountResult] = await Promise.all([ + countPromise, + totalCountPromise, + ]); + count = parseInt(countResult?.count ?? '0'); + totalCount = parseInt(totalCountResult?.count); + } + } catch (e) { + // Don't fail the workflows call due to count + } + + return { count, totalCount }; +}; + +type WorkflowCountByExecutionStatusOptions = { + namespace: string; + filters: WorkflowFilter[]; +}; + +export const fetchWorkflowCountByExecutionStatus = async ({ + namespace, + filters, +}: WorkflowCountByExecutionStatusOptions): Promise => { + try { + const groupByClause = 'GROUP BY ExecutionStatus'; + const countRoute = routeForApi('workflows.count', { + namespace, + }); + const query = toListWorkflowQueryFromFilters(combineFilters(filters)); + const { count, groups } = + await requestFromAPI(countRoute, { + params: { query: `${query} ${groupByClause}` }, + notifyOnError: false, + }); + return { count, groups }; + } catch (e) { + return { count: '0', groups: [] }; + } +}; diff --git a/src/lib/services/workflow-service.ts b/src/lib/services/workflow-service.ts index a05785f4f..cba87c175 100644 --- a/src/lib/services/workflow-service.ts +++ b/src/lib/services/workflow-service.ts @@ -1,4 +1,3 @@ -import { noop } from 'svelte/internal'; import { get } from 'svelte/store'; import { v4 } from 'uuid'; @@ -88,53 +87,6 @@ export type FetchWorkflow = | typeof fetchAllWorkflows | typeof fetchAllArchivedWorkflows; -export const fetchWorkflowCount = async ( - namespace: string, - query: string, - request = fetch, -): Promise<{ totalCount: number; count: number }> => { - let totalCount = 0; - let count = 0; - try { - const countRoute = routeForApi('workflows.count', { namespace }); - if (!query) { - const totalCountResult = await requestFromAPI<{ count: string }>( - countRoute, - { - params: {}, - onError: noop, - handleError: noop, - request, - }, - ); - totalCount = parseInt(totalCountResult?.count); - } else { - const countPromise = requestFromAPI<{ count: string }>(countRoute, { - params: { query }, - onError: noop, - handleError: noop, - request, - }); - const totalCountPromise = requestFromAPI<{ count: string }>(countRoute, { - params: { query: '' }, - onError: noop, - handleError: noop, - request, - }); - const [countResult, totalCountResult] = await Promise.all([ - countPromise, - totalCountPromise, - ]); - count = parseInt(countResult?.count ?? '0'); - totalCount = parseInt(totalCountResult?.count); - } - } catch (e) { - // Don't fail the workflows call due to count - } - - return { count, totalCount }; -}; - export const fetchAllWorkflows = async ( namespace: string, parameters: ValidWorkflowParameters, diff --git a/src/lib/stores/workflows.ts b/src/lib/stores/workflows.ts index 23bd421fd..abce870bc 100644 --- a/src/lib/stores/workflows.ts +++ b/src/lib/stores/workflows.ts @@ -4,10 +4,8 @@ import { derived, get, readable, writable } from 'svelte/store'; import { page } from '$app/stores'; import { translate } from '$lib/i18n/translate'; -import { - fetchAllWorkflows, - fetchWorkflowCount, -} from '$lib/services/workflow-service'; +import { fetchWorkflowCount } from '$lib/services/workflow-counts'; +import { fetchAllWorkflows } from '$lib/services/workflow-service'; import type { FilterParameters, WorkflowExecution } from '$lib/types/workflows'; import { withLoading } from '$lib/utilities/stores/with-loading'; diff --git a/src/lib/types/workflows.ts b/src/lib/types/workflows.ts index 41280ef05..4d7c69dff 100644 --- a/src/lib/types/workflows.ts +++ b/src/lib/types/workflows.ts @@ -1,4 +1,4 @@ -import type { WorkflowVersionTimpstamp } from '$lib/types'; +import type { Payloads, WorkflowVersionTimpstamp } from '$lib/types'; import type { Payload, @@ -30,6 +30,11 @@ export type ListWorkflowExecutionsResponse = Replace< Optional<{ executions: WorkflowExecutionInfo[] }> >; +export type CountWorkflowExecutionsResponse = { + count: string; + groups: { count: string; groupValues: Payloads }[]; +}; + export type WorkflowExecutionConfig = Replace< import('$lib/types').WorkflowExecutionConfig, { defaultWorkflowTaskTimeout: Duration } diff --git a/tests/integration/workflows-count.spec.ts b/tests/integration/workflows-count.spec.ts index 2b7d7c748..d4f0fe8ae 100644 --- a/tests/integration/workflows-count.spec.ts +++ b/tests/integration/workflows-count.spec.ts @@ -5,10 +5,11 @@ import { mockSystemInfoApi, mockWorkflowApis, mockWorkflowsApis, + mockWorkflowsGroupByCountApi, waitForWorkflowsApis, } from '~/test-utilities/mock-apis'; -test.describe('Workflows List with Counts', () => { +test.describe('Workflows List with Counts when countGroupByExecutionStatus is disabled', () => { test.beforeEach(async ({ page }) => { await mockWorkflowsApis(page); await mockWorkflowApis(page); @@ -30,9 +31,15 @@ test.describe('Workflows List with Counts', () => { }); test.describe('Shows total count and result count', () => { - test('Changes the url and updates filters on manual search', async ({ - page, - }) => { + test('Results of workflows ', async ({ page }) => { + await page.waitForSelector( + '[data-testid="workflow-count"][data-loaded="true"]', + ); + + await expect(page.getByTestId('workflow-count')).toHaveText( + '15 workflows', + ); + await page.fill('#manual-search', 'WorkflowType="ImportantWorkflowType"'); await page.click('[data-testid="manual-search-button"]'); @@ -53,3 +60,37 @@ test.describe('Workflows List with Counts', () => { }); }); }); + +test.describe('Workflows List with Counts when countGroupByExecutionStatus is enabled', () => { + test.beforeEach(async ({ page }) => { + await mockWorkflowsApis(page); + await mockWorkflowApis(page); + + await mockClusterApi(page, { + visibilityStore: 'elasticsearch', + persistenceStore: 'postgres,elasticsearch', + }); + + page.goto('/namespaces/default/workflows'); + + await mockWorkflowsGroupByCountApi(page); + await waitForWorkflowsApis(page); + }); + + test.describe('Shows only result count', () => { + test('Counts of workflows ', async ({ page }) => { + await page.waitForSelector( + '[data-testid="workflow-count"][data-loaded="true"]', + ); + await expect(page.getByTestId('workflow-count')).toHaveText( + '31,230 workflows', + ); + await expect(page.getByTestId('workflow-status-Running')).toHaveText( + '6 Running', + ); + await expect(page.getByTestId('workflow-status-Completed')).toHaveText( + '21,652 Completed', + ); + }); + }); +}); diff --git a/tests/integration/workflows-list-with-advanced-visibility.spec.ts b/tests/integration/workflows-list-with-advanced-visibility.spec.ts index 1d57ab3a5..f335025b2 100644 --- a/tests/integration/workflows-list-with-advanced-visibility.spec.ts +++ b/tests/integration/workflows-list-with-advanced-visibility.spec.ts @@ -39,10 +39,6 @@ test.describe('Workflows List with Advanced Visibility', () => { await page.waitForSelector( '[data-testid="workflow-count"][data-loaded="true"]', ); - - await expect(page.getByTestId('workflow-count')).toHaveText( - 'Results 15 of 15 workflows', - ); }); }); @@ -158,10 +154,6 @@ test.describe('Workflows List with Advanced Visibility', () => { await page.waitForSelector( '[data-testid="workflow-count"][data-loaded="true"]', ); - - await expect(page.getByTestId('workflow-count')).toHaveText( - 'Results 15 of 15 workflows', - ); }); test('keeps workflow datetime filter after navigating away and back to workflow list', async ({ diff --git a/tests/test-utilities/mock-apis.ts b/tests/test-utilities/mock-apis.ts index 765c6123f..a8f637898 100644 --- a/tests/test-utilities/mock-apis.ts +++ b/tests/test-utilities/mock-apis.ts @@ -27,6 +27,7 @@ export { mockClusterApi, CLUSTER_API } from './mocks/cluster'; export { mockNamespaceApi, NAMESPACE_API } from './mocks/namespace'; export { mockNamespacesApi, NAMESPACES_API } from './mocks/namespaces'; export { mockSettingsApi, SETTINGS_API } from './mocks/settings'; +export { mockSystemInfoApi } from './mocks/system-info'; export { mockSearchAttributesApi, From a4f4a412948edb5283d05ff3b7f1e44a859e726b Mon Sep 17 00:00:00 2001 From: Alex Tideman Date: Mon, 16 Oct 2023 11:03:33 -0500 Subject: [PATCH 20/20] Export mockGroupByApi --- tests/test-utilities/mock-apis.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test-utilities/mock-apis.ts b/tests/test-utilities/mock-apis.ts index a8f637898..078778f1a 100644 --- a/tests/test-utilities/mock-apis.ts +++ b/tests/test-utilities/mock-apis.ts @@ -37,6 +37,7 @@ export { mockWorkflowsApi, WORKFLOWS_API } from './mocks/workflows'; export { mockWorkflowApi, WORKFLOW_API } from './mocks/workflow'; export { mockWorkflowsCountApi, + mockWorkflowsGroupByCountApi, WORKFLOWS_COUNT_API, } from './mocks/workflows-count'; export {