diff --git a/lib/public/views/Environments/ActiveColumns/environmentsActiveColumns.js b/lib/public/views/Environments/ActiveColumns/environmentsActiveColumns.js index 5e2b185f29..d392ffb53a 100644 --- a/lib/public/views/Environments/ActiveColumns/environmentsActiveColumns.js +++ b/lib/public/views/Environments/ActiveColumns/environmentsActiveColumns.js @@ -24,6 +24,7 @@ import { environmentStatusHistoryLegendComponent } from '../../../components/env import { infoTooltip } from '../../../components/common/popover/infoTooltip.js'; import { aliEcsEnvironmentLinkComponent } from '../../../components/common/externalLinks/aliEcsEnvironmentLinkComponent.js'; import { StatusAcronym } from '../../../domain/enums/statusAcronym.mjs'; +import { timeRangeFilter } from '../../../components/Filters/common/filters/timeRangeFilter.js'; import { checkboxes } from '../../../components/Filters/common/filters/checkboxFilter.js'; import { rawTextFilter } from '../../../components/Filters/common/filters/rawTextFilter.js'; @@ -95,10 +96,18 @@ export const environmentsActiveColumns = { }, createdAt: { name: 'Created At', - visible: false, + visible: true, sortable: false, size: 'w-10', format: (timestamp) => formatTimestamp(timestamp, false), + + /** + * CreatedAt filter component + * + * @param {EnvironmentOverviewModel} environmentOverviewModel the environment overview model + * @return {Component} the filter component + */ + filter: (environmentOverviewModel) => timeRangeFilter(environmentOverviewModel.filteringModel.get('created')), }, status: { name: 'Current Status', diff --git a/lib/public/views/Environments/Overview/EnvironmentOverviewModel.js b/lib/public/views/Environments/Overview/EnvironmentOverviewModel.js index 834313ea2c..8498a02d79 100644 --- a/lib/public/views/Environments/Overview/EnvironmentOverviewModel.js +++ b/lib/public/views/Environments/Overview/EnvironmentOverviewModel.js @@ -14,6 +14,7 @@ import { buildUrl } from '/js/src/index.js'; import { FilteringModel } from '../../../components/Filters/common/FilteringModel.js'; import { OverviewPageModel } from '../../../models/OverviewModel.js'; +import { TimeRangeInputModel } from '../../../components/Filters/common/filters/TimeRangeInputModel.js'; import { SelectionFilterModel } from '../../../components/Filters/common/filters/SelectionFilterModel.js'; import { RawTextFilterModel } from '../../../components/Filters/common/filters/RawTextFilterModel.js'; import { debounce } from '../../../utilities/debounce.js'; @@ -32,6 +33,7 @@ export class EnvironmentOverviewModel extends OverviewPageModel { super(); this._filteringModel = new FilteringModel({ + created: new TimeRangeInputModel(), runNumbers: new RawTextFilterModel(), statusHistory: new RawTextFilterModel(), currentStatus: new SelectionFilterModel({ diff --git a/test/public/envs/overview.test.js b/test/public/envs/overview.test.js index b56499de1d..1b9fa872c6 100644 --- a/test/public/envs/overview.test.js +++ b/test/public/envs/overview.test.js @@ -27,6 +27,7 @@ const { goToPage, openFilteringPanel, fillInput, + getPeriodInputsSelectors, expectAttributeValue, resetFilters, } = require('../defaults.js'); @@ -87,7 +88,7 @@ module.exports = () => { it('Should have balloon on runs column', async () => { await checkColumnBalloon(page, 1, 2); - await checkColumnBalloon(page, 1, 5); + await checkColumnBalloon(page, 1, 6); }); it('Should have correct status color in the overview page', async () => { @@ -135,11 +136,11 @@ module.exports = () => { }; - await checkEnvironmentStatusColor(1, 3); - await checkEnvironmentStatusColor(2, 3); - await checkEnvironmentStatusColor(3, 3); - await checkEnvironmentStatusColor(6, 3); - await checkEnvironmentStatusColor(9, 3); + await checkEnvironmentStatusColor(1, 4); + await checkEnvironmentStatusColor(2, 4); + await checkEnvironmentStatusColor(3, 4); + await checkEnvironmentStatusColor(6, 4); + await checkEnvironmentStatusColor(9, 4); }); it('can set how many environments are available per page', async () => { @@ -403,4 +404,53 @@ module.exports = () => { await filterOnID('.id-filter input', 'j', ['CmCvjNbg', 'GIDO1jdkD', '8E4aZTjY', 'Dxi029djX']); await resetFilters(page); }); + + it('should successfully filter environments by their createdAt date', async () => { + /** + * This is the sequence to test filtering the environments based on their createdAt date + * + * @param {string} selector the filter input selector + * @param {string} fromDate the from date string + * @param {string} fromTime the from time string + * @param {string} toDate the to date string + * @param {string} toTime the to time string + * @param {string[]} expectedIds the list of expected environment IDs after filtering + * @return {void} + */ + const filterOnCreatedAt = async (selector, fromDate, fromTime, toDate, toTime, expectedIds) => { + await fillInput(page, selector.fromTimeSelector, fromTime, ['change']); + await fillInput(page, selector.toTimeSelector, toTime, ['change']); + + await fillInput(page, selector.fromDateSelector, fromDate, ['change']); + await fillInput(page, selector.toDateSelector, toDate, ['change']); + + await waitForTableLength(page, expectedIds.length); + expect(await page.$$eval('tbody tr', (rows) => rows.map((row) => row.id))).to.eql(expectedIds.map(id => `row${id}`)); + }; + + await openFilteringPanel(page); + + const createdAtPopoverSelector = await getPopoverSelector(await page.$('.createdAt-filter .popover-trigger')); + const periodInputsSelectors = getPeriodInputsSelectors(createdAtPopoverSelector); + + await filterOnCreatedAt( + periodInputsSelectors, + '2019-05-08', + '00:00', + '2019-05-10', + '00:00', + ['eZF99lH6'], + ); + await resetFilters(page); + + await filterOnCreatedAt( + periodInputsSelectors, + '2019-08-09', + '00:00', + '2019-08-09', + '14:00', + ['GIDO1jdkD', '8E4aZTjY', 'Dxi029djX'], + ); + await resetFilters(page); + }); };