diff --git a/src/web/entities/__tests__/useEntitiesReloadInterval.jsx b/src/web/entities/__tests__/useEntitiesReloadInterval.jsx new file mode 100644 index 0000000000..38ddf1d6d1 --- /dev/null +++ b/src/web/entities/__tests__/useEntitiesReloadInterval.jsx @@ -0,0 +1,99 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +/* eslint-disable react/prop-types */ + +import {describe, test, expect} from '@gsa/testing'; + +import {screen, rendererWith} from 'web/utils/testing'; + +import useEntitiesReloadInterval from '../useEntitiesReloadInterval'; +import {reloadInterval} from 'web/pages/tasks/detailspage'; + +const TestComponent = ({entities, useActive, isVisible = true}) => { + const timeoutFunc = useEntitiesReloadInterval(entities, {useActive}); + return {timeoutFunc({isVisible})}; +}; + +describe('useEntitiesReloadInterval', () => { + test('should return the reload interval', () => { + const entities = [{isActive: () => true}]; + const gmp = {settings: {reloadInterval: 60000}}; + const {render} = rendererWith({gmp}); + + render(); + + expect(screen.getByTestId('timeout')).toHaveTextContent('60000'); + }); + + test('should return the active reload interval', () => { + const entities = [{isActive: () => true}]; + const gmp = { + settings: {reloadInterval: 60000, reloadIntervalActive: 30000}, + }; + const {render} = rendererWith({gmp}); + + render(); + + expect(screen.getByTestId('timeout')).toHaveTextContent('30000'); + }); + + test('should return the reload interval when all entities are inactive', () => { + const entities = [{isActive: () => false}]; + const gmp = { + settings: {reloadInterval: 60000, reloadIntervalActive: 30000}, + }; + const {render} = rendererWith({gmp}); + + render(); + + expect(screen.getByTestId('timeout')).toHaveTextContent('60000'); + }); + + test('should return the active reload interval if at least one entity is active', () => { + const entities = [{isActive: () => false}, {isActive: () => true}]; + const gmp = { + settings: {reloadInterval: 60000, reloadIntervalActive: 30000}, + }; + const {render} = rendererWith({gmp}); + + render(); + + expect(screen.getByTestId('timeout')).toHaveTextContent('30000'); + }); + + test('should return the reload interval if not entity is available', () => { + const entities = []; + const gmp = { + settings: { + reloadInterval: 60000, + reloadIntervalActive: 30000, + }, + }; + const {render} = rendererWith({gmp}); + + render(); + + expect(screen.getByTestId('timeout')).toHaveTextContent('60000'); + }); + + test('should return the inactive reload interval if not visible', () => { + const entities = [{isActive: () => false}, {isActive: () => true}]; + const gmp = { + settings: { + reloadInterval: 60000, + reloadIntervalActive: 30000, + reloadIntervalInactive: 40000, + }, + }; + const {render} = rendererWith({gmp}); + + render( + , + ); + + expect(screen.getByTestId('timeout')).toHaveTextContent('40000'); + }); +}); diff --git a/src/web/entities/useEntitiesReloadInterval.js b/src/web/entities/useEntitiesReloadInterval.js new file mode 100644 index 0000000000..d834d536d3 --- /dev/null +++ b/src/web/entities/useEntitiesReloadInterval.js @@ -0,0 +1,52 @@ +/* SPDX-FileCopyrightText: 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import {useCallback} from 'react'; + +import {isDefined} from 'gmp/utils/identity'; + +import useGmp from 'web/utils/useGmp'; + +/** + * Hook to get the reload interval for entities + * + * Can be best used in conjunction with useReload + * + * @example + * const entities = [entity1, entity2]; + * const timeoutFunc = useEntitiesReloadInterval(entities); + * const [startTimer, clearTimer, isRunning] = useReload(reloadFunc, timeoutFunc); + * + * @param {Array} entities Optional array of entities to consider + * @param {Object} options Set useActive to true to consider the active state + * of the entities for the reload interval. If at least one entity is active + * the reload interval will be the active interval (shorter). If no entity is + * active the normal interval will be used. Default is false. + * @returns Function A timeout function that calculates the reload interval + */ +const useEntitiesReloadInterval = (entities, {useActive = false} = {}) => { + const gmp = useGmp(); + const gmpSettings = gmp.settings; + const timeoutFunc = useCallback( + ({isVisible}) => { + if (!isVisible) { + return gmpSettings.reloadIntervalInactive; + } + if ( + useActive && + isDefined(entities) && + entities.some(entity => entity.isActive()) + ) { + return gmpSettings.reloadIntervalActive; + } + return gmpSettings.reloadInterval; + }, + [entities, gmpSettings, useActive], + ); + + return timeoutFunc; +}; + +export default useEntitiesReloadInterval;