Skip to content

Commit 71a7c30

Browse files
committed
[O2B-1491] Add current status filtering for environments
Introduces a filter for the environment's current status. Make backend filtering logic handle unknown statuses and to handle known 'MIXED' and 'DONE' statuses. Updates tests to verify filtering functionality.
1 parent bb74d46 commit 71a7c30

5 files changed

Lines changed: 60 additions & 6 deletions

File tree

lib/domain/enums/StatusAcronyms.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ const statusAcronyms = Object.freeze({
1818
CONFIGURED: 'C',
1919
RUNNING: 'R',
2020
ERROR: 'E',
21+
MIXED: 'M',
2122
DESTROYED: 'X',
23+
DONE: 'X',
2224
});
2325

2426
exports.statusAcronyms = statusAcronyms;

lib/public/views/Environments/ActiveColumns/environmentsActiveColumns.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { environmentStatusHistoryLegendComponent } from '../../../components/env
2424
import { infoTooltip } from '../../../components/common/popover/infoTooltip.js';
2525
import { aliEcsEnvironmentLinkComponent } from '../../../components/common/externalLinks/aliEcsEnvironmentLinkComponent.js';
2626
import { StatusAcronym } from '../../../domain/enums/statusAcronym.mjs';
27+
import { checkboxes } from '../../../components/Filters/common/filters/checkboxFilter.js';
2728

2829
/**
2930
* List of active columns for a generic Environments component
@@ -83,6 +84,14 @@ export const environmentsActiveColumns = {
8384
size: 'w-10',
8485
noEllipsis: true,
8586
format: (_, environment) => displayEnvironmentStatus(environment),
87+
88+
/**
89+
* Status filter component
90+
*
91+
* @param {EnvironmentOverviewModel} environmentOverviewModel the environment overview model
92+
* @return {Component} the filter component
93+
*/
94+
filter: (environmentOverviewModel) => checkboxes(environmentOverviewModel.filteringModel.get('currentStatus').selectionModel),
8695
},
8796
historyItems: {
8897
name: h('.flex-row.g2.items-center', ['Status History', infoTooltip(environmentStatusHistoryLegendComponent())]),

lib/public/views/Environments/Overview/EnvironmentOverviewModel.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
import { buildUrl } from '/js/src/index.js';
1515
import { FilteringModel } from '../../../components/Filters/common/FilteringModel.js';
1616
import { OverviewPageModel } from '../../../models/OverviewModel.js';
17+
import { SelectionFilterModel } from '../../../components/Filters/common/filters/SelectionFilterModel.js';
1718
import { debounce } from '../../../utilities/debounce.js';
19+
import { coloredEnvironmentStatusComponent } from '../ColoredEnvironmentStatusComponent.js';
20+
import { StatusAcronym } from '../../../domain/enums/statusAcronym.mjs';
1821

1922
/**
2023
* Environment overview page model
@@ -28,6 +31,13 @@ export class EnvironmentOverviewModel extends OverviewPageModel {
2831
super();
2932

3033
this._filteringModel = new FilteringModel({
34+
currentStatus: new SelectionFilterModel({
35+
availableOptions: Object.keys(StatusAcronym).map((status) => ({
36+
value: status,
37+
label: coloredEnvironmentStatusComponent(status),
38+
rawLabel: status,
39+
})).concat({ value: 'UNKNOWN', label: coloredEnvironmentStatusComponent('UNKNOWN'), rawLabel: 'UNKNOWN' }),
40+
}),
3141
});
3242

3343
this._filteringModel.observe(() => this._applyFilters(true));

lib/usecases/environment/GetAllEnvironmentsUseCase.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,21 @@ const { statusAcronyms } = require('../../domain/enums/StatusAcronyms.js');
2727
* It orders the history items by updatedAt DESC and selects to have the latests
2828
* history item on top. Then it limits the result to 1, so only
2929
* the latest history item is selected.
30+
* the latest history item is selected. If the environment has no history
31+
* items, it returns 'UNKNOWN' to indicate the environment has never had a status.
3032
*
3133
* Environment refers to the current environment in the main query,
3234
* because this query is a sub query that is executed for every environment.
3335
*/
3436
const ENVIRONMENT_LATEST_HISTORY_ITEM_SUBQUERY = `
35-
(SELECT h.status
36-
FROM environments_history_items AS h
37-
WHERE h.environment_id = Environment.id
38-
ORDER BY h.updated_at DESC
39-
LIMIT 1
40-
)`;
37+
(CASE
38+
WHEN EXISTS(SELECT 1 FROM environments_history_items AS h WHERE h.environment_id = Environment.id) THEN
39+
(SELECT h.status
40+
FROM environments_history_items AS h WHERE h.environment_id = Environment.id
41+
ORDER BY h.updated_at DESC
42+
LIMIT 1)
43+
ELSE 'UNKNOWN'
44+
END)`;
4145

4246
/**
4347
* Subquery to select the status history for each environment.

test/public/envs/overview.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,33 @@ module.exports = () => {
290290
await openFilteringPanel(page);
291291
await page.waitForSelector(filterPanelSelector, { visible: true });
292292
});
293+
294+
it('should successfully filter environments by their current status', async () => {
295+
/**
296+
* Checks that all the rows of the given table have a valid current status
297+
*
298+
* @param {string[]} authorizedCurrentStatuses the list of valid current statuses
299+
* @return {void}
300+
*/
301+
const checkTableCurrentStatuses = async (authorizedCurrentStatuses) => {
302+
const rows = await page.$$('tbody tr');
303+
for (const row of rows) {
304+
expect(await row.evaluate((rowItem) => {
305+
const rowId = rowItem.id;
306+
return document.querySelector(`#${rowId}-status-text`).innerText;
307+
})).to.be.oneOf(authorizedCurrentStatuses);
308+
}
309+
};
310+
311+
const currentStatusSelectorPrefix = '.status-filter #checkboxes-checkbox-';
312+
const getCurrentStatusCheckboxSelector = (statusName) => `${currentStatusSelectorPrefix}${statusName}`;
313+
314+
await page.$eval(getCurrentStatusCheckboxSelector("RUNNING"), (element) => element.click());
315+
await waitForTableLength(page, 2);
316+
await checkTableCurrentStatuses(["RUNNING"]);
317+
318+
await page.$eval(getCurrentStatusCheckboxSelector("DEPLOYED"), (element) => element.click());
319+
await waitForTableLength(page, 3);
320+
await checkTableCurrentStatuses(["RUNNING", "DEPLOYED"]);
321+
});
293322
};

0 commit comments

Comments
 (0)