diff --git a/gsa/CMakeLists.txt b/gsa/CMakeLists.txt index c155353c14..663f9ba337 100644 --- a/gsa/CMakeLists.txt +++ b/gsa/CMakeLists.txt @@ -823,6 +823,7 @@ set (GSA_JS_SRC_FILES ${GSA_SRC_DIR}/src/web/authorized.js ${GSA_SRC_DIR}/src/web/utils/cert.js ${GSA_SRC_DIR}/src/web/utils/compose.js + ${GSA_SRC_DIR}/src/web/utils/constants.js ${GSA_SRC_DIR}/src/web/utils/cpe.js ${GSA_SRC_DIR}/src/web/utils/globalcss.js ${GSA_SRC_DIR}/src/web/utils/os.js diff --git a/gsa/public/config.js b/gsa/public/config.js index 40c89b1c27..ec60ca2ff7 100644 --- a/gsa/public/config.js +++ b/gsa/public/config.js @@ -1,8 +1,5 @@ -const FIVE_SECONDS = 5; - config = { loglevel: 'warn', - autorefresh: FIVE_SECONDS, manualurl: 'http://docs.greenbone.net/GSM-Manual/gos-4/', protocoldocurl: 'http://docs.greenbone.net/API/OMP/omp-7.0.html', }; diff --git a/gsa/src/gmp/__tests__/gmpsettings.js b/gsa/src/gmp/__tests__/gmpsettings.js index 6ec0281747..27367edaa5 100644 --- a/gsa/src/gmp/__tests__/gmpsettings.js +++ b/gsa/src/gmp/__tests__/gmpsettings.js @@ -36,7 +36,7 @@ describe('GmpSettings tests', () => { test('should init with passed options', () => { const storage = createStorage(); const settings = new GmpSettings(storage, { - autorefresh: 10, + reloadinterval: 10, locale: 'en', manualurl: 'http://manual', protocol: 'http', @@ -48,7 +48,7 @@ describe('GmpSettings tests', () => { username: 'foo', }); - expect(settings.autorefresh).toEqual(10); + expect(settings.reloadinterval).toEqual(10); expect(settings.locale).toEqual('en'); expect(settings.manualurl).toEqual('http://manual'); expect(settings.protocol).toEqual('http'); @@ -81,7 +81,7 @@ describe('GmpSettings tests', () => { protocol: 'http', }); - expect(settings.autorefresh).toBeUndefined(); + expect(settings.reloadinterval).toEqual(15000); expect(settings.locale).toEqual('en'); expect(settings.manualurl).toBeUndefined(); expect(settings.protocol).toEqual('http'); @@ -101,7 +101,7 @@ describe('GmpSettings tests', () => { test('should ensure options override settings from storage', () => { const storage = createStorage({ - autorefresh: 20, + reloadinterval: 20, locale: 'de', manualurl: 'http://ipsum', protocol: 'https', @@ -114,7 +114,7 @@ describe('GmpSettings tests', () => { }); const settings = new GmpSettings(storage, { - autorefresh: 10, + reloadinterval: 10, locale: 'en', manualurl: 'http://manual', protocol: 'http', @@ -126,7 +126,7 @@ describe('GmpSettings tests', () => { username: 'foo', }); - expect(settings.autorefresh).toEqual(10); + expect(settings.reloadinterval).toEqual(10); expect(settings.locale).toEqual('en'); expect(settings.manualurl).toEqual('http://manual'); expect(settings.protocol).toEqual('http'); diff --git a/gsa/src/gmp/gmp.js b/gsa/src/gmp/gmp.js index 11c0cfb210..3249cff6cc 100644 --- a/gsa/src/gmp/gmp.js +++ b/gsa/src/gmp/gmp.js @@ -84,7 +84,7 @@ class Gmp { constructor(options = {}) { const { - autorefresh, + reloadinterval, protocol, server, storage, @@ -96,7 +96,7 @@ class Gmp { log.debug('Using gmp options', options); this.settings = new GmpSettings(storage, { - autorefresh, + reloadinterval, manualurl, protocol, protocoldocurl, @@ -218,8 +218,8 @@ class Gmp { return this; } - get autorefresh() { - return this.settings.autorefresh; + get reloadInterval() { + return this.settings.reloadinterval; } addHttpErrorHandler(handler) { diff --git a/gsa/src/gmp/gmpsettings.js b/gsa/src/gmp/gmpsettings.js index 73acd9ef72..037126c1af 100644 --- a/gsa/src/gmp/gmpsettings.js +++ b/gsa/src/gmp/gmpsettings.js @@ -22,6 +22,8 @@ */ import {isDefined} from './utils/identity'; +const DEFAULT_RELOAD_INTERVAL = 15 * 1000; // fifteen seconds + const set = (storage, name, value) => { if (isDefined(value)) { storage.setItem(name, value); @@ -34,7 +36,7 @@ const set = (storage, name, value) => { class GmpSettings { constructor(storage = global.localStorage, options = {}) { const { - autorefresh, + reloadinterval = DEFAULT_RELOAD_INTERVAL, locale, manualurl, protocol = global.location.protocol, @@ -47,7 +49,7 @@ class GmpSettings { } = {...storage, ...options}; this.storage = storage; - this.autorefresh = autorefresh; + this.reloadinterval = reloadinterval; this.locale = locale; this.manualurl = manualurl; this.protocol = protocol; diff --git a/gsa/src/web/entities/container.js b/gsa/src/web/entities/container.js index 8adee33c50..f982c0bf0d 100644 --- a/gsa/src/web/entities/container.js +++ b/gsa/src/web/entities/container.js @@ -60,6 +60,8 @@ const exclude_props = [ 'onDownload', ]; +const LOAD_TIME_FACTOR = 1.2; + class EntitiesContainer extends React.Component { constructor(...args) { @@ -131,8 +133,11 @@ class EntitiesContainer extends React.Component { }; componentDidMount() { + this.isRunning = true; const {filter} = this.props.location.query; + this.startMeasurement(); + if (isDefined(filter)) { // use filter from url this.load(Filter.fromString(filter)); @@ -144,6 +149,7 @@ class EntitiesContainer extends React.Component { } componentWillUnmount() { + this.isRunning = false; this.clearTimer(); // remove possible running timer } @@ -170,23 +176,57 @@ class EntitiesContainer extends React.Component { this.load(this.props.filter); } - getRefreshInterval() { - const {gmp} = this.props; - return gmp.autorefresh * 1000; + startMeasurement() { + this.startTimeStamp = performance.now(); + } + + endMeasurement() { + if (!isDefined(this.startTimeStamp)) { + return 0; + } + + const duration = performance.now() - this.startTimeStamp; + this.startTimeStamp = undefined; + return duration; + } + + getReloadInterval() { + const { + defaultReloadInterval, + reloadInterval, + } = this.props; + + return isDefined(reloadInterval) ? reloadInterval(this.props) : + defaultReloadInterval; } startTimer() { - const refresh = this.getRefreshInterval(); - if (refresh > 0) { - this.timer = global.setTimeout(this.handleTimer, refresh); + if (!this.isRunning) { + return; + } + + const loadTime = this.endMeasurement(); + + log.debug('Loading time was', loadTime, 'milliseconds'); + + let interval = this.getReloadInterval(); + + if (loadTime > interval) { + // ensure timer is longer then the loading procedure + interval = loadTime * LOAD_TIME_FACTOR; + } + + if (interval > 0) { + this.timer = global.setTimeout(this.handleTimer, interval); log.debug('Started reload timer with id', this.timer, 'and interval of', - refresh, 'milliseconds'); + interval, 'milliseconds for', this.props.gmpname); } } clearTimer() { if (isDefined(this.timer)) { - log.debug('Clearing reload timer with id', this.timer); + log.debug('Clearing reload timer with id', this.timer, 'for', + this.props.gmpname); global.clearTimeout(this.timer); } } @@ -195,13 +235,18 @@ class EntitiesContainer extends React.Component { log.debug('Timer', this.timer, 'finished. Reloading data.'); this.timer = undefined; - this.reload(); + + this.startMeasurement(); + this.notifyTimer(); + this.reload(); } handleChanged() { - this.reload(); + this.startMeasurement(); + this.notifyChanged(); + this.reload(); } handleSelectionTypeChange(selectionType) { @@ -273,8 +318,8 @@ class EntitiesContainer extends React.Component { this.handleInteraction(); promise.then(deleted => { - this.reload(); log.debug('successfully deleted entities', deleted); + this.handleChanged(); }, this.handleError); } @@ -641,6 +686,7 @@ class EntitiesContainer extends React.Component { EntitiesContainer.propTypes = { children: PropTypes.func.isRequired, + defaultReloadInterval: PropTypes.number.isRequired, entities: PropTypes.array, entitiesCounts: PropTypes.counts, extraLoadParams: PropTypes.object, @@ -652,6 +698,7 @@ EntitiesContainer.propTypes = { loadEntities: PropTypes.func.isRequired, loadedFilter: PropTypes.filter, notify: PropTypes.func.isRequired, + reloadInterval: PropTypes.func, showError: PropTypes.func.isRequired, showErrorMessage: PropTypes.func.isRequired, showSuccessMessage: PropTypes.func.isRequired, diff --git a/gsa/src/web/entities/withEntitiesContainer.js b/gsa/src/web/entities/withEntitiesContainer.js index 087ecf8364..1dcdb2695d 100644 --- a/gsa/src/web/entities/withEntitiesContainer.js +++ b/gsa/src/web/entities/withEntitiesContainer.js @@ -42,6 +42,7 @@ import EntitiesContainer from './container'; const withEntitiesContainer = (gmpname, { entitiesSelector, loadEntities, + reloadInterval, }) => Component => { let EntitiesContainerWrapper = props => ( @@ -50,6 +51,7 @@ const withEntitiesContainer = (gmpname, { {...props} notify={notify} gmpname={gmpname} + reloadInterval={reloadInterval} > {pageProps => ( ); - const mapStateToProps = (state, props) => { + const mapStateToProps = (state, {gmp}) => { const eSelector = entitiesSelector(state); const pSelector = getPage(state); const filter = pSelector.getFilter(gmpname); const entities = eSelector.getEntities(filter); return { + defaultReloadInterval: gmp.reloadInterval, entities, entitiesCounts: eSelector.getEntitiesCounts(filter), filter, diff --git a/gsa/src/web/entity/container.js b/gsa/src/web/entity/container.js index 77feb8af3b..9945f034c0 100644 --- a/gsa/src/web/entity/container.js +++ b/gsa/src/web/entity/container.js @@ -46,10 +46,18 @@ class EntityContainer extends React.Component { } componentDidMount() { + this.isRunning = true; + const {id} = this.props; this.load(id); } + componentWillUnmount() { + this.isRunning = false; + + this.clearTimer(); + } + componentDidUpdate() { const {id} = this.props; if (id !== this.state.id) { @@ -58,8 +66,11 @@ class EntityContainer extends React.Component { } load(id) { - this.props.load(id); + this.clearTimer(); + this.setState({id}); + + this.props.load(id).then(() => this.startTimer()); } reload() { @@ -71,18 +82,27 @@ class EntityContainer extends React.Component { this.reload(); } - getRefreshInterval() { - const {gmp} = this.props; - return gmp.autorefresh * 1000; + getReloadInterval() { + const { + defaultReloadInterval, + reloadInterval, + } = this.props; + + return isDefined(reloadInterval) ? reloadInterval(this.props) : + defaultReloadInterval; } - startTimer(immediate = false) { - const refresh = immediate ? 0 : this.getRefreshInterval(); + startTimer() { + if (!this.isRunning) { + return; + } + + const interval = this.getReloadInterval(); - if (refresh >= 0) { - this.timer = window.setTimeout(this.handleTimer, refresh); + if (interval > 0) { + this.timer = global.setTimeout(this.handleTimer, interval); log.debug('Started reload timer with id', this.timer, 'and interval of', - refresh, 'milliseconds'); + interval, 'milliseconds'); } } @@ -123,10 +143,12 @@ class EntityContainer extends React.Component { EntityContainer.propTypes = { children: PropTypes.func.isRequired, + defaultReloadInterval: PropTypes.number.isRequired, entityType: PropTypes.string.isRequired, gmp: PropTypes.gmp.isRequired, id: PropTypes.id.isRequired, load: PropTypes.func.isRequired, + reloadInterval: PropTypes.func, showError: PropTypes.func.isRequired, showSuccessMessage: PropTypes.func.isRequired, onDownload: PropTypes.func.isRequired, diff --git a/gsa/src/web/entity/withEntityContainer.js b/gsa/src/web/entity/withEntityContainer.js index dc2f4da59f..ab4930b0b3 100644 --- a/gsa/src/web/entity/withEntityContainer.js +++ b/gsa/src/web/entity/withEntityContainer.js @@ -55,12 +55,14 @@ const withEntityContainer = (entityType, { load, entitySelector, mapStateToProps: componentMapStateToProps, + reloadInterval, }) => Component => { const EntityContainerWrapper = ({id, ...props}) => ( {cprops => } @@ -86,6 +88,7 @@ const withEntityContainer = (entityType, { }) : undefined; return { isLoading: entitySel.isLoadingEntity(id), + defaultReloadInterval: gmp.reloadInterval, ...otherProps, id, entity: entitySel.getEntity(id), diff --git a/gsa/src/web/pages/agents/detailspage.js b/gsa/src/web/pages/agents/detailspage.js index e2ab0d0d1d..527ce46904 100644 --- a/gsa/src/web/pages/agents/detailspage.js +++ b/gsa/src/web/pages/agents/detailspage.js @@ -266,10 +266,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/alerts/detailspage.js b/gsa/src/web/pages/alerts/detailspage.js index 1df7dfd7ee..893097cd20 100644 --- a/gsa/src/web/pages/alerts/detailspage.js +++ b/gsa/src/web/pages/alerts/detailspage.js @@ -239,10 +239,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/assets/dashboard.js b/gsa/src/web/pages/assets/dashboard.js index 38a50b8c57..6ba0c541e6 100644 --- a/gsa/src/web/pages/assets/dashboard.js +++ b/gsa/src/web/pages/assets/dashboard.js @@ -64,17 +64,17 @@ class AssetsDashboard extends React.Component { this.clearTimer(); } - getRefreshInterval() { + getReloadInterval() { const {gmp} = this.props; - return gmp.autorefresh * 1000; + return gmp.reloadInterval; } startTimer() { - const refresh = this.getRefreshInterval(); - if (refresh >= 0) { - this.timer = window.setTimeout(this.handleTimer, refresh); + const interval = this.getReloadInterval(); + if (interval > 0) { + this.timer = window.setTimeout(this.handleTimer, interval); log.debug('Started reload timer with id', this.timer, 'and interval of', - refresh, 'milliseconds'); + interval, 'milliseconds'); } } diff --git a/gsa/src/web/pages/credentials/detailspage.js b/gsa/src/web/pages/credentials/detailspage.js index 4ad430cd0e..2305b4d8e5 100644 --- a/gsa/src/web/pages/credentials/detailspage.js +++ b/gsa/src/web/pages/credentials/detailspage.js @@ -350,10 +350,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/filters/detailspage.js b/gsa/src/web/pages/filters/detailspage.js index f5d703a868..194469e336 100644 --- a/gsa/src/web/pages/filters/detailspage.js +++ b/gsa/src/web/pages/filters/detailspage.js @@ -242,10 +242,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/groups/detailspage.js b/gsa/src/web/pages/groups/detailspage.js index a83e5b1c1f..52b5526fa9 100644 --- a/gsa/src/web/pages/groups/detailspage.js +++ b/gsa/src/web/pages/groups/detailspage.js @@ -240,10 +240,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/hosts/detailspage.js b/gsa/src/web/pages/hosts/detailspage.js index b32d184990..2ec8dfbbe2 100644 --- a/gsa/src/web/pages/hosts/detailspage.js +++ b/gsa/src/web/pages/hosts/detailspage.js @@ -412,10 +412,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/notes/detailspage.js b/gsa/src/web/pages/notes/detailspage.js index d0032ba657..ef28112dc9 100644 --- a/gsa/src/web/pages/notes/detailspage.js +++ b/gsa/src/web/pages/notes/detailspage.js @@ -317,10 +317,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/nvts/detailspage.js b/gsa/src/web/pages/nvts/detailspage.js index f489c892ea..aaac128256 100644 --- a/gsa/src/web/pages/nvts/detailspage.js +++ b/gsa/src/web/pages/nvts/detailspage.js @@ -353,11 +353,11 @@ const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadNotesFunc = loadNotes(gmp); const loadOverridesFunc = loadOverrides(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadNotesFunc(nvtIdFilter(id))); - dispatch(loadOverridesFunc(nvtIdFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadNotesFunc(nvtIdFilter(id))), + dispatch(loadOverridesFunc(nvtIdFilter(id))), + ]); }; export default withEntityContainer('task', { diff --git a/gsa/src/web/pages/operatingsystems/detailspage.js b/gsa/src/web/pages/operatingsystems/detailspage.js index 0c49117c56..64b064e974 100644 --- a/gsa/src/web/pages/operatingsystems/detailspage.js +++ b/gsa/src/web/pages/operatingsystems/detailspage.js @@ -318,10 +318,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/overrides/detailspage.js b/gsa/src/web/pages/overrides/detailspage.js index 23b331b1c4..8c467ff375 100644 --- a/gsa/src/web/pages/overrides/detailspage.js +++ b/gsa/src/web/pages/overrides/detailspage.js @@ -317,10 +317,10 @@ Page.propTypes = { const load = gmp => { const loadOverride = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadOverride(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadOverride(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/portlists/detailspage.js b/gsa/src/web/pages/portlists/detailspage.js index 17a757246d..153586b3c1 100644 --- a/gsa/src/web/pages/portlists/detailspage.js +++ b/gsa/src/web/pages/portlists/detailspage.js @@ -298,10 +298,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/reportformats/detailspage.js b/gsa/src/web/pages/reportformats/detailspage.js index 2141b6f1ca..32d3889452 100644 --- a/gsa/src/web/pages/reportformats/detailspage.js +++ b/gsa/src/web/pages/reportformats/detailspage.js @@ -345,10 +345,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/reports/detailspage.js b/gsa/src/web/pages/reports/detailspage.js index 88b543e275..d465bd6be1 100644 --- a/gsa/src/web/pages/reports/detailspage.js +++ b/gsa/src/web/pages/reports/detailspage.js @@ -285,7 +285,7 @@ class ReportDetails extends React.Component { getRefreshInterval() { const {gmp} = this.props; - return gmp.autorefresh * 1000; + return gmp.reloadInterval; } startTimer(immediate = false) { diff --git a/gsa/src/web/pages/reports/listpage.js b/gsa/src/web/pages/reports/listpage.js index 6677a02065..b3724bd1dd 100644 --- a/gsa/src/web/pages/reports/listpage.js +++ b/gsa/src/web/pages/reports/listpage.js @@ -28,13 +28,11 @@ import _ from 'gmp/locale'; import Filter, {REPORTS_FILTER_FILTER} from 'gmp/models/filter'; +import {isActive} from 'gmp/models/task'; + import {isDefined} from 'gmp/utils/identity'; import {selectSaveId} from 'gmp/utils/id'; -import compose from 'web/utils/compose'; -import PropTypes from 'web/utils/proptypes'; -import withGmp from 'web/utils/withGmp'; - import EntitiesPage from 'web/entities/page'; import withEntitiesContainer from 'web/entities/withEntitiesContainer'; @@ -52,6 +50,11 @@ import { selector as entitiesSelector, } from 'web/store/entities/reports'; +import {DEFAULT_RELOAD_INTERVAL_ACTIVE} from 'web/utils/constants'; +import compose from 'web/utils/compose'; +import PropTypes from 'web/utils/proptypes'; +import withGmp from 'web/utils/withGmp'; + import ReportFilterDialog from './filterdialog'; import ImportReportDialog from './importdialog'; import ReportsTable from './table'; @@ -267,11 +270,19 @@ Page.propTypes = { onInteraction: PropTypes.func.isRequired, }; +const reportsReloadInterval = ({ + entities = [], + defaultReloadInterval, +}) => entities.some(entity => isActive(entity.report.scan_run_status)) ? + DEFAULT_RELOAD_INTERVAL_ACTIVE : + defaultReloadInterval; + export default compose( withGmp, withEntitiesContainer('report', { entitiesSelector, loadEntities, + reloadInterval: reportsReloadInterval, }), )(Page); diff --git a/gsa/src/web/pages/roles/detailspage.js b/gsa/src/web/pages/roles/detailspage.js index 2e6f03f291..105c8b6f33 100644 --- a/gsa/src/web/pages/roles/detailspage.js +++ b/gsa/src/web/pages/roles/detailspage.js @@ -336,11 +336,11 @@ const generalPermissionsFilter = id => const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))); - dispatch(loadPermissionsFunc(generalPermissionsFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))), + dispatch(loadPermissionsFunc(generalPermissionsFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/scanconfigs/detailspage.js b/gsa/src/web/pages/scanconfigs/detailspage.js index bacf33a726..c62113f557 100644 --- a/gsa/src/web/pages/scanconfigs/detailspage.js +++ b/gsa/src/web/pages/scanconfigs/detailspage.js @@ -482,10 +482,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/scanners/detailspage.js b/gsa/src/web/pages/scanners/detailspage.js index a8e47af215..59a34e77e9 100644 --- a/gsa/src/web/pages/scanners/detailspage.js +++ b/gsa/src/web/pages/scanners/detailspage.js @@ -290,10 +290,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/scans/dashboard.js b/gsa/src/web/pages/scans/dashboard.js index bfa0210037..33daead37f 100644 --- a/gsa/src/web/pages/scans/dashboard.js +++ b/gsa/src/web/pages/scans/dashboard.js @@ -80,17 +80,17 @@ class ScansDashboard extends React.Component { this.clearTimer(); } - getRefreshInterval() { + getReloadInterval() { const {gmp} = this.props; - return gmp.autorefresh * 1000; + return gmp.reloadInterval; } startTimer() { - const refresh = this.getRefreshInterval(); - if (refresh >= 0) { - this.timer = window.setTimeout(this.handleTimer, refresh); + const interval = this.getReloadInterval(); + if (interval > 0) { + this.timer = window.setTimeout(this.handleTimer, interval); log.debug('Started reload timer with id', this.timer, 'and interval of', - refresh, 'milliseconds'); + interval, 'milliseconds'); } } diff --git a/gsa/src/web/pages/schedules/detailspage.js b/gsa/src/web/pages/schedules/detailspage.js index 77925fbdf1..29cf786aee 100644 --- a/gsa/src/web/pages/schedules/detailspage.js +++ b/gsa/src/web/pages/schedules/detailspage.js @@ -240,10 +240,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/securityinfo/dashboard.js b/gsa/src/web/pages/securityinfo/dashboard.js index 5c94717378..ba6e1e361c 100644 --- a/gsa/src/web/pages/securityinfo/dashboard.js +++ b/gsa/src/web/pages/securityinfo/dashboard.js @@ -68,17 +68,17 @@ class SecurityInfoDashboard extends React.Component { this.clearTimer(); } - getRefreshInterval() { + getReloadInterval() { const {gmp} = this.props; - return gmp.autorefresh * 1000; + return gmp.reloadInterval; } startTimer() { - const refresh = this.getRefreshInterval(); - if (refresh >= 0) { - this.timer = window.setTimeout(this.handleTimer, refresh); + const interval = this.getReloadInterval(); + if (interval >= 0) { + this.timer = window.setTimeout(this.handleTimer, interval); log.debug('Started reload timer with id', this.timer, 'and interval of', - refresh, 'milliseconds'); + interval, 'milliseconds'); } } diff --git a/gsa/src/web/pages/tags/detailspage.js b/gsa/src/web/pages/tags/detailspage.js index 052e2ced15..1b6117091c 100644 --- a/gsa/src/web/pages/tags/detailspage.js +++ b/gsa/src/web/pages/tags/detailspage.js @@ -282,10 +282,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/targets/detailspage.js b/gsa/src/web/pages/targets/detailspage.js index ca842d2761..d7c577e57f 100644 --- a/gsa/src/web/pages/targets/detailspage.js +++ b/gsa/src/web/pages/targets/detailspage.js @@ -307,10 +307,10 @@ const TargetPermissions = withComponentDefaults({ const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/pages/tasks/detailspage.js b/gsa/src/web/pages/tasks/detailspage.js index d417aab921..9c419b97a6 100644 --- a/gsa/src/web/pages/tasks/detailspage.js +++ b/gsa/src/web/pages/tasks/detailspage.js @@ -89,6 +89,7 @@ import { loadEntity as loadTask, } from 'web/store/entities/tasks'; +import {DEFAULT_RELOAD_INTERVAL_ACTIVE} from 'web/utils/constants'; import PropTypes from 'web/utils/proptypes'; import {renderYesNo} from 'web/utils/render'; import withComponentDefaults from 'web/utils/withComponentDefaults'; @@ -559,18 +560,21 @@ const load = gmp => { const loadPermissionsFunc = loadPermissions(gmp); const loadNotesFunc = loadNotes(gmp); const loadOverridesFunc = loadOverrides(gmp); - return id => dispatch => { - dispatch(loadTaskFunc(id)); - dispatch(loadPermissionsFunc(permissionsResourceFilter(id))); - dispatch(loadNotesFunc(taskIdFilter(id))); - dispatch(loadOverridesFunc(taskIdFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadTaskFunc(id)), + dispatch(loadPermissionsFunc(permissionsResourceFilter(id))), + dispatch(loadNotesFunc(taskIdFilter(id))), + dispatch(loadOverridesFunc(taskIdFilter(id))), + ]); }; export default withEntityContainer('task', { load, entitySelector: taskSelector, mapStateToProps, + reloadInterval: ({defaultReloadInterval, entity}) => entity.isActive() ? + DEFAULT_RELOAD_INTERVAL_ACTIVE : + defaultReloadInterval, })(Page); // vim: set ts=2 sw=2 tw=80: diff --git a/gsa/src/web/pages/tasks/listpage.js b/gsa/src/web/pages/tasks/listpage.js index 52a4cdaf65..a7c2d8991a 100644 --- a/gsa/src/web/pages/tasks/listpage.js +++ b/gsa/src/web/pages/tasks/listpage.js @@ -46,6 +46,8 @@ import IconDivider from 'web/components/layout/icondivider'; import IconMenu from 'web/components/menu/iconmenu'; import MenuEntry from 'web/components/menu/menuentry'; +import {DEFAULT_RELOAD_INTERVAL_ACTIVE} from 'web/utils/constants'; + import NewIconMenu from './icons/newiconmenu'; import TaskComponent from './component'; @@ -208,9 +210,17 @@ Page.propTypes = { onInteraction: PropTypes.func.isRequired, }; +const taskReloadInterval = ({ + entities = [], + defaultReloadInterval, +}) => entities.some(task => task.isActive()) ? + DEFAULT_RELOAD_INTERVAL_ACTIVE : + defaultReloadInterval; + export default withEntitiesContainer('task', { entitiesSelector, loadEntities, + reloadInterval: taskReloadInterval, })(Page); // vim: set ts=2 sw=2 tw=80: diff --git a/gsa/src/web/pages/users/detailspage.js b/gsa/src/web/pages/users/detailspage.js index eb4a72826a..09bbae7d6f 100644 --- a/gsa/src/web/pages/users/detailspage.js +++ b/gsa/src/web/pages/users/detailspage.js @@ -240,10 +240,10 @@ Page.propTypes = { const load = gmp => { const loadEntityFunc = loadEntity(gmp); const loadPermissionsFunc = loadPermissions(gmp); - return id => dispatch => { - dispatch(loadEntityFunc(id)); - dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))); - }; + return id => dispatch => Promise.all([ + dispatch(loadEntityFunc(id)), + dispatch(loadPermissionsFunc(permissionsSubjectFilter(id))), + ]); }; const mapStateToProps = (rootState, {id}) => { diff --git a/gsa/src/web/utils/constants.js b/gsa/src/web/utils/constants.js new file mode 100644 index 0000000000..9d213d254c --- /dev/null +++ b/gsa/src/web/utils/constants.js @@ -0,0 +1,25 @@ +/* Greenbone Security Assistant + * + * Authors: + * Björn Ricks + * + * Copyright: + * Copyright (C) 2018 Greenbone Networks GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +export const DEFAULT_RELOAD_INTERVAL_ACTIVE = 3 * 1000; // three seconds + +// vim: set ts=2 sw=2 tw=80: