From 0c4e02ba1401d73d88ee3ca450b110a6c13ada44 Mon Sep 17 00:00:00 2001 From: Hugo Kiyodi Oshiro Date: Tue, 6 Aug 2024 12:16:49 +0200 Subject: [PATCH] Plugins: Add filters by update available (#91526) --- .../features/plugins/admin/pages/Browse.test.tsx | 15 +++++++++++++++ .../app/features/plugins/admin/pages/Browse.tsx | 2 ++ .../plugins/admin/state/selectors.test.ts | 8 ++++++++ .../app/features/plugins/admin/state/selectors.ts | 7 +++++++ 4 files changed, 32 insertions(+) diff --git a/public/app/features/plugins/admin/pages/Browse.test.tsx b/public/app/features/plugins/admin/pages/Browse.test.tsx index 00f0e89f1a4..3cb936fb7c4 100644 --- a/public/app/features/plugins/admin/pages/Browse.test.tsx +++ b/public/app/features/plugins/admin/pages/Browse.test.tsx @@ -94,6 +94,21 @@ describe('Browse list of plugins', () => { expect(queryByText('Plugin 2')).not.toBeInTheDocument(); }); + it('should list plugins with update when filtering by update', async () => { + const { queryByText } = renderBrowse('/plugins?filterBy=has-update', [ + getCatalogPluginMock({ id: 'plugin-1', name: 'Plugin 1', isInstalled: true, hasUpdate: true }), + getCatalogPluginMock({ id: 'plugin-2', name: 'Plugin 2', isInstalled: false }), + getCatalogPluginMock({ id: 'plugin-3', name: 'Plugin 3', isInstalled: true, hasUpdate: true }), + getCatalogPluginMock({ id: 'plugin-4', name: 'Plugin 4', isInstalled: true, isCore: true }), + ]); + + await waitFor(() => expect(queryByText('Plugin 1')).toBeInTheDocument()); + expect(queryByText('Plugin 3')).toBeInTheDocument(); + + expect(queryByText('Plugin 2')).not.toBeInTheDocument(); + expect(queryByText('Plugin 4')).not.toBeInTheDocument(); + }); + it('should list all plugins (including disabled plugins) when filtering by all', async () => { const { queryByText } = renderBrowse('/plugins?filterBy=all&filterByType=all', [ getCatalogPluginMock({ id: 'plugin-1', name: 'Plugin 1', isInstalled: true }), diff --git a/public/app/features/plugins/admin/pages/Browse.tsx b/public/app/features/plugins/admin/pages/Browse.tsx index 4c08f91dde1..0e60bb60003 100644 --- a/public/app/features/plugins/admin/pages/Browse.tsx +++ b/public/app/features/plugins/admin/pages/Browse.tsx @@ -37,6 +37,7 @@ export default function Browse({ route }: GrafanaRouteComponentProps): ReactElem keyword, type: filterByType !== 'all' ? filterByType : undefined, isInstalled: filterBy === 'installed' ? true : undefined, + hasUpdate: filterBy === 'has-update' ? true : undefined, }, sortBy ); @@ -44,6 +45,7 @@ export default function Browse({ route }: GrafanaRouteComponentProps): ReactElem const filterByOptions = [ { value: 'all', label: 'All' }, { value: 'installed', label: 'Installed' }, + { value: 'has-update', label: 'New Updates' }, ]; const onSortByChange = (value: SelectableValue) => { diff --git a/public/app/features/plugins/admin/state/selectors.test.ts b/public/app/features/plugins/admin/state/selectors.test.ts index d10f0611412..68d8ed23153 100644 --- a/public/app/features/plugins/admin/state/selectors.test.ts +++ b/public/app/features/plugins/admin/state/selectors.test.ts @@ -43,6 +43,7 @@ describe('Plugins Selectors', () => { isInstalled: true, type: PluginType.app, isCore: false, + hasUpdate: true, }), ]), }); @@ -81,6 +82,13 @@ describe('Plugins Selectors', () => { expect(results.map(({ name }) => name)).toEqual(['Plugin 4']); }); + it('should be possible to only search for with update', () => { + const results = selectPlugins({ hasUpdate: true })(store.getState()); + + expect(results).toHaveLength(1); + expect(results.map(({ name }) => name)).toEqual(['Plugin 5']); + }); + it('should be possible to search by multiple filters', () => { const results = selectPlugins({ keyword: '2', type: PluginType.datasource })(store.getState()); diff --git a/public/app/features/plugins/admin/state/selectors.ts b/public/app/features/plugins/admin/state/selectors.ts index e56f6057ce2..db0de51035c 100644 --- a/public/app/features/plugins/admin/state/selectors.ts +++ b/public/app/features/plugins/admin/state/selectors.ts @@ -29,6 +29,9 @@ export type PluginFilters = { // (Optional, only applied if set) isEnterprise?: boolean; + + // (Optional, only applied if set) + hasUpdate?: boolean; }; export const selectPlugins = (filters: PluginFilters) => @@ -60,6 +63,10 @@ export const selectPlugins = (filters: PluginFilters) => return false; } + if (filters.hasUpdate !== undefined && plugin.hasUpdate !== filters.hasUpdate) { + return false; + } + return true; }); });