From 6805d99365bb825b784555e1c1c5fc447bda0e60 Mon Sep 17 00:00:00 2001 From: Rodrigo Arze Leon Date: Fri, 25 Oct 2024 18:31:51 -0400 Subject: [PATCH 1/4] Add message when filtered data is empty array --- .../components/IntegrationSearch.tsx | 96 ++++++++++--------- 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/packages/engine-frontend/components/IntegrationSearch.tsx b/packages/engine-frontend/components/IntegrationSearch.tsx index bfe42808..771b06c3 100644 --- a/packages/engine-frontend/components/IntegrationSearch.tsx +++ b/packages/engine-frontend/components/IntegrationSearch.tsx @@ -65,54 +65,64 @@ export function IntegrationSearch({ {/* Search results */} {listIntegrationsRes.isLoading ? ( -
+
) : (
- {Object.entries(intsByCategory ?? {}).map( - ([category, categoryInts]) => ( -
-

- {category.length < 5 - ? category.toUpperCase() - : category - .split('-') - .map( - (word) => - word.charAt(0).toUpperCase() + word.slice(1), - ) - .join(' ')} -

-
- {categoryInts.map((int) => ( - { - onEvent?.({ - type: e.type, - integration: { - connectorConfigId: int.connector_config_id, - id: int.id, - }, - }) - }}> - {({openConnect}) => ( - - )} - - ))} + {(ints && ints.length > 0) || + Object.keys(intsByCategory ?? {}).length > 0 ? ( + Object.entries(intsByCategory ?? {}).map( + ([category, categoryInts]) => ( +
+

+ {category.length < 5 + ? category.toUpperCase() + : category + .split('-') + .map( + (word) => + word.charAt(0).toUpperCase() + word.slice(1), + ) + .join(' ')} +

+
+ {categoryInts.map((int) => ( + { + onEvent?.({ + type: e.type, + integration: { + connectorConfigId: int.connector_config_id, + id: int.id, + }, + }) + }}> + {({openConnect}) => ( + + )} + + ))} +
-
- ), + ), + ) + ) : ( +
+

+ No available connectors, please check that you have configured + connectors available or review your filter values. +

+
)}
)} From 925624c7c89807dc1a912734d44733e29c7aa9a4 Mon Sep 17 00:00:00 2001 From: Rodrigo Arze Leon Date: Fri, 25 Oct 2024 19:55:02 -0400 Subject: [PATCH 2/4] Integrate category filter to add connection tab --- .../components/IntegrationSearch.tsx | 39 +++++++++++-------- packages/ui/components/CheckboxFilter.tsx | 36 ++++++++++++++--- packages/ui/utils.ts | 9 +++++ 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/packages/engine-frontend/components/IntegrationSearch.tsx b/packages/engine-frontend/components/IntegrationSearch.tsx index 771b06c3..6d482011 100644 --- a/packages/engine-frontend/components/IntegrationSearch.tsx +++ b/packages/engine-frontend/components/IntegrationSearch.tsx @@ -1,8 +1,9 @@ 'use client' import {Loader, Search} from 'lucide-react' -import React from 'react' -import {Input} from '@openint/ui' +import React, {useState} from 'react' +import {Input, parseCategory} from '@openint/ui' +import {CheckboxFilter} from '@openint/ui/components/CheckboxFilter' import {ConnectionCard} from '@openint/ui/domain-components/ConnectionCard' import type {ConnectorConfig} from '../hocs/WithConnectConfig' import type {ConnectEventType} from '../hocs/WithConnectorConnect' @@ -25,7 +26,8 @@ export function IntegrationSearch({ type: ConnectEventType }) => void }) { - const [searchText, setSearchText] = React.useState('') + const [searchText, setSearchText] = useState('') + const [categoryFilter, setCategoryFilter] = useState([]) const listIntegrationsRes = _trpcReact.listConfiguredIntegrations.useQuery({ connector_config_ids: connectorConfigs.map((ccfg) => ccfg.id), @@ -36,24 +38,34 @@ export function IntegrationSearch({ ccfg: connectorConfigs.find((ccfg) => ccfg.id === int.connector_config_id)!, })) + const categories = Array.from( + new Set(connectorConfigs.flatMap((ccfg) => ccfg.verticals)), + ) + const intsByCategory = ints?.reduce( (acc, int) => { int.ccfg.verticals.forEach((vertical) => { - acc[vertical] = (acc[vertical] || []).concat(int) + if (categoryFilter.length === 0 || categoryFilter.includes(vertical)) { + acc[vertical] = (acc[vertical] || []).concat(int) + } }) return acc }, {} as Record, ) + const onApplyFilter = (selected: string[]) => { + setCategoryFilter(selected) + } + return (
{/* Search integrations */}
-
-
+
+
{/* top-2.5 is not working for some reason due to tailwind setup */} - + setSearchText(e.target.value)} />
- + +
{/* Search results */} {listIntegrationsRes.isLoading ? ( @@ -76,15 +89,7 @@ export function IntegrationSearch({ ([category, categoryInts]) => (

- {category.length < 5 - ? category.toUpperCase() - : category - .split('-') - .map( - (word) => - word.charAt(0).toUpperCase() + word.slice(1), - ) - .join(' ')} + {parseCategory(category)}

{categoryInts.map((int) => ( diff --git a/packages/ui/components/CheckboxFilter.tsx b/packages/ui/components/CheckboxFilter.tsx index 9d37ebf5..89daac84 100644 --- a/packages/ui/components/CheckboxFilter.tsx +++ b/packages/ui/components/CheckboxFilter.tsx @@ -3,13 +3,14 @@ import {useState} from 'react' import {Button} from '../shadcn/Button' import {Checkbox} from '../shadcn/Checkbox' import {Popover, PopoverContent, PopoverTrigger} from '../shadcn/Popover' +import {parseCategory} from '../utils' export function CheckboxFilter({ options, onApply, }: { options: string[] - onApply: () => void + onApply: (selected: string[]) => void }) { const [checkedState, setCheckedState] = useState>( options.reduce( @@ -37,7 +38,7 @@ export function CheckboxFilter({ Category - +
{options.map((option) => (
{checkedState[option] && ( @@ -80,14 +81,37 @@ export function CheckboxFilter({ htmlFor={option} className="cursor-pointer text-sm font-semibold"> {' '} - {option} + {parseCategory(option)}
))} {/* Added a visible divider here */}
-
- +
diff --git a/packages/ui/utils.ts b/packages/ui/utils.ts index 2ae4bafb..f6f76550 100644 --- a/packages/ui/utils.ts +++ b/packages/ui/utils.ts @@ -13,3 +13,12 @@ export function getValidChildren(children: React.ReactNode) { React.isValidElement(child), ) as React.ReactElement[] } + +export function parseCategory(category: string) { + return category.length < 5 + ? category.toUpperCase() + : category + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' ') +} From ee25b0be277f69750a7a13512ad494232b4dce56 Mon Sep 17 00:00:00 2001 From: Rodrigo Arze Leon Date: Fri, 25 Oct 2024 20:02:22 -0400 Subject: [PATCH 3/4] Fix lint --- packages/engine-frontend/components/IntegrationSearch.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine-frontend/components/IntegrationSearch.tsx b/packages/engine-frontend/components/IntegrationSearch.tsx index 6d482011..5058468a 100644 --- a/packages/engine-frontend/components/IntegrationSearch.tsx +++ b/packages/engine-frontend/components/IntegrationSearch.tsx @@ -1,7 +1,7 @@ 'use client' import {Loader, Search} from 'lucide-react' -import React, {useState} from 'react' +import {useState} from 'react' import {Input, parseCategory} from '@openint/ui' import {CheckboxFilter} from '@openint/ui/components/CheckboxFilter' import {ConnectionCard} from '@openint/ui/domain-components/ConnectionCard' From 22f5963b7bbd1691a23fb115c3f53b46d2e04aed Mon Sep 17 00:00:00 2001 From: Rodrigo Arze Leon Date: Mon, 28 Oct 2024 12:35:40 -0400 Subject: [PATCH 4/4] Show filter when we have more than one category --- packages/engine-frontend/components/IntegrationSearch.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/engine-frontend/components/IntegrationSearch.tsx b/packages/engine-frontend/components/IntegrationSearch.tsx index 5058468a..c453089c 100644 --- a/packages/engine-frontend/components/IntegrationSearch.tsx +++ b/packages/engine-frontend/components/IntegrationSearch.tsx @@ -73,7 +73,9 @@ export function IntegrationSearch({ onChange={(e) => setSearchText(e.target.value)} />
- + {categories.length > 1 && ( + + )}
{/* Search results */}