diff --git a/frontend/packages/console-shared/src/components/catalog/catalog-view/CatalogFilters.tsx b/frontend/packages/console-shared/src/components/catalog/catalog-view/CatalogFilters.tsx index c668d3dfdcc..d1d10e31591 100644 --- a/frontend/packages/console-shared/src/components/catalog/catalog-view/CatalogFilters.tsx +++ b/frontend/packages/console-shared/src/components/catalog/catalog-view/CatalogFilters.tsx @@ -5,7 +5,12 @@ import { FilterSidePanelCategoryItem, } from '@patternfly/react-catalog-view-extension'; import * as _ from 'lodash'; -import { CatalogFilterCounts, CatalogFilters } from '../utils/types'; +import { + CatalogFilter, + CatalogFilterCounts, + CatalogFilterItem, + CatalogFilters, +} from '../utils/types'; type CatalogFiltersProps = { activeFilters: CatalogFilters; @@ -24,7 +29,14 @@ const CatalogFilters: React.FC = ({ onFilterChange, onShowAllToggle, }) => { - const renderFilterItem = (filter, filterName, groupName) => { + const sortedActiveFilters = Object.keys(activeFilters) + .sort() + .reduce((acc, groupName) => { + acc[groupName] = activeFilters[groupName]; + return acc; + }, {}); + + const renderFilterItem = (filter: CatalogFilterItem, filterName: string, groupName: string) => { const { label, active } = filter; const count = filterGroupCounts[groupName]?.[filterName] ?? 0; // TODO remove when adopting https://github.com/patternfly/patternfly-react/issues/5139 @@ -47,24 +59,35 @@ const CatalogFilters: React.FC = ({ ); }; - const renderFilterGroup = (filterGroup, groupName) => - Object.keys(filterGroup).length > 1 ? ( - onShowAllToggle(groupName)} - showAll={filterGroupsShowAll[groupName] ?? false} - data-test-group-name={groupName} - > - {_.map(filterGroup, (filter, filterName) => - renderFilterItem(filter, filterName, groupName), - )} - - ) : null; + const renderFilterGroup = (filterGroup: CatalogFilter, groupName: string) => { + const filterGroupKeys = Object.keys(filterGroup); + if (filterGroupKeys.length > 1) { + const sortedFilterGroup = filterGroupKeys.sort().reduce((acc, filterName) => { + acc[filterName] = filterGroup[filterName]; + return acc; + }, {}); + return ( + onShowAllToggle(groupName)} + showAll={filterGroupsShowAll[groupName] ?? false} + data-test-group-name={groupName} + > + {_.map(sortedFilterGroup, (filter, filterName) => + renderFilterItem(filter, filterName, groupName), + )} + + ); + } + return null; + }; return ( - {_.map(activeFilters, (filterGroup, groupName) => renderFilterGroup(filterGroup, groupName))} + {_.map(sortedActiveFilters, (filterGroup, groupName) => + renderFilterGroup(filterGroup, groupName), + )} ); }; diff --git a/frontend/packages/console-shared/src/components/catalog/service/CatalogServiceProvider.tsx b/frontend/packages/console-shared/src/components/catalog/service/CatalogServiceProvider.tsx index c16fc308524..e09c2cfb3da 100644 --- a/frontend/packages/console-shared/src/components/catalog/service/CatalogServiceProvider.tsx +++ b/frontend/packages/console-shared/src/components/catalog/service/CatalogServiceProvider.tsx @@ -36,7 +36,7 @@ const CatalogServiceProvider: React.FC = ({ const [extItemsMap, setExtItemsMap] = React.useState<{ [uid: string]: CatalogItem[] }>({}); const [extItemsErrorMap, setItemsErrorMap] = React.useState<{ [uid: string]: Error }>({}); const [metadataProviderMap, setMetadataProviderMap] = React.useState<{ - [type: string]: CatalogItemMetadataProviderFunction[]; + [type: string]: { [id: string]: CatalogItemMetadataProviderFunction }; }>({}); const loaded = @@ -79,8 +79,11 @@ const CatalogServiceProvider: React.FC = ({ setItemsErrorMap((prev) => ({ ...prev, [uid]: error })); }, []); - const onMetadataValueResolved = React.useCallback((provider, type) => { - setMetadataProviderMap((prev) => ({ ...prev, [type]: [...(prev?.[type] ?? []), provider] })); + const onMetadataValueResolved = React.useCallback((provider, uid, type) => { + setMetadataProviderMap((prev) => ({ + ...prev, + [type]: { ...(prev?.[type] ?? {}), [uid]: provider }, + })); }, []); const searchCatalog = React.useCallback( @@ -148,7 +151,9 @@ const CatalogServiceProvider: React.FC = ({ id={extension.uid} useValue={extension.properties.provider} options={defaultOptions} - onValueResolved={(value) => onMetadataValueResolved(value, extension.properties.type)} + onValueResolved={(value, uid) => + onMetadataValueResolved(value, uid, extension.properties.type) + } /> ))} {children(catalogService)} diff --git a/frontend/packages/console-shared/src/components/catalog/utils/__tests__/catalog-utils.spec.tsx b/frontend/packages/console-shared/src/components/catalog/utils/__tests__/catalog-utils.spec.tsx index 49ce1c6a9e5..496459dca00 100644 --- a/frontend/packages/console-shared/src/components/catalog/utils/__tests__/catalog-utils.spec.tsx +++ b/frontend/packages/console-shared/src/components/catalog/utils/__tests__/catalog-utils.spec.tsx @@ -34,10 +34,10 @@ describe('catalog-utils#applyCatalogItemMetadata', () => { }, ]; const metadataProviderMap: { - [type: string]: CatalogItemMetadataProviderFunction[]; + [type: string]: { [id: string]: CatalogItemMetadataProviderFunction }; } = { - type1: [ - () => ({ + type1: { + '@console/dev-console[49]': () => ({ tags: ['foo', 'bar'], attributes: { foo: 'bar', @@ -51,7 +51,7 @@ describe('catalog-utils#applyCatalogItemMetadata', () => { }, ], }), - ], + }, }; const result = applyCatalogItemMetadata(catalogItems, metadataProviderMap); diff --git a/frontend/packages/console-shared/src/components/catalog/utils/catalog-utils.tsx b/frontend/packages/console-shared/src/components/catalog/utils/catalog-utils.tsx index 863e80f3bf7..668087e7e21 100644 --- a/frontend/packages/console-shared/src/components/catalog/utils/catalog-utils.tsx +++ b/frontend/packages/console-shared/src/components/catalog/utils/catalog-utils.tsx @@ -94,11 +94,11 @@ export const customPropertyPresent = ( export const applyCatalogItemMetadata = ( catalogItems: CatalogItem[], metadataProviderMap: { - [type: string]: CatalogItemMetadataProviderFunction[]; + [type: string]: { [id: string]: CatalogItemMetadataProviderFunction }; }, ) => catalogItems.map((item) => { - const metadataProviders = metadataProviderMap[item.type]; + const metadataProviders = Object.values(metadataProviderMap[item.type] ?? {}); if (metadataProviders?.length) { const metadata = metadataProviders .map((metadataProvider) => metadataProvider(item)) diff --git a/frontend/packages/dev-console/console-extensions.json b/frontend/packages/dev-console/console-extensions.json index 1084e446136..6518dec771f 100644 --- a/frontend/packages/dev-console/console-extensions.json +++ b/frontend/packages/dev-console/console-extensions.json @@ -285,7 +285,7 @@ ] }, "flags": { - "required": ["OPENSHIFT"] + "required": ["ALLOW_SERVICE_BINDING"] } }, { @@ -296,7 +296,7 @@ "provider": { "$codeRef": "catalog.bindableItemMetadataProvider" } }, "flags": { - "required": ["OPENSHIFT"] + "required": ["ALLOW_SERVICE_BINDING"] } }, { diff --git a/frontend/packages/dev-console/src/components/catalog/providers/useBindableItemMetadataProvider.ts b/frontend/packages/dev-console/src/components/catalog/providers/useBindableItemMetadataProvider.ts index c28b32f8185..2d733dc93ba 100644 --- a/frontend/packages/dev-console/src/components/catalog/providers/useBindableItemMetadataProvider.ts +++ b/frontend/packages/dev-console/src/components/catalog/providers/useBindableItemMetadataProvider.ts @@ -5,25 +5,18 @@ import { CatalogItemMetadataProviderFunction, ExtensionHook, } from '@console/dynamic-plugin-sdk'; -import { fetchBindableServices } from '../../topology/bindable-services/fetch-bindable-services-utils'; +import { getGroupVersionKindForModel } from '@console/dynamic-plugin-sdk/src/lib-core'; +import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook'; +import { BindableServicesModel } from '../../topology/bindable-services/models'; +import { BindableServiceGVK, BindableServicesKind } from '../../topology/bindable-services/types'; const useBindableItemMetadataProvider: ExtensionHook = () => { - const [bindableServices, setBindableServices] = React.useState([]); - const [loaded, setLoaded] = React.useState(false); - const [error, setError] = React.useState(null); + const [bindableKindsRes, loaded, error] = useK8sWatchResource({ + groupVersionKind: getGroupVersionKindForModel(BindableServicesModel), + name: 'bindable-kinds', + }); - React.useEffect(() => { - fetchBindableServices() - .then((resp) => { - setBindableServices(resp); - setLoaded(true); - }) - .catch((e) => { - setBindableServices([]); - setLoaded(true); - setError(e); - }); - }, []); + const bindableServices: BindableServiceGVK[] = bindableKindsRes?.status ?? []; const [t] = useTranslation();