From 2e98490b382f5478afc65a1352fafdfad546d215 Mon Sep 17 00:00:00 2001 From: MVarshini Date: Mon, 19 Aug 2024 10:19:00 +0530 Subject: [PATCH 1/8] PANDA-445 --- frontend/src/actions/commonActions.js | 4 +- frontend/src/actions/homeActions.js | 10 +-- frontend/src/actions/ocpActions.js | 6 +- frontend/src/actions/paginationActions.js | 39 +++++++++ frontend/src/actions/quayActions.js | 84 +++++++++++++++++++ frontend/src/actions/sortingActions.js | 37 ++++++++ frontend/src/actions/telcoActions.js | 81 ++++++++++++++++++ frontend/src/actions/types.js | 17 ++++ .../components/organisms/Pagination/index.jsx | 36 +++++++- .../organisms/TableLayout/index.jsx | 31 +++---- .../src/components/templates/Home/index.jsx | 44 +--------- .../src/components/templates/OCP/index.jsx | 37 ++++---- .../src/components/templates/Quay/index.jsx | 39 ++++++++- .../src/components/templates/Telco/index.jsx | 37 +++++++- frontend/src/reducers/index.js | 4 + frontend/src/reducers/quayReducer.js | 69 +++++++++++++++ frontend/src/reducers/telcoReducer.js | 71 ++++++++++++++++ frontend/src/utils/apiConstants.js | 3 + 18 files changed, 551 insertions(+), 98 deletions(-) create mode 100644 frontend/src/actions/paginationActions.js create mode 100644 frontend/src/actions/quayActions.js create mode 100644 frontend/src/actions/sortingActions.js create mode 100644 frontend/src/actions/telcoActions.js create mode 100644 frontend/src/reducers/quayReducer.js create mode 100644 frontend/src/reducers/telcoReducer.js diff --git a/frontend/src/actions/commonActions.js b/frontend/src/actions/commonActions.js index 81546e7b..6764b1ab 100644 --- a/frontend/src/actions/commonActions.js +++ b/frontend/src/actions/commonActions.js @@ -1,6 +1,6 @@ import * as TYPES from "@/actions/types.js"; -import { setCatFilters, sliceTableRows } from "./homeActions"; +import { setCatFilters, sliceCPTTableRows } from "./homeActions"; import { setOCPCatFilters, sliceOCPTableRows } from "./ocpActions"; import { DEFAULT_PER_PAGE } from "@/assets/constants/paginationConstants"; @@ -45,7 +45,7 @@ const sortedTableRows = (currState, sortedResults) => (dispatch) => { type: TYPES.SET_FILTERED_DATA, payload: sortedResults, }); - dispatch(sliceTableRows(0, DEFAULT_PER_PAGE)); + dispatch(sliceCPTTableRows(0, DEFAULT_PER_PAGE)); return; } if (currState === "ocp") { diff --git a/frontend/src/actions/homeActions.js b/frontend/src/actions/homeActions.js index 84296a98..d9a304d9 100644 --- a/frontend/src/actions/homeActions.js +++ b/frontend/src/actions/homeActions.js @@ -67,7 +67,7 @@ export const setCPTSortDir = (direction) => ({ payload: direction, }); -export const sliceTableRows = (startIdx, endIdx) => (dispatch, getState) => { +export const sliceCPTTableRows = (startIdx, endIdx) => (dispatch, getState) => { const results = [...getState().cpt.filteredResults]; dispatch({ @@ -201,12 +201,12 @@ export const setDateFilter = dispatch(fetchOCPJobsData()); }; -export const setPage = (pageNo) => ({ +export const setCPTPage = (pageNo) => ({ type: TYPES.SET_PAGE, payload: pageNo, }); -export const setPageOptions = (page, perPage) => ({ +export const setCPTPageOptions = (page, perPage) => ({ type: TYPES.SET_PAGE_OPTIONS, payload: { page, perPage }, }); @@ -223,6 +223,6 @@ export const getCPTSummary = () => (dispatch, getState) => { export const tableReCalcValues = () => (dispatch) => { dispatch(getCPTSummary()); - dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE)); - dispatch(sliceTableRows(0, DEFAULT_PER_PAGE)); + dispatch(setCPTPageOptions(START_PAGE, DEFAULT_PER_PAGE)); + dispatch(sliceCPTTableRows(0, DEFAULT_PER_PAGE)); }; diff --git a/frontend/src/actions/ocpActions.js b/frontend/src/actions/ocpActions.js index aae00a40..c8d61cc7 100644 --- a/frontend/src/actions/ocpActions.js +++ b/frontend/src/actions/ocpActions.js @@ -56,12 +56,12 @@ export const fetchOCPJobs = () => async (dispatch, getState) => { dispatch({ type: TYPES.COMPLETED }); }; -export const setPage = (pageNo) => ({ +export const setOCPPage = (pageNo) => ({ type: TYPES.SET_OCP_PAGE, payload: pageNo, }); -export const setPageOptions = (page, perPage) => ({ +export const setOCPPageOptions = (page, perPage) => ({ type: TYPES.SET_OCP_PAGE_OPTIONS, payload: { page, perPage }, }); @@ -257,6 +257,6 @@ export const setTableColumns = (key, isAdding) => (dispatch, getState) => { }; export const tableReCalcValues = () => (dispatch) => { dispatch(getOCPSummary()); - dispatch(setPageOptions(START_PAGE, DEFAULT_PER_PAGE)); + dispatch(setOCPPageOptions(START_PAGE, DEFAULT_PER_PAGE)); dispatch(sliceOCPTableRows(0, DEFAULT_PER_PAGE)); }; diff --git a/frontend/src/actions/paginationActions.js b/frontend/src/actions/paginationActions.js new file mode 100644 index 00000000..80a7dff1 --- /dev/null +++ b/frontend/src/actions/paginationActions.js @@ -0,0 +1,39 @@ +import { + setCPTPage, + setCPTPageOptions, + sliceCPTTableRows, +} from "./homeActions"; +import { setOCPPage, setOCPPageOptions, sliceOCPTableRows } from "./ocpActions"; +import { setQuayPage, setQuayPageOptions } from "./quayActions"; +import { setTelcoPage, setTelcoPageOptions } from "./telcoActions"; +export const setPage = (newPage, currType) => (dispatch) => { + if (currType === "cpt") { + dispatch(setCPTPage(newPage)); + } else if (currType === "ocp") { + dispatch(setOCPPage(newPage)); + } else if (currType === "quay") { + dispatch(setQuayPage(newPage)); + } else if (currType === "telco") { + dispatch(setTelcoPage(newPage)); + } +}; + +export const setPageOptions = (newPage, newPerPage, currType) => (dispatch) => { + if (currType === "cpt") { + dispatch(setCPTPageOptions(newPage, newPerPage)); + } else if (currType === "ocp") { + dispatch(setOCPPageOptions(newPage, newPerPage)); + } else if (currType === "quay") { + dispatch(setQuayPageOptions(newPage, newPerPage)); + } else if (currType === "telco") { + dispatch(setTelcoPageOptions(newPage, newPerPage)); + } +}; + +export const sliceTableRows = (startIdx, endIdx, currType) => (dispatch) => { + if (currType === "cpt") { + dispatch(sliceCPTTableRows(startIdx, endIdx)); + } else if (currType === "ocp") { + dispatch(sliceOCPTableRows(startIdx, endIdx)); + } +}; diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js new file mode 100644 index 00000000..d1f3a120 --- /dev/null +++ b/frontend/src/actions/quayActions.js @@ -0,0 +1,84 @@ +import * as API_ROUTES from "@/utils/apiConstants"; +import * as TYPES from "@/actions/types.js"; + +import { + DEFAULT_PER_PAGE, + START_PAGE, +} from "@/assets/constants/paginationConstants"; +import { appendDateFilter, appendQueryString } from "@/utils/helper.js"; + +import API from "@/utils/axiosInstance"; +import { showFailureToast } from "@/actions/toastActions"; + +export const fetchQuayJobsData = () => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.LOADING }); + const { start_date, end_date } = getState().cpt; + const response = await API.get(API_ROUTES.QUAY_JOBS_API_V1, { + params: { + pretty: true, + start_date: "2022-08-16", + end_date: "2024-08-16", + // ...(start_date && { start_date }), + // ...(end_date && { end_date }), + }, + }); + if (response?.data?.results?.length > 0) { + const startDate = response.data.startDate, + endDate = response.data.endDate; + //on initial load startDate and endDate are empty, so from response append to url + appendDateFilter(startDate, endDate); + dispatch({ + type: TYPES.SET_QUAY_JOBS_DATA, + payload: response.data.results, + }); + dispatch({ + type: TYPES.SET_QUAY_FILTERED_DATA, + payload: response.data.results, + }); + dispatch({ + type: TYPES.SET_QUAY_DATE_FILTER, + payload: { + start_date: startDate, + end_date: endDate, + }, + }); + dispatch(tableReCalcValues()); + } + } catch (error) { + dispatch(showFailureToast()); + } + dispatch({ type: TYPES.COMPLETED }); +}; + +export const setQuayPage = (pageNo) => ({ + type: TYPES.SET_QUAY_PAGE, + payload: pageNo, +}); + +export const setQuayPageOptions = (page, perPage) => ({ + type: TYPES.SET_QUAY_PAGE_OPTIONS, + payload: { page, perPage }, +}); +export const setQuaySortIndex = (index) => ({ + type: TYPES.SET_QUAY_SORT_INDEX, + payload: index, +}); + +export const setQuaySortDir = (direction) => ({ + type: TYPES.SET_QUAY_SORT_DIR, + payload: direction, +}); +export const sliceQuayTableRows = + (startIdx, endIdx) => (dispatch, getState) => { + const results = [...getState().quay.filteredResults]; + + dispatch({ + type: TYPES.SET_QUAY_INIT_JOBS, + payload: results.slice(startIdx, endIdx), + }); + }; +export const tableReCalcValues = () => (dispatch) => { + dispatch(setQuayPageOptions(START_PAGE, DEFAULT_PER_PAGE)); + dispatch(sliceQuayTableRows(0, DEFAULT_PER_PAGE)); +}; diff --git a/frontend/src/actions/sortingActions.js b/frontend/src/actions/sortingActions.js new file mode 100644 index 00000000..fae3fe7e --- /dev/null +++ b/frontend/src/actions/sortingActions.js @@ -0,0 +1,37 @@ +import { setCPTSortDir, setCPTSortIndex } from "./homeActions"; +import { setOCPSortDir, setOCPSortIndex } from "./ocpActions"; +import { setQuaySortDir, setQuaySortIndex } from "./quayActions"; +import { setTelcoSortDir, setTelcoSortIndex } from "./telcoActions"; + +import { sortTable } from "./commonActions"; +import store from "@/store/store"; + +const { dispatch } = store; +export const setActiveSortDir = (dir, currType) => { + console.log("hey 1"); + if (currType === "cpt") { + dispatch(setCPTSortDir(dir)); + } else if (currType === "ocp") { + dispatch(setOCPSortDir(dir)); + } else if (currType === "quay") { + dispatch(setQuaySortDir(dir)); + } else if (currType === "telco") { + dispatch(setTelcoSortDir(dir)); + } +}; +export const setActiveSortIndex = (index, currType) => { + console.log("hey 2"); + console.log(currType); + if (currType === "cpt") { + dispatch(setCPTSortIndex(index)); + } else if (currType === "ocp") { + dispatch(setOCPSortIndex(index)); + } else if (currType === "quay") { + dispatch(setQuaySortIndex(index)); + } else if (currType === "telco") { + dispatch(setTelcoSortIndex(index)); + } +}; +export const handleOnSort = (currType) => { + dispatch(sortTable(currType)); +}; diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js new file mode 100644 index 00000000..fc4fdd6c --- /dev/null +++ b/frontend/src/actions/telcoActions.js @@ -0,0 +1,81 @@ +import * as API_ROUTES from "@/utils/apiConstants"; +import * as TYPES from "@/actions/types.js"; + +import { + DEFAULT_PER_PAGE, + START_PAGE, +} from "@/assets/constants/paginationConstants"; +import { appendDateFilter, appendQueryString } from "@/utils/helper.js"; + +import API from "@/utils/axiosInstance"; +import { showFailureToast } from "@/actions/toastActions"; + +export const fetchTelcoJobsData = () => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.LOADING }); + const { start_date, end_date } = getState().cpt; + const response = await API.get(API_ROUTES.TELCO_JOBS_API_V1, { + params: { + pretty: true, + ...(start_date && { start_date }), + ...(end_date && { end_date }), + }, + }); + if (response?.data?.results?.length > 0) { + const startDate = response.data.startDate, + endDate = response.data.endDate; + //on initial load startDate and endDate are empty, so from response append to url + appendDateFilter(startDate, endDate); + dispatch({ + type: TYPES.SET_TELCO_JOBS_DATA, + payload: response.data.results, + }); + dispatch({ + type: TYPES.SET_TELCO_FILTERED_DATA, + payload: response.data.results, + }); + dispatch({ + type: TYPES.SET_TELCO_DATE_FILTER, + payload: { + start_date: startDate, + end_date: endDate, + }, + }); + dispatch(tableReCalcValues()); + } + } catch (error) { + dispatch(showFailureToast()); + } + dispatch({ type: TYPES.COMPLETED }); +}; +export const setTelcoPage = (pageNo) => ({ + type: TYPES.SET_TELCO_PAGE, + payload: pageNo, +}); + +export const setTelcoPageOptions = (page, perPage) => ({ + type: TYPES.SET_TELCO_PAGE_OPTIONS, + payload: { page, perPage }, +}); +export const setTelcoSortIndex = (index) => ({ + type: TYPES.SET_TELCO_SORT_INDEX, + payload: index, +}); + +export const setTelcoSortDir = (direction) => ({ + type: TYPES.SET_TELCO_SORT_DIR, + payload: direction, +}); +export const sliceTelcoTableRows = + (startIdx, endIdx) => (dispatch, getState) => { + const results = [...getState().telco.filteredResults]; + + dispatch({ + type: TYPES.SET_TELCO_INIT_JOBS, + payload: results.slice(startIdx, endIdx), + }); + }; +export const tableReCalcValues = () => (dispatch) => { + dispatch(setTelcoPageOptions(START_PAGE, DEFAULT_PER_PAGE)); + dispatch(sliceTelcoTableRows(0, DEFAULT_PER_PAGE)); +}; diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index 77db108b..2cd769c9 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -43,3 +43,20 @@ export const SET_OCP_APPLIED_FILTERS = "SET_OCP_APPLIED_FILTERS"; export const SET_OCP_GRAPH_DATA = "SET_OCP_GRAPH_DATA"; export const SET_OCP_COLUMNS = "SET_OCP_COLUMNS"; export const SET_SELECTED_OCP_FILTERS = "SET_SELECTED_OCP_FILTERS"; +/* QUAY Jobs*/ +export const SET_QUAY_JOBS_DATA = "SET_QUAY_JOBS_DATA"; +export const SET_QUAY_DATE_FILTER = "SET_QUAY_DATE_FILTER"; +export const SET_QUAY_SORT_INDEX = "SET_QUAY_SORT_INDEX"; +export const SET_QUAY_SORT_DIR = "SET_QUAY_SORT_DIR"; +export const SET_QUAY_PAGE = "SET_QUAY_PAGE"; +export const SET_QUAY_PAGE_OPTIONS = "SET_QUAY_PAGE_OPTIONS"; +export const SET_QUAY_INIT_JOBS = "SET_OCP_INIT_JOBS"; +export const SET_QUAY_FILTERED_DATA = "SET_QUAY_FILTERED_DATA"; +/* Telco Jobs */ +export const SET_TELCO_JOBS_DATA = "SET_TELCO_JOBS_DATA"; +export const SET_TELCO_SORT_INDEX = "SET_TELCO_SORT_INDEX"; +export const SET_TELCO_SORT_DIR = "SET_TELCO_SORT_DIR"; +export const SET_TELCO_PAGE = "SET_TELCO_PAGE"; +export const SET_TELCO_PAGE_OPTIONS = "SET_TELCO_PAGE_OPTIONS"; +export const SET_TELCO_INIT_JOBS = "SET_OCP_INIT_JOBS"; +export const SET_TELCO_FILTERED_DATA = "SET_TELCO_FILTERED_DATA"; diff --git a/frontend/src/components/organisms/Pagination/index.jsx b/frontend/src/components/organisms/Pagination/index.jsx index 490a801d..7b316a21 100644 --- a/frontend/src/components/organisms/Pagination/index.jsx +++ b/frontend/src/components/organisms/Pagination/index.jsx @@ -1,12 +1,38 @@ import { Pagination, PaginationVariant } from "@patternfly/react-core"; +import { + setPage, + setPageOptions, + sliceTableRows, +} from "@/actions/paginationActions"; + +import PropTypes from "prop-types"; +import { useCallback } from "react"; +import { useDispatch } from "react-redux"; const RenderPagination = (props) => { + const dispatch = useDispatch(); + const perPageOptions = [ { title: "25", value: 25 }, { title: "50", value: 50 }, { title: "100", value: 100 }, ]; + const onSetPage = useCallback( + (_evt, newPage, _perPage, startIdx, endIdx) => { + dispatch(setPage(newPage, props.type)); + dispatch(sliceTableRows(startIdx, endIdx, props.type)); + }, + [dispatch, props.type] + ); + const onPerPageSelect = useCallback( + (_evt, newPerPage, newPage, startIdx, endIdx) => { + dispatch(setPageOptions(newPage, newPerPage, props.type)); + dispatch(sliceTableRows(startIdx, endIdx, props.type)); + }, + [dispatch, props.type] + ); + return ( { page={props.page} variant={PaginationVariant.bottom} perPageOptions={perPageOptions} - onSetPage={props.onSetPage} - onPerPageSelect={props.onPerPageSelect} + onSetPage={onSetPage} + onPerPageSelect={onPerPageSelect} /> ); }; +RenderPagination.propTypes = { + page: PropTypes.number, + perPage: PropTypes.number, + type: PropTypes.string, + items: PropTypes.number, +}; export default RenderPagination; diff --git a/frontend/src/components/organisms/TableLayout/index.jsx b/frontend/src/components/organisms/TableLayout/index.jsx index 57ee8062..b84c72e3 100644 --- a/frontend/src/components/organisms/TableLayout/index.jsx +++ b/frontend/src/components/organisms/TableLayout/index.jsx @@ -1,4 +1,9 @@ import { Table, Tbody, Th, Thead, Tr } from "@patternfly/react-table"; +import { + handleOnSort, + setActiveSortDir, + setActiveSortIndex, +} from "@/actions/sortingActions"; import PropTypes from "prop-types"; import RenderPagination from "@/components/organisms/Pagination"; @@ -11,17 +16,11 @@ const TableLayout = (props) => { tableColumns, activeSortIndex, activeSortDir, - setActiveSortIndex, - setActiveSortDir, - handleOnSort, page, perPage, - setPage, - setPerPage, - onSetPage, - onPerPageSelect, totalItems, addExpansion, + type, } = props; const getSortParams = (columnIndex) => ({ @@ -31,9 +30,9 @@ const TableLayout = (props) => { defaultDirection: "asc", }, onSort: (_event, index, direction) => { - setActiveSortIndex(index); - setActiveSortDir(direction); - handleOnSort(); + setActiveSortIndex(index, type); + setActiveSortDir(direction, type); + handleOnSort(type); }, columnIndex, }); @@ -68,11 +67,8 @@ const TableLayout = (props) => { ); @@ -83,16 +79,9 @@ TableLayout.propTypes = { tableColumns: PropTypes.array, activeSortIndex: PropTypes.number || PropTypes.object, activeSortDir: PropTypes.string || PropTypes.object, - setActiveSortIndex: PropTypes.func, - setActiveSortDir: PropTypes.func, - handleOnSort: PropTypes.func, totalItems: PropTypes.number, page: PropTypes.number, perPage: PropTypes.number, - onPerPageSelect: PropTypes.func, - onSetPage: PropTypes.func, - setPage: PropTypes.func, - setPerPage: PropTypes.func, addExpansion: PropTypes.bool, graphData: PropTypes.array, type: PropTypes.string, diff --git a/frontend/src/components/templates/Home/index.jsx b/frontend/src/components/templates/Home/index.jsx index 8e6d8254..4a32451f 100644 --- a/frontend/src/components/templates/Home/index.jsx +++ b/frontend/src/components/templates/Home/index.jsx @@ -2,26 +2,20 @@ import { fetchOCPJobsData, removeAppliedFilters, setAppliedFilters, - setCPTSortDir, - setCPTSortIndex, setCatFilters, setDateFilter, setFilterFromURL, setOtherSummaryFilter, - setPage, - setPageOptions, setSelectedFilter, setSelectedFilterFromUrl, - sliceTableRows, } from "@/actions/homeActions.js"; -import { useCallback, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate, useSearchParams } from "react-router-dom"; import MetricsTab from "@//components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; import TableLayout from "@/components/organisms/TableLayout"; -import { sortTable } from "@/actions/commonActions"; +import { useEffect } from "react"; const Home = () => { const dispatch = useDispatch(); @@ -69,35 +63,6 @@ const Home = () => { useEffect(() => { dispatch(fetchOCPJobsData()); }, [dispatch]); - //Sorting - const setActiveSortDir = (dir) => { - dispatch(setCPTSortDir(dir)); - }; - const setActiveSortIndex = (index) => { - dispatch(setCPTSortIndex(index)); - }; - const handleOnSort = () => { - dispatch(sortTable("cpt")); - }; - // Sorting - - // Pagination Helper - const onSetPage = useCallback( - (_evt, newPage, _perPage, startIdx, endIdx) => { - dispatch(setPage(newPage)); - dispatch(sliceTableRows(startIdx, endIdx)); - }, - [dispatch] - ); - const onPerPageSelect = useCallback( - (_evt, newPerPage, newPage, startIdx, endIdx) => { - dispatch(setPageOptions(newPage, newPerPage)); - dispatch(sliceTableRows(startIdx, endIdx)); - }, - [dispatch] - ); - // Pagination helper - // Filter Helper const onCategoryChange = (_event, value) => { dispatch(setCatFilters(value)); @@ -172,16 +137,11 @@ const Home = () => { tableColumns={tableColumns} activeSortIndex={activeSortIndex} activeSortDir={activeSortDir} - setActiveSortDir={setActiveSortDir} - setActiveSortIndex={setActiveSortIndex} - handleOnSort={handleOnSort} - onPerPageSelect={onPerPageSelect} - onSetPage={onSetPage} page={page} perPage={perPage} totalItems={filteredResults.length} addExpansion={false} - state={"cpt"} + type={"cpt"} /> ); diff --git a/frontend/src/components/templates/OCP/index.jsx b/frontend/src/components/templates/OCP/index.jsx index 623df07f..24241bc3 100644 --- a/frontend/src/components/templates/OCP/index.jsx +++ b/frontend/src/components/templates/OCP/index.jsx @@ -9,12 +9,9 @@ import { setOCPSortDir, setOCPSortIndex, setOtherSummaryFilter, - setPage, - setPageOptions, setSelectedFilter, setSelectedFilterFromUrl, setTableColumns, - sliceOCPTableRows, } from "@/actions/ocpActions"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; @@ -91,22 +88,22 @@ const OCP = () => { }; // Sorting - // Pagination Helper - const onSetPage = useCallback( - (_evt, newPage, _perPage, startIdx, endIdx) => { - dispatch(setPage(newPage)); - dispatch(sliceOCPTableRows(startIdx, endIdx)); - }, - [dispatch] - ); - const onPerPageSelect = useCallback( - (_evt, newPerPage, newPage, startIdx, endIdx) => { - dispatch(setPageOptions(newPage, newPerPage)); - dispatch(sliceOCPTableRows(startIdx, endIdx)); - }, - [dispatch] - ); - // Pagination helper + // // Pagination Helper + // const onSetPage = useCallback( + // (_evt, newPage, _perPage, startIdx, endIdx) => { + // dispatch(setPage(newPage)); + // dispatch(sliceOCPTableRows(startIdx, endIdx)); + // }, + // [dispatch] + // ); + // const onPerPageSelect = useCallback( + // (_evt, newPerPage, newPage, startIdx, endIdx) => { + // dispatch(setPageOptions(newPage, newPerPage)); + // dispatch(sliceOCPTableRows(startIdx, endIdx)); + // }, + // [dispatch] + // ); + // // Pagination helper /* Summary Tab Filter*/ const removeStatusFilter = () => { if ( @@ -208,8 +205,6 @@ const OCP = () => { setActiveSortDir={setActiveSortDir} setActiveSortIndex={setActiveSortIndex} handleOnSort={handleOnSort} - onPerPageSelect={onPerPageSelect} - onSetPage={onSetPage} page={page} perPage={perPage} totalItems={filteredResults.length} diff --git a/frontend/src/components/templates/Quay/index.jsx b/frontend/src/components/templates/Quay/index.jsx index d4b55e15..e60e45a3 100644 --- a/frontend/src/components/templates/Quay/index.jsx +++ b/frontend/src/components/templates/Quay/index.jsx @@ -1,5 +1,42 @@ +import { useDispatch, useSelector } from "react-redux"; + +import TableFilter from "@/components/organisms/TableFilters"; +import TableLayout from "@/components/organisms/TableLayout"; +import { fetchQuayJobsData } from "@/actions/quayActions.js"; +import { useEffect } from "react"; + const Quay = () => { - return <>Quay; + const dispatch = useDispatch(); + + const { + tableData, + tableColumns, + activeSortIndex, + activeSortDir, + page, + perPage, + filteredResults, + } = useSelector((state) => state.quay); + + useEffect(() => { + dispatch(fetchQuayJobsData()); + }, [dispatch]); + + return ( + <> + + + ); }; export default Quay; diff --git a/frontend/src/components/templates/Telco/index.jsx b/frontend/src/components/templates/Telco/index.jsx index 8b9b5741..275bd7b4 100644 --- a/frontend/src/components/templates/Telco/index.jsx +++ b/frontend/src/components/templates/Telco/index.jsx @@ -1,5 +1,40 @@ +import { useDispatch, useSelector } from "react-redux"; + +import TableLayout from "@/components/organisms/TableLayout"; +import { fetchTelcoJobsData } from "@/actions/telcoActions.js"; +import { useEffect } from "react"; + const Telco = () => { - return <>Telco; + const dispatch = useDispatch(); + const { + tableData, + tableColumns, + activeSortIndex, + activeSortDir, + page, + perPage, + filteredResults, + } = useSelector((state) => state.telco); + + useEffect(() => { + dispatch(fetchTelcoJobsData()); + }, [dispatch]); + + return ( + <> + + + ); }; export default Telco; diff --git a/frontend/src/reducers/index.js b/frontend/src/reducers/index.js index caaa3874..1fb4c555 100644 --- a/frontend/src/reducers/index.js +++ b/frontend/src/reducers/index.js @@ -1,7 +1,9 @@ import HomeReducer from "./homeReducer"; import LoadingReducer from "./loadingReducer"; import OCPReducer from "./ocpReducer"; +import QuayReducer from "./quayReducer"; import SideMenuReducer from "./sideMenuReducer"; +import TelcoReducer from "./telcoReducer"; import ToastReducer from "./toastReducer"; import { combineReducers } from "redux"; @@ -11,4 +13,6 @@ export default combineReducers({ sidemenu: SideMenuReducer, cpt: HomeReducer, ocp: OCPReducer, + quay: QuayReducer, + telco: TelcoReducer, }); diff --git a/frontend/src/reducers/quayReducer.js b/frontend/src/reducers/quayReducer.js new file mode 100644 index 00000000..6d8a26d4 --- /dev/null +++ b/frontend/src/reducers/quayReducer.js @@ -0,0 +1,69 @@ +import * as TYPES from "@/actions/types"; + +import { + DEFAULT_PER_PAGE, + START_PAGE, +} from "@/assets/constants/paginationConstants"; + +const initialState = { + results: [], + start_date: "", + end_date: "", + tableColumns: [ + { name: "Benchmark", value: "benchmark" }, + { name: "Release Stream", value: "releaseStream" }, + { name: "Platform", value: "platform" }, + { name: "Worker Count", value: "workerNodesCount" }, + { name: "Start Date", value: "startDate" }, + { name: "End Date", value: "endDate" }, + { name: "Status", value: "jobStatus" }, + ], + tableFilters: [ + { name: "Benchmark", value: "benchmark" }, + { name: "Release Stream", value: "releaseStream" }, + { name: "Platform", value: "platform" }, + { name: "Worker Count", value: "workerNodesCount" }, + { name: "Status", value: "jobStatus" }, + ], + filterData: [], + filteredResults: [], + activeSortDir: null, + activeSortIndex: null, + tableData: [], + page: START_PAGE, + perPage: DEFAULT_PER_PAGE, +}; + +const QuayReducer = (state = initialState, action = {}) => { + const { type, payload } = action; + + switch (type) { + case TYPES.SET_QUAY_JOBS_DATA: + return { + ...state, + results: payload, + }; + case TYPES.SET_QUAY_DATE_FILTER: + return { + ...state, + start_date: payload.start_date, + end_date: payload.end_date, + }; + case TYPES.SET_QUAY_SORT_INDEX: + return { ...state, activeSortIndex: payload }; + case TYPES.SET_QUAY_SORT_DIR: + return { ...state, activeSortDir: payload }; + case TYPES.SET_QUAY_PAGE: + return { ...state, page: payload }; + case TYPES.SET_QUAY_PAGE_OPTIONS: + return { ...state, page: payload.page, perPage: payload.perPage }; + case TYPES.SET_QUAY_INIT_JOBS: + return { ...state, tableData: payload }; + case TYPES.SET_QUAY_FILTERED_DATA: + return { ...state, filteredResults: payload }; + default: + return state; + } +}; + +export default QuayReducer; diff --git a/frontend/src/reducers/telcoReducer.js b/frontend/src/reducers/telcoReducer.js new file mode 100644 index 00000000..9abb6422 --- /dev/null +++ b/frontend/src/reducers/telcoReducer.js @@ -0,0 +1,71 @@ +import * as TYPES from "@/actions/types"; + +import { + DEFAULT_PER_PAGE, + START_PAGE, +} from "@/assets/constants/paginationConstants"; + +const initialState = { + results: [], + start_date: "", + end_date: "", + tableColumns: [ + { name: "Benchmark", value: "benchmark" }, + { name: "Release Stream", value: "releaseStream" }, + { name: "Build", value: "TELCOVersion" }, + { name: "CPU", value: "cpu_util" }, + { name: "Node Name", value: "nodeName" }, + { name: "Start Date", value: "startDate" }, + { name: "End Date", value: "endDate" }, + { name: "Status", value: "jobStatus" }, + ], + tableFilters: [ + { name: "Benchmark", value: "benchmark" }, + { name: "Release Stream", value: "releaseStream" }, + { name: "Build", value: "TELCOVersion" }, + { name: "CPU", value: "cpu_util" }, + { name: "Node Name", value: "nodeName" }, + { name: "Status", value: "jobStatus" }, + ], + filterData: [], + filteredResults: [], + activeSortDir: null, + activeSortIndex: null, + tableData: [], + page: START_PAGE, + perPage: DEFAULT_PER_PAGE, +}; + +const TelcoReducer = (state = initialState, action = {}) => { + const { type, payload } = action; + + switch (type) { + case TYPES.SET_TELCO_JOBS_DATA: + return { + ...state, + results: payload, + }; + case TYPES.SET_TELCO_DATE_FILTER: + return { + ...state, + start_date: payload.start_date, + end_date: payload.end_date, + }; + case TYPES.SET_TELCO_SORT_INDEX: + return { ...state, activeSortIndex: payload }; + case TYPES.SET_TELCO_SORT_DIR: + return { ...state, activeSortDir: payload }; + case TYPES.SET_TELCO_PAGE: + return { ...state, page: payload }; + case TYPES.SET_TELCO_PAGE_OPTIONS: + return { ...state, page: payload.page, perPage: payload.perPage }; + case TYPES.SET_TELCO_INIT_JOBS: + return { ...state, tableData: payload }; + case TYPES.SET_TELCO_FILTERED_DATA: + return { ...state, filteredResults: payload }; + default: + return state; + } +}; + +export default TelcoReducer; diff --git a/frontend/src/utils/apiConstants.js b/frontend/src/utils/apiConstants.js index e6d68406..52576b4a 100644 --- a/frontend/src/utils/apiConstants.js +++ b/frontend/src/utils/apiConstants.js @@ -14,3 +14,6 @@ export const CPT_JOBS_API_V1 = "/api/v1/cpt/jobs"; export const QUAY_JOBS_API_V1 = "/api/v1/quay/jobs"; export const QUAY_GRAPH_API_V1 = "/api/v1/quay/graph"; + +export const TELCO_JOBS_API_V1 = "/api/v1/telco/jobs"; +export const TELCO_GRAPH_API_V1 = "/api/v1/telco/graph"; From ac4b7822cfbb96fb50b2b7eeb3f4c8b297f7f8b9 Mon Sep 17 00:00:00 2001 From: MVarshini Date: Mon, 19 Aug 2024 19:54:24 +0530 Subject: [PATCH 2/8] Metrics Tab and Filter --- frontend/src/actions/commonActions.js | 34 +++- frontend/src/actions/filterActions.js | 92 +++++++++++ frontend/src/actions/homeActions.js | 10 +- frontend/src/actions/ocpActions.js | 8 +- frontend/src/actions/quayActions.js | 141 ++++++++++++++++- frontend/src/actions/sortingActions.js | 3 - frontend/src/actions/telcoActions.js | 146 +++++++++++++++++- frontend/src/actions/types.js | 12 ++ .../components/organisms/MetricsTab/index.jsx | 44 +++++- .../organisms/TableFilters/index.jsx | 35 +++-- .../organisms/TableLayout/index.jsx | 2 +- .../src/components/templates/Home/index.jsx | 56 +------ .../src/components/templates/OCP/index.jsx | 108 ++----------- .../src/components/templates/Quay/index.jsx | 51 +++++- .../src/components/templates/Telco/index.jsx | 55 ++++++- frontend/src/reducers/quayReducer.js | 23 +++ frontend/src/reducers/telcoReducer.js | 24 +++ 17 files changed, 664 insertions(+), 180 deletions(-) create mode 100644 frontend/src/actions/filterActions.js diff --git a/frontend/src/actions/commonActions.js b/frontend/src/actions/commonActions.js index 6764b1ab..1b2af030 100644 --- a/frontend/src/actions/commonActions.js +++ b/frontend/src/actions/commonActions.js @@ -1,7 +1,9 @@ import * as TYPES from "@/actions/types.js"; -import { setCatFilters, sliceCPTTableRows } from "./homeActions"; +import { setCPTCatFilters, sliceCPTTableRows } from "./homeActions"; import { setOCPCatFilters, sliceOCPTableRows } from "./ocpActions"; +import { setQuayCatFilters, sliceQuayTableRows } from "./quayActions"; +import { setTelcoCatFilters, sliceTelcoTableRows } from "./telcoActions"; import { DEFAULT_PER_PAGE } from "@/assets/constants/paginationConstants"; import { cloneDeep } from "lodash"; @@ -54,6 +56,22 @@ const sortedTableRows = (currState, sortedResults) => (dispatch) => { payload: sortedResults, }); dispatch(sliceOCPTableRows(0, DEFAULT_PER_PAGE)); + return; + } + if (currState === "quay") { + dispatch({ + type: TYPES.SET_QUAY_FILTERED_DATA, + payload: sortedResults, + }); + dispatch(sliceQuayTableRows(0, DEFAULT_PER_PAGE)); + return; + } + if (currState === "telco") { + dispatch({ + type: TYPES.SET_TELCO_FILTERED_DATA, + payload: sortedResults, + }); + dispatch(sliceTelcoTableRows(0, DEFAULT_PER_PAGE)); } }; @@ -114,7 +132,19 @@ const setFilterData = (filterData, currState, activeFilter) => (dispatch) => { type: TYPES.SET_CPT_FILTER_DATA, payload: filterData, }); - dispatch(setCatFilters(activeFilter)); + dispatch(setCPTCatFilters(activeFilter)); + } else if (currState === "quay") { + dispatch({ + type: TYPES.SET_QUAY_FILTER_DATA, + payload: filterData, + }); + dispatch(setQuayCatFilters(activeFilter)); + } else if (currState === "telco") { + dispatch({ + type: TYPES.SET_TELCO_FILTER_DATA, + payload: filterData, + }); + dispatch(setTelcoCatFilters(activeFilter)); } }; diff --git a/frontend/src/actions/filterActions.js b/frontend/src/actions/filterActions.js new file mode 100644 index 00000000..7f565887 --- /dev/null +++ b/frontend/src/actions/filterActions.js @@ -0,0 +1,92 @@ +import { + removeCPTAppliedFilters, + setCPTAppliedFilters, + setCPTCatFilters, + setCPTDateFilter, + setCPTOtherSummaryFilter, +} from "./homeActions"; +import { + removeOCPAppliedFilters, + setOCPAppliedFilters, + setOCPCatFilters, + setOCPDateFilter, + setOCPOtherSummaryFilter, +} from "./ocpActions"; +import { + removeQuayAppliedFilters, + setQuayAppliedFilters, + setQuayCatFilters, + setQuayDateFilter, + setQuayOtherSummaryFilter, +} from "./quayActions"; +import { + removeTelcoAppliedFilters, + setTelcoAppliedFilters, + setTelcoCatFilters, + setTelcoDateFilter, + setTelcoOtherSummaryFilter, +} from "./telcoActions"; + +import store from "@/store/store"; + +const { dispatch } = store; + +export const setCatFilters = (category, currType) => { + if (currType === "cpt") { + dispatch(setCPTCatFilters(category)); + } else if (currType === "ocp") { + dispatch(setOCPCatFilters(category)); + } else if (currType === "quay") { + dispatch(setQuayCatFilters(category)); + } else if (currType === "telco") { + dispatch(setTelcoCatFilters(category)); + } +}; + +export const setAppliedFilters = (navigation, currType) => { + if (currType === "cpt") { + dispatch(setCPTAppliedFilters(navigation)); + } else if (currType === "ocp") { + dispatch(setOCPAppliedFilters(navigation)); + } else if (currType === "quay") { + dispatch(setQuayAppliedFilters(navigation)); + } else if (currType === "telco") { + dispatch(setTelcoAppliedFilters(navigation)); + } +}; + +export const removeAppliedFilters = (key, value, navigation, currType) => { + if (currType === "cpt") { + dispatch(removeCPTAppliedFilters(key, value, navigation)); + } else if (currType === "ocp") { + dispatch(removeOCPAppliedFilters(key, value, navigation)); + } else if (currType === "quay") { + dispatch(removeQuayAppliedFilters(key, value, navigation)); + } else if (currType === "telco") { + dispatch(removeTelcoAppliedFilters(key, value, navigation)); + } +}; + +export const setDateFilter = (date, key, navigation, currType) => { + if (currType === "cpt") { + dispatch(setCPTDateFilter(date, key, navigation)); + } else if (currType === "ocp") { + dispatch(setOCPDateFilter(date, key, navigation)); + } else if (currType === "quay") { + dispatch(setQuayDateFilter(date, key, navigation)); + } else if (currType === "telco") { + dispatch(setTelcoDateFilter(date, key, navigation)); + } +}; + +export const setOtherSummaryFilter = (currType) => { + if (currType === "cpt") { + dispatch(setCPTOtherSummaryFilter()); + } else if (currType === "ocp") { + dispatch(setOCPOtherSummaryFilter()); + } else if (currType === "quay") { + dispatch(setQuayOtherSummaryFilter()); + } else if (currType === "telco") { + dispatch(setTelcoOtherSummaryFilter()); + } +}; diff --git a/frontend/src/actions/homeActions.js b/frontend/src/actions/homeActions.js index d9a304d9..b8edfca1 100644 --- a/frontend/src/actions/homeActions.js +++ b/frontend/src/actions/homeActions.js @@ -76,7 +76,7 @@ export const sliceCPTTableRows = (startIdx, endIdx) => (dispatch, getState) => { }); }; -export const setCatFilters = (category) => (dispatch, getState) => { +export const setCPTCatFilters = (category) => (dispatch, getState) => { const filterData = [...getState().cpt.filterData]; const options = filterData.filter((item) => item.name === category)[0].value; const list = options.map((item) => ({ name: item, value: item })); @@ -112,7 +112,7 @@ export const setSelectedFilter = }); }; -export const setAppliedFilters = (navigate) => (dispatch, getState) => { +export const setCPTAppliedFilters = (navigate) => (dispatch, getState) => { const { selectedFilters, start_date, end_date } = getState().cpt; const appliedFilterArr = selectedFilters.filter((i) => i.value.length > 0); @@ -130,7 +130,7 @@ export const setAppliedFilters = (navigate) => (dispatch, getState) => { dispatch(applyFilters()); }; -export const setOtherSummaryFilter = () => (dispatch, getState) => { +export const setCPTOtherSummaryFilter = () => (dispatch, getState) => { const filteredResults = [...getState().cpt.filteredResults]; const keyWordArr = ["success", "failure"]; const data = filteredResults.filter( @@ -142,7 +142,7 @@ export const setOtherSummaryFilter = () => (dispatch, getState) => { }); dispatch(tableReCalcValues()); }; -export const removeAppliedFilters = +export const removeCPTAppliedFilters = (filterKey, filterValue, navigate) => (dispatch, getState) => { const { start_date, end_date } = getState().cpt; @@ -184,7 +184,7 @@ export const setFilterFromURL = (searchParams) => ({ payload: searchParams, }); -export const setDateFilter = +export const setCPTDateFilter = (start_date, end_date, navigate) => (dispatch, getState) => { const appliedFilters = getState().cpt.appliedFilters; diff --git a/frontend/src/actions/ocpActions.js b/frontend/src/actions/ocpActions.js index c8d61cc7..0638ece8 100644 --- a/frontend/src/actions/ocpActions.js +++ b/frontend/src/actions/ocpActions.js @@ -141,7 +141,7 @@ export const setSelectedFilter = payload: selectedFilters, }); }; -export const setAppliedFilters = (navigate) => (dispatch, getState) => { +export const setOCPAppliedFilters = (navigate) => (dispatch, getState) => { const { start_date, end_date, selectedFilters } = getState().ocp; const appliedFilterArr = selectedFilters.filter((i) => i.value.length > 0); @@ -158,7 +158,7 @@ export const setAppliedFilters = (navigate) => (dispatch, getState) => { dispatch(applyFilters()); }; -export const removeAppliedFilters = +export const removeOCPAppliedFilters = (filterKey, filterValue, navigate) => (dispatch, getState) => { const appliedFilters = dispatch( deleteAppliedFilters(filterKey, filterValue, "ocp") @@ -172,7 +172,7 @@ export const removeAppliedFilters = dispatch(applyFilters()); }; -export const setDateFilter = +export const setOCPDateFilter = (start_date, end_date, navigate) => (dispatch, getState) => { const appliedFilters = getState().ocp.appliedFilters; @@ -194,7 +194,7 @@ export const setFilterFromURL = (searchParams) => ({ payload: searchParams, }); -export const setOtherSummaryFilter = () => (dispatch, getState) => { +export const setOCPOtherSummaryFilter = () => (dispatch, getState) => { const filteredResults = [...getState().ocp.filteredResults]; const keyWordArr = ["success", "failure"]; const data = filteredResults.filter( diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js index d1f3a120..fa33e26e 100644 --- a/frontend/src/actions/quayActions.js +++ b/frontend/src/actions/quayActions.js @@ -6,14 +6,22 @@ import { START_PAGE, } from "@/assets/constants/paginationConstants"; import { appendDateFilter, appendQueryString } from "@/utils/helper.js"; +import { + buildFilterData, + calculateMetrics, + deleteAppliedFilters, + getFilteredData, + getSelectedFilter, +} from "./commonActions"; import API from "@/utils/axiosInstance"; +import { cloneDeep } from "lodash"; import { showFailureToast } from "@/actions/toastActions"; export const fetchQuayJobsData = () => async (dispatch, getState) => { try { dispatch({ type: TYPES.LOADING }); - const { start_date, end_date } = getState().cpt; + const { start_date, end_date } = getState().quay; const response = await API.get(API_ROUTES.QUAY_JOBS_API_V1, { params: { pretty: true, @@ -43,6 +51,7 @@ export const fetchQuayJobsData = () => async (dispatch, getState) => { end_date: endDate, }, }); + dispatch(applyFilters()); dispatch(tableReCalcValues()); } } catch (error) { @@ -78,7 +87,137 @@ export const sliceQuayTableRows = payload: results.slice(startIdx, endIdx), }); }; + +export const setQuayCatFilters = (category) => (dispatch, getState) => { + const filterData = [...getState().quay.filterData]; + const options = filterData.filter((item) => item.name === category)[0].value; + const list = options.map((item) => ({ name: item, value: item })); + + dispatch({ + type: TYPES.SET_QUAY_CATEGORY_FILTER, + payload: category, + }); + dispatch({ + type: TYPES.SET_QUAY_FILTER_OPTIONS, + payload: list, + }); +}; +export const removeQuayAppliedFilters = + (filterKey, filterValue, navigate) => (dispatch, getState) => { + const { start_date, end_date } = getState().quay; + + const appliedFilters = dispatch( + deleteAppliedFilters(filterKey, filterValue, "quay") + ); + + dispatch({ + type: TYPES.SET_QUAY_APPLIED_FILTERS, + payload: appliedFilters, + }); + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + dispatch(applyFilters()); + }; +export const applyFilters = () => (dispatch, getState) => { + const { appliedFilters } = getState().quay; + + const results = [...getState().quay.results]; + + const isFilterApplied = + Object.keys(appliedFilters).length > 0 && + Object.values(appliedFilters).flat().length > 0; + + const filtered = isFilterApplied + ? getFilteredData(appliedFilters, results) + : results; + + dispatch({ + type: TYPES.SET_FILTERED_DATA, + payload: filtered, + }); + dispatch(tableReCalcValues()); + dispatch(buildFilterData("quay")); +}; +export const setQuayAppliedFilters = (navigate) => (dispatch, getState) => { + const { selectedFilters, start_date, end_date } = getState().quay; + + const appliedFilterArr = selectedFilters.filter((i) => i.value.length > 0); + + const appliedFilters = {}; + appliedFilterArr.forEach((item) => { + appliedFilters[item["name"]] = item.value; + }); + + dispatch({ + type: TYPES.SET_QUAY_APPLIED_FILTERS, + payload: appliedFilters, + }); + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + dispatch(applyFilters()); +}; + +export const setSelectedFilterFromUrl = (params) => (dispatch, getState) => { + const selectedFilters = cloneDeep(getState().quay.selectedFilters); + for (const key in params) { + selectedFilters.find((i) => i.name === key).value = params[key].split(","); + } + dispatch({ + type: TYPES.SET_QUAY_SELECTED_FILTERS, + payload: selectedFilters, + }); +}; + +export const setSelectedFilter = + (selectedCategory, selectedOption, isFromMetrics) => (dispatch) => { + const selectedFilters = dispatch( + getSelectedFilter(selectedCategory, selectedOption, "quay", isFromMetrics) + ); + dispatch({ + type: TYPES.SET_QUAY_SELECTED_FILTERS, + payload: selectedFilters, + }); + }; +export const setQuayDateFilter = + (start_date, end_date, navigate) => (dispatch, getState) => { + const appliedFilters = getState().quay.appliedFilters; + + dispatch({ + type: TYPES.SET_QUAY_DATE_FILTER, + payload: { + start_date, + end_date, + }, + }); + + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + + dispatch(fetchQuayJobsData()); + }; + +export const setQuayOtherSummaryFilter = () => (dispatch, getState) => { + const filteredResults = [...getState().quay.filteredResults]; + const keyWordArr = ["success", "failure"]; + const data = filteredResults.filter( + (item) => !keyWordArr.includes(item.jobStatus?.toLowerCase()) + ); + dispatch({ + type: TYPES.SET_QUAY_FILTERED_DATA, + payload: data, + }); + dispatch(tableReCalcValues()); +}; + +export const getQuaySummary = () => (dispatch, getState) => { + const results = [...getState().quay.filteredResults]; + + const countObj = calculateMetrics(results); + dispatch({ + type: TYPES.SET_QUAY_SUMMARY, + payload: countObj, + }); +}; + export const tableReCalcValues = () => (dispatch) => { + dispatch(getQuaySummary()); dispatch(setQuayPageOptions(START_PAGE, DEFAULT_PER_PAGE)); dispatch(sliceQuayTableRows(0, DEFAULT_PER_PAGE)); }; diff --git a/frontend/src/actions/sortingActions.js b/frontend/src/actions/sortingActions.js index fae3fe7e..742820b5 100644 --- a/frontend/src/actions/sortingActions.js +++ b/frontend/src/actions/sortingActions.js @@ -8,7 +8,6 @@ import store from "@/store/store"; const { dispatch } = store; export const setActiveSortDir = (dir, currType) => { - console.log("hey 1"); if (currType === "cpt") { dispatch(setCPTSortDir(dir)); } else if (currType === "ocp") { @@ -20,8 +19,6 @@ export const setActiveSortDir = (dir, currType) => { } }; export const setActiveSortIndex = (index, currType) => { - console.log("hey 2"); - console.log(currType); if (currType === "cpt") { dispatch(setCPTSortIndex(index)); } else if (currType === "ocp") { diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js index fc4fdd6c..b50bc91b 100644 --- a/frontend/src/actions/telcoActions.js +++ b/frontend/src/actions/telcoActions.js @@ -6,14 +6,22 @@ import { START_PAGE, } from "@/assets/constants/paginationConstants"; import { appendDateFilter, appendQueryString } from "@/utils/helper.js"; +import { + buildFilterData, + calculateMetrics, + deleteAppliedFilters, + getFilteredData, + getSelectedFilter, +} from "./commonActions"; import API from "@/utils/axiosInstance"; +import { cloneDeep } from "lodash"; import { showFailureToast } from "@/actions/toastActions"; export const fetchTelcoJobsData = () => async (dispatch, getState) => { try { dispatch({ type: TYPES.LOADING }); - const { start_date, end_date } = getState().cpt; + const { start_date, end_date } = getState().telco; const response = await API.get(API_ROUTES.TELCO_JOBS_API_V1, { params: { pretty: true, @@ -41,6 +49,7 @@ export const fetchTelcoJobsData = () => async (dispatch, getState) => { end_date: endDate, }, }); + dispatch(applyFilters()); dispatch(tableReCalcValues()); } } catch (error) { @@ -75,7 +84,142 @@ export const sliceTelcoTableRows = payload: results.slice(startIdx, endIdx), }); }; +export const setTelcoCatFilters = (category) => (dispatch, getState) => { + const filterData = [...getState().telco.filterData]; + const options = filterData.filter((item) => item.name === category)[0].value; + const list = options.map((item) => ({ name: item, value: item })); + + dispatch({ + type: TYPES.SET_TELCO_CATEGORY_FILTER, + payload: category, + }); + dispatch({ + type: TYPES.SET_TELCO_FILTER_OPTIONS, + payload: list, + }); +}; +export const removeTelcoAppliedFilters = + (filterKey, filterValue, navigate) => (dispatch, getState) => { + const { start_date, end_date } = getState().telco; + + const appliedFilters = dispatch( + deleteAppliedFilters(filterKey, filterValue, "telco") + ); + + dispatch({ + type: TYPES.SET_TELCO_APPLIED_FILTERS, + payload: appliedFilters, + }); + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + dispatch(applyFilters()); + }; +export const applyFilters = () => (dispatch, getState) => { + const { appliedFilters } = getState().telco; + + const results = [...getState().telco.results]; + + const isFilterApplied = + Object.keys(appliedFilters).length > 0 && + Object.values(appliedFilters).flat().length > 0; + + const filtered = isFilterApplied + ? getFilteredData(appliedFilters, results) + : results; + + dispatch({ + type: TYPES.SET_FILTERED_DATA, + payload: filtered, + }); + dispatch(tableReCalcValues()); + dispatch(buildFilterData("telco")); +}; +export const setTelcoAppliedFilters = (navigate) => (dispatch, getState) => { + const { selectedFilters, start_date, end_date } = getState().telco; + + const appliedFilterArr = selectedFilters.filter((i) => i.value.length > 0); + + const appliedFilters = {}; + appliedFilterArr.forEach((item) => { + appliedFilters[item["name"]] = item.value; + }); + + dispatch({ + type: TYPES.SET_TELCO_APPLIED_FILTERS, + payload: appliedFilters, + }); + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + dispatch(applyFilters()); +}; + +export const setSelectedFilterFromUrl = (params) => (dispatch, getState) => { + const selectedFilters = cloneDeep(getState().telco.selectedFilters); + for (const key in params) { + selectedFilters.find((i) => i.name === key).value = params[key].split(","); + } + dispatch({ + type: TYPES.SET_TELCO_SELECTED_FILTERS, + payload: selectedFilters, + }); +}; + +export const setSelectedFilter = + (selectedCategory, selectedOption, isFromMetrics) => (dispatch) => { + const selectedFilters = dispatch( + getSelectedFilter( + selectedCategory, + selectedOption, + "telco", + isFromMetrics + ) + ); + dispatch({ + type: TYPES.TELCO_SET_SELECTED_FILTERS, + payload: selectedFilters, + }); + }; + +export const setTelcoDateFilter = + (start_date, end_date, navigate) => (dispatch, getState) => { + const appliedFilters = getState().telco.appliedFilters; + + dispatch({ + type: TYPES.SET_TELCO_DATE_FILTER, + payload: { + start_date, + end_date, + }, + }); + + appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); + + dispatch(fetchTelcoJobsData()); + }; + +export const getTelcoSummary = () => (dispatch, getState) => { + const results = [...getState().telco.filteredResults]; + + const countObj = calculateMetrics(results); + dispatch({ + type: TYPES.SET_TELCO_SUMMARY, + payload: countObj, + }); +}; + +export const setTelcoOtherSummaryFilter = () => (dispatch, getState) => { + const filteredResults = [...getState().telco.filteredResults]; + const keyWordArr = ["success", "failure"]; + const data = filteredResults.filter( + (item) => !keyWordArr.includes(item.jobStatus?.toLowerCase()) + ); + dispatch({ + type: TYPES.SET_TELCO_FILTERED_DATA, + payload: data, + }); + dispatch(tableReCalcValues()); +}; + export const tableReCalcValues = () => (dispatch) => { + dispatch(getTelcoSummary()); dispatch(setTelcoPageOptions(START_PAGE, DEFAULT_PER_PAGE)); dispatch(sliceTelcoTableRows(0, DEFAULT_PER_PAGE)); }; diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index 2cd769c9..a5205a46 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -52,6 +52,12 @@ export const SET_QUAY_PAGE = "SET_QUAY_PAGE"; export const SET_QUAY_PAGE_OPTIONS = "SET_QUAY_PAGE_OPTIONS"; export const SET_QUAY_INIT_JOBS = "SET_OCP_INIT_JOBS"; export const SET_QUAY_FILTERED_DATA = "SET_QUAY_FILTERED_DATA"; +export const SET_QUAY_CATEGORY_FILTER = "SET_QUAY_CATEGORY_FILTER"; +export const SET_QUAY_FILTER_OPTIONS = "SET_QUAY_FILTER_OPTIONS"; +export const SET_QUAY_FILTER_DATA = "SET_QUAY_FILTER_DATA"; +export const SET_QUAY_APPLIED_FILTERS = "SET_QUAY_APPLIED_FILTERS"; +export const SET_QUAY_SELECTED_FILTERS = "SET_QUAY_SELECTED_FILTERS"; +export const SET_QUAY_SUMMARY = "SET_QUAY_SUMMARY"; /* Telco Jobs */ export const SET_TELCO_JOBS_DATA = "SET_TELCO_JOBS_DATA"; export const SET_TELCO_SORT_INDEX = "SET_TELCO_SORT_INDEX"; @@ -60,3 +66,9 @@ export const SET_TELCO_PAGE = "SET_TELCO_PAGE"; export const SET_TELCO_PAGE_OPTIONS = "SET_TELCO_PAGE_OPTIONS"; export const SET_TELCO_INIT_JOBS = "SET_OCP_INIT_JOBS"; export const SET_TELCO_FILTERED_DATA = "SET_TELCO_FILTERED_DATA"; +export const SET_TELCO_CATEGORY_FILTER = "SET_TELCO_CATEGORY_FILTER"; +export const SET_TELCO_FILTER_OPTIONS = "SET_TELCO_FILTER_OPTIONS"; +export const SET_TELCO_FILTER_DATA = "SET_TELCO_FILTER_DATA"; +export const SET_TELCO_APPLIED_FILTERS = "SET_TELCO_APPLIED_FILTERS"; +export const SET_TELCO_SELECTED_FILTERS = "SET_TELCO_SELECTED_FILTERS"; +export const SET_TELCO_SUMMARY = "SET_TELCO_SUMMARY"; diff --git a/frontend/src/components/organisms/MetricsTab/index.jsx b/frontend/src/components/organisms/MetricsTab/index.jsx index abe7bc44..83e10839 100644 --- a/frontend/src/components/organisms/MetricsTab/index.jsx +++ b/frontend/src/components/organisms/MetricsTab/index.jsx @@ -6,6 +6,11 @@ import { AccordionItem, AccordionToggle, } from "@patternfly/react-core"; +import { + removeAppliedFilters, + setAppliedFilters, + setOtherSummaryFilter, +} from "@/actions/filterActions"; import MetricCard from "@/components/molecules/MetricCard"; import PropTypes from "prop-types"; @@ -21,6 +26,30 @@ const MetricsTab = (props) => { setExpanded(id); } }; + const removeStatusFilter = () => { + if ( + Array.isArray(props.appliedFilters["jobStatus"]) && + props.appliedFilters["jobStatus"].length > 0 + ) { + props.appliedFilters["jobStatus"].forEach((element) => { + props.updateSelectedFilter("jobStatus", element, true); + removeAppliedFilters( + "jobStatus", + element, + props.navigation, + props.type + ); + }); + } + }; + const applyStatusFilter = (value) => { + props.updateSelectedFilter("jobStatus", value, true); + setAppliedFilters(props.navigation, props.type); + }; + const applyOtherFilter = () => { + removeStatusFilter(); + setOtherSummaryFilter(props.type); + }; return ( @@ -39,23 +68,23 @@ const MetricsTab = (props) => { > @@ -65,8 +94,9 @@ const MetricsTab = (props) => { MetricsTab.propTypes = { totalItems: PropTypes.number, summary: PropTypes.object, - removeStatusFilter: PropTypes.func, - applyStatusFilter: PropTypes.func, - applyOtherFilter: PropTypes.func, + type: PropTypes.string, + updateSelectedFilter: PropTypes.func, + navigation: PropTypes.func, + appliedFilters: PropTypes.object, }; export default MetricsTab; diff --git a/frontend/src/components/organisms/TableFilters/index.jsx b/frontend/src/components/organisms/TableFilters/index.jsx index ddd44368..c5f5ae62 100644 --- a/frontend/src/components/organisms/TableFilters/index.jsx +++ b/frontend/src/components/organisms/TableFilters/index.jsx @@ -9,6 +9,12 @@ import { ToolbarContent, ToolbarItem, } from "@patternfly/react-core"; +import { + removeAppliedFilters, + setAppliedFilters, + setCatFilters, + setDateFilter, +} from "@/actions/filterActions.js"; import ColumnMenuFilter from "@/components/molecules/ColumnMenuFilter"; import DatePicker from "react-date-picker"; @@ -27,11 +33,7 @@ const TableFilter = (props) => { appliedFilters, start_date, end_date, - onCategoryChange, - onOptionsChange, - deleteItem, - startDateChangeHandler, - endDateChangeHandler, + navigation, type, showColumnMenu, setColumns, @@ -50,6 +52,23 @@ const TableFilter = (props) => { return filter.name; }; + const onCategoryChange = (_event, value) => { + setCatFilters(value, type); + }; + const onOptionsChange = () => { + setAppliedFilters(navigation, type); + }; + const deleteItem = (key, value) => { + removeAppliedFilters(key, value, navigation, type); + updateSelectedFilter(key, value, false); + }; + const startDateChangeHandler = (date, key) => { + setDateFilter(date, key, navigation, type); + }; + const endDateChangeHandler = (date, key) => { + setDateFilter(key, date, navigation, type); + }; + return ( <> @@ -128,15 +147,11 @@ TableFilter.propTypes = { appliedFilters: PropTypes.object, start_date: PropTypes.string, end_date: PropTypes.string, - onCategoryChange: PropTypes.func, - onOptionsChange: PropTypes.func, - deleteItem: PropTypes.func, - startDateChangeHandler: PropTypes.func, - endDateChangeHandler: PropTypes.func, type: PropTypes.string, showColumnMenu: PropTypes.bool, setColumns: PropTypes.func, selectedFilters: PropTypes.array, updateSelectedFilter: PropTypes.func, + navigation: PropTypes.func, }; export default TableFilter; diff --git a/frontend/src/components/organisms/TableLayout/index.jsx b/frontend/src/components/organisms/TableLayout/index.jsx index b84c72e3..caa62c0d 100644 --- a/frontend/src/components/organisms/TableLayout/index.jsx +++ b/frontend/src/components/organisms/TableLayout/index.jsx @@ -42,7 +42,7 @@ const TableLayout = (props) => { - {addExpansion &&
} + {addExpansion && } {tableColumns?.length > 0 && tableColumns.map((col, idx) => ( diff --git a/frontend/src/components/templates/Home/index.jsx b/frontend/src/components/templates/Home/index.jsx index 4a32451f..02d8b2a9 100644 --- a/frontend/src/components/templates/Home/index.jsx +++ b/frontend/src/components/templates/Home/index.jsx @@ -1,11 +1,7 @@ import { fetchOCPJobsData, - removeAppliedFilters, - setAppliedFilters, - setCatFilters, - setDateFilter, + setCPTDateFilter, setFilterFromURL, - setOtherSummaryFilter, setSelectedFilter, setSelectedFilterFromUrl, } from "@/actions/homeActions.js"; @@ -56,7 +52,7 @@ const Home = () => { } dispatch(setFilterFromURL(obj)); dispatch(setSelectedFilterFromUrl(params)); - dispatch(setDateFilter(startDate, endDate, navigate)); + dispatch(setCPTDateFilter(startDate, endDate, navigate)); } }, []); @@ -64,41 +60,6 @@ const Home = () => { dispatch(fetchOCPJobsData()); }, [dispatch]); // Filter Helper - const onCategoryChange = (_event, value) => { - dispatch(setCatFilters(value)); - }; - const onOptionsChange = () => { - dispatch(setAppliedFilters(navigate)); - }; - const deleteItem = (key, value) => { - dispatch(removeAppliedFilters(key, value, navigate)); - updateSelectedFilter(key, value, false); - }; - const startDateChangeHandler = (date, key) => { - dispatch(setDateFilter(date, key, navigate)); - }; - const endDateChangeHandler = (date, key) => { - dispatch(setDateFilter(key, date, navigate)); - }; - const removeStatusFilter = () => { - if ( - Array.isArray(appliedFilters["jobStatus"]) && - appliedFilters["jobStatus"].length > 0 - ) { - appliedFilters["jobStatus"].forEach((element) => { - updateSelectedFilter("jobStatus", element, true); - dispatch(removeAppliedFilters("jobStatus", element, navigate)); - }); - } - }; - const applyStatusFilter = (value) => { - updateSelectedFilter("jobStatus", value, true); - dispatch(setAppliedFilters(navigate)); - }; - const applyOtherFilter = () => { - removeStatusFilter(); - dispatch(setOtherSummaryFilter()); - }; const updateSelectedFilter = (category, value, isFromMetrics) => { dispatch(setSelectedFilter(category, value, isFromMetrics)); }; @@ -108,9 +69,10 @@ const Home = () => { { appliedFilters={appliedFilters} start_date={start_date} end_date={end_date} - onCategoryChange={onCategoryChange} - onOptionsChange={onOptionsChange} - deleteItem={deleteItem} - startDateChangeHandler={startDateChangeHandler} - endDateChangeHandler={endDateChangeHandler} type={"cpt"} selectedFilters={selectedFilters} updateSelectedFilter={updateSelectedFilter} showColumnMenu={false} + navigation={navigate} /> { const dispatch = useDispatch(); @@ -46,13 +39,6 @@ const OCP = () => { selectedFilters, } = useSelector((state) => state.ocp); - const modifidedTableFilters = useMemo( - () => - tableFilters.filter( - (item) => item.value !== "endDate" && item.value !== "startDate" - ), - [tableFilters] - ); useEffect(() => { if (searchParams.size > 0) { // date filter is set apart @@ -68,7 +54,7 @@ const OCP = () => { } dispatch(setFilterFromURL(obj)); dispatch(setSelectedFilterFromUrl(params)); - dispatch(setDateFilter(startDate, endDate, navigate)); + dispatch(setOCPDateFilter(startDate, endDate, navigate)); } }, []); @@ -76,76 +62,18 @@ const OCP = () => { dispatch(fetchOCPJobs()); }, [dispatch]); - //Sorting - const setActiveSortDir = (dir) => { - dispatch(setOCPSortDir(dir)); - }; - const setActiveSortIndex = (index) => { - dispatch(setOCPSortIndex(index)); - }; - const handleOnSort = () => { - dispatch(sortTable("ocp")); - }; - // Sorting - - // // Pagination Helper - // const onSetPage = useCallback( - // (_evt, newPage, _perPage, startIdx, endIdx) => { - // dispatch(setPage(newPage)); - // dispatch(sliceOCPTableRows(startIdx, endIdx)); - // }, - // [dispatch] - // ); - // const onPerPageSelect = useCallback( - // (_evt, newPerPage, newPage, startIdx, endIdx) => { - // dispatch(setPageOptions(newPage, newPerPage)); - // dispatch(sliceOCPTableRows(startIdx, endIdx)); - // }, - // [dispatch] - // ); - // // Pagination helper - /* Summary Tab Filter*/ - const removeStatusFilter = () => { - if ( - Array.isArray(appliedFilters["jobStatus"]) && - appliedFilters["jobStatus"].length > 0 - ) { - appliedFilters["jobStatus"].forEach((element) => { - updateSelectedFilter("jobStatus", element, true); - dispatch(removeAppliedFilters("jobStatus", element, navigate)); - }); - } - }; - const applyStatusFilter = (value) => { - updateSelectedFilter("jobStatus", value, true); - dispatch(setAppliedFilters(navigate)); - }; - const applyOtherFilter = () => { - removeStatusFilter(); - dispatch(setOtherSummaryFilter()); - }; + //Filter Helper + const modifidedTableFilters = useMemo( + () => + tableFilters.filter( + (item) => item.value !== "endDate" && item.value !== "startDate" + ), + [tableFilters] + ); const updateSelectedFilter = (category, value, isFromMetrics = false) => { dispatch(setSelectedFilter(category, value, isFromMetrics)); }; - /* Filter helper */ - - const onCategoryChange = (_event, value) => { - dispatch(setOCPCatFilters(value)); - }; - const onOptionsChange = () => { - dispatch(setAppliedFilters(navigate)); - }; - const deleteItem = (key, value) => { - dispatch(removeAppliedFilters(key, value, navigate)); - updateSelectedFilter(key, value); - }; - const startDateChangeHandler = (date, key) => { - dispatch(setDateFilter(date, key, navigate)); - }; - const endDateChangeHandler = (date, key) => { - dispatch(setDateFilter(key, date, navigate)); - }; //Row expansion const [expandedRunNames, setExpandedRunNames] = useState([]); const setRunExpanded = (run, isExpanding = true) => { @@ -172,9 +100,10 @@ const OCP = () => { { appliedFilters={appliedFilters} start_date={start_date} end_date={end_date} - onCategoryChange={onCategoryChange} - onOptionsChange={onOptionsChange} - deleteItem={deleteItem} - startDateChangeHandler={startDateChangeHandler} - endDateChangeHandler={endDateChangeHandler} type={"ocp"} showColumnMenu={true} setColumns={setColumns} selectedFilters={selectedFilters} updateSelectedFilter={updateSelectedFilter} + navigation={navigate} /> { tableColumns={tableColumns} activeSortIndex={activeSortIndex} activeSortDir={activeSortDir} - setActiveSortDir={setActiveSortDir} - setActiveSortIndex={setActiveSortIndex} - handleOnSort={handleOnSort} page={page} perPage={perPage} totalItems={filteredResults.length} diff --git a/frontend/src/components/templates/Quay/index.jsx b/frontend/src/components/templates/Quay/index.jsx index e60e45a3..efee6d1e 100644 --- a/frontend/src/components/templates/Quay/index.jsx +++ b/frontend/src/components/templates/Quay/index.jsx @@ -1,12 +1,15 @@ +import { fetchQuayJobsData, setSelectedFilter } from "@/actions/quayActions.js"; import { useDispatch, useSelector } from "react-redux"; +import { useEffect, useMemo } from "react"; +import MetricsTab from "@/components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; import TableLayout from "@/components/organisms/TableLayout"; -import { fetchQuayJobsData } from "@/actions/quayActions.js"; -import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; const Quay = () => { const dispatch = useDispatch(); + const navigate = useNavigate(); const { tableData, @@ -16,14 +19,58 @@ const Quay = () => { page, perPage, filteredResults, + tableFilters, + filterOptions, + categoryFilterValue, + filterData, + appliedFilters, + start_date, + end_date, + selectedFilters, + summary, } = useSelector((state) => state.quay); useEffect(() => { dispatch(fetchQuayJobsData()); }, [dispatch]); + //Filter Helper + const modifidedTableFilters = useMemo( + () => + tableFilters.filter( + (item) => item.value !== "endDate" && item.value !== "startDate" + ), + [tableFilters] + ); + const updateSelectedFilter = (category, value, isFromMetrics) => { + dispatch(setSelectedFilter(category, value, isFromMetrics)); + }; + //Filter Helper + return ( <> + + { const dispatch = useDispatch(); + const navigate = useNavigate(); + const { tableData, tableColumns, @@ -14,14 +22,57 @@ const Telco = () => { page, perPage, filteredResults, + tableFilters, + filterOptions, + categoryFilterValue, + filterData, + appliedFilters, + start_date, + end_date, + selectedFilters, + summary, } = useSelector((state) => state.telco); useEffect(() => { dispatch(fetchTelcoJobsData()); }, [dispatch]); + //Filter Helper + const modifidedTableFilters = useMemo( + () => + tableFilters.filter( + (item) => item.value !== "endDate" && item.value !== "startDate" + ), + [tableFilters] + ); + const updateSelectedFilter = (category, value, isFromMetrics) => { + dispatch(setSelectedFilter(category, value, isFromMetrics)); + }; + //Filter Helper return ( <> + + { @@ -61,6 +72,18 @@ const QuayReducer = (state = initialState, action = {}) => { return { ...state, tableData: payload }; case TYPES.SET_QUAY_FILTERED_DATA: return { ...state, filteredResults: payload }; + case TYPES.SET_QUAY_FILTER_OPTIONS: + return { ...state, filterOptions: payload }; + case TYPES.SET_QUAY_CATEGORY_FILTER: + return { ...state, categoryFilterValue: payload }; + case TYPES.SET_QUAY_FILTER_DATA: + return { ...state, filterData: payload }; + case TYPES.SET_QUAY_APPLIED_FILTERS: + return { ...state, appliedFilters: payload }; + case TYPES.SET_QUAY_SELECTED_FILTERS: + return { ...state, selectedFilters: payload }; + case TYPES.SET_QUAY_SUMMARY: + return { ...state, summary: payload }; default: return state; } diff --git a/frontend/src/reducers/telcoReducer.js b/frontend/src/reducers/telcoReducer.js index 9abb6422..315d27ec 100644 --- a/frontend/src/reducers/telcoReducer.js +++ b/frontend/src/reducers/telcoReducer.js @@ -27,13 +27,25 @@ const initialState = { { name: "Node Name", value: "nodeName" }, { name: "Status", value: "jobStatus" }, ], + selectedFilters: [ + { name: "benchmark", value: [] }, + { name: "releaseStream", value: [] }, + { name: "TELCOVersion", value: [] }, + { name: "cpu_util", value: [] }, + { name: "nodeName", value: [] }, + { name: "jobStatus", value: [] }, + ], filterData: [], filteredResults: [], + categoryFilterValue: "Benchmark", + filterOptions: [], + appliedFilters: {}, activeSortDir: null, activeSortIndex: null, tableData: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, + summary: {}, }; const TelcoReducer = (state = initialState, action = {}) => { @@ -63,6 +75,18 @@ const TelcoReducer = (state = initialState, action = {}) => { return { ...state, tableData: payload }; case TYPES.SET_TELCO_FILTERED_DATA: return { ...state, filteredResults: payload }; + case TYPES.SET_TELCO_CATEGORY_FILTER: + return { ...state, categoryFilterValue: payload }; + case TYPES.SET_TELCO_FILTER_OPTIONS: + return { ...state, filterOptions: payload }; + case TYPES.SET_TELCO_FILTER_DATA: + return { ...state, filterData: payload }; + case TYPES.SET_TELCO_APPLIED_FILTERS: + return { ...state, appliedFilters: payload }; + case TYPES.SET_TELCO_SELECTED_FILTERS: + return { ...state, selectedFilters: payload }; + case TYPES.SET_TELCO_SUMMARY: + return { ...state, summary: payload }; default: return state; } From 2102ade8fa5ba029b8d69b2df176efc67a7ef2fb Mon Sep 17 00:00:00 2001 From: MVarshini Date: Tue, 20 Aug 2024 21:46:27 +0530 Subject: [PATCH 3/8] graphs --- frontend/src/actions/ocpActions.js | 41 +++++++++-------- frontend/src/actions/quayActions.js | 45 ++++++++++++++++++- frontend/src/actions/telcoActions.js | 44 ++++++++++++++++++ frontend/src/actions/types.js | 5 +++ .../src/assets/constants/metadataConstants.js | 3 ++ .../src/components/atoms/PlotGraph/index.jsx | 2 +- .../molecules/ExpandedRow/index.jsx | 38 +++++++++++++--- .../molecules/MultiSelectBox/index.jsx | 1 - .../components/molecules/TableRows/index.jsx | 1 + .../src/components/templates/OCP/index.jsx | 2 +- .../src/components/templates/Quay/index.jsx | 38 ++++++++++++++-- .../src/components/templates/Telco/index.jsx | 34 ++++++++++++-- frontend/src/reducers/quayReducer.js | 26 +++++++++++ frontend/src/reducers/telcoReducer.js | 37 ++++++++++++--- 14 files changed, 274 insertions(+), 43 deletions(-) diff --git a/frontend/src/actions/ocpActions.js b/frontend/src/actions/ocpActions.js index 0638ece8..aefca386 100644 --- a/frontend/src/actions/ocpActions.js +++ b/frontend/src/actions/ocpActions.js @@ -217,27 +217,30 @@ export const getOCPSummary = () => (dispatch, getState) => { }); }; -export const fetchGraphData = (uuid) => async (dispatch, getState) => { - try { - dispatch({ type: TYPES.GRAPH_LOADING }); - - const graphData = getState().ocp.graphData; - const hasData = graphData.filter((a) => a.uuid === uuid).length > 0; - if (!hasData) { - const response = await API.get(`${API_ROUTES.OCP_GRAPH_API_V1}/${uuid}`); - - if (response.status === 200) { - dispatch({ - type: TYPES.SET_OCP_GRAPH_DATA, - payload: { uuid, data: response.data }, - }); +export const fetchGraphData = + (uuid, nodeName) => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.GRAPH_LOADING }); + + const graphData = getState().ocp.graphData; + const hasData = graphData.filter((a) => a.uuid === uuid).length > 0; + if (!hasData) { + const response = await API.get( + `${API_ROUTES.OCP_GRAPH_API_V1}/${uuid}` + ); + + if (response.status === 200) { + dispatch({ + type: TYPES.SET_OCP_GRAPH_DATA, + payload: { uuid, data: [[nodeName, response.data]] }, + }); + } } + } catch (error) { + dispatch(showFailureToast()); } - } catch (error) { - dispatch(showFailureToast()); - } - dispatch({ type: TYPES.GRAPH_COMPLETED }); -}; + dispatch({ type: TYPES.GRAPH_COMPLETED }); + }; export const setTableColumns = (key, isAdding) => (dispatch, getState) => { let tableColumns = [...getState().ocp.tableColumns]; diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js index fa33e26e..c558376e 100644 --- a/frontend/src/actions/quayActions.js +++ b/frontend/src/actions/quayActions.js @@ -13,9 +13,9 @@ import { getFilteredData, getSelectedFilter, } from "./commonActions"; +import { cloneDeep, result } from "lodash"; import API from "@/utils/axiosInstance"; -import { cloneDeep } from "lodash"; import { showFailureToast } from "@/actions/toastActions"; export const fetchQuayJobsData = () => async (dispatch, getState) => { @@ -216,6 +216,49 @@ export const getQuaySummary = () => (dispatch, getState) => { }); }; +export const setTableColumns = (key, isAdding) => (dispatch, getState) => { + let tableColumns = [...getState().quay.tableColumns]; + const tableFilters = getState().quay.tableFilters; + + if (isAdding) { + const filterObj = tableFilters.find((item) => item.value === key); + tableColumns.push(filterObj); + } else { + tableColumns = tableColumns.filter((item) => item.value !== key); + } + + dispatch({ + type: TYPES.SET_QUAY_COLUMNS, + payload: tableColumns, + }); +}; + +export const fetchGraphData = (uuid) => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.GRAPH_LOADING }); + + const graphData = getState().ocp.graphData; + const hasData = graphData.filter((a) => a.uuid === uuid).length > 0; + if (!hasData) { + const response = await API.get(`${API_ROUTES.QUAY_GRAPH_API_V1}/${uuid}`); + + if (response.status === 200) { + const result = Object.keys(response.data).map((key) => [ + key, + response.data[key], + ]); + dispatch({ + type: TYPES.SET_QUAY_GRAPH_DATA, + payload: { uuid, data: result }, + }); + } + } + } catch (error) { + dispatch(showFailureToast()); + } + dispatch({ type: TYPES.GRAPH_COMPLETED }); +}; + export const tableReCalcValues = () => (dispatch) => { dispatch(getQuaySummary()); dispatch(setQuayPageOptions(START_PAGE, DEFAULT_PER_PAGE)); diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js index b50bc91b..ac815997 100644 --- a/frontend/src/actions/telcoActions.js +++ b/frontend/src/actions/telcoActions.js @@ -218,6 +218,50 @@ export const setTelcoOtherSummaryFilter = () => (dispatch, getState) => { dispatch(tableReCalcValues()); }; +export const setTableColumns = (key, isAdding) => (dispatch, getState) => { + let tableColumns = [...getState().telco.tableColumns]; + const tableFilters = getState().telco.tableFilters; + + if (isAdding) { + const filterObj = tableFilters.find((item) => item.value === key); + tableColumns.push(filterObj); + } else { + tableColumns = tableColumns.filter((item) => item.value !== key); + } + + dispatch({ + type: TYPES.SET_TELCO_COLUMNS, + payload: tableColumns, + }); +}; +export const fetchGraphData = + (uuid, encryption) => async (dispatch, getState) => { + try { + dispatch({ type: TYPES.GRAPH_LOADING }); + + const graphData = getState().ocp.graphData; + const hasData = graphData.filter((a) => a.uuid === uuid).length > 0; + if (!hasData) { + const response = await API.get( + `${API_ROUTES.TELCO_GRAPH_API_V1}/${uuid}/${encryption}` + ); + + if (response.status === 200) { + const result = Object.keys(response.data).map((key) => [ + key, + response.data[key], + ]); + dispatch({ + type: TYPES.SET_TELCO_GRAPH_DATA, + payload: { uuid, data: result }, + }); + } + } + } catch (error) { + dispatch(showFailureToast()); + } + dispatch({ type: TYPES.GRAPH_COMPLETED }); + }; export const tableReCalcValues = () => (dispatch) => { dispatch(getTelcoSummary()); dispatch(setTelcoPageOptions(START_PAGE, DEFAULT_PER_PAGE)); diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index a5205a46..1384d515 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -58,8 +58,11 @@ export const SET_QUAY_FILTER_DATA = "SET_QUAY_FILTER_DATA"; export const SET_QUAY_APPLIED_FILTERS = "SET_QUAY_APPLIED_FILTERS"; export const SET_QUAY_SELECTED_FILTERS = "SET_QUAY_SELECTED_FILTERS"; export const SET_QUAY_SUMMARY = "SET_QUAY_SUMMARY"; +export const SET_QUAY_COLUMNS = "SET_QUAY_COLUMNS"; +export const SET_QUAY_GRAPH_DATA = "SET_QUAY_GRAPH_DATA"; /* Telco Jobs */ export const SET_TELCO_JOBS_DATA = "SET_TELCO_JOBS_DATA"; +export const SET_TELCO_DATE_FILTER = "SET_TELCO_DATE_FILTER"; export const SET_TELCO_SORT_INDEX = "SET_TELCO_SORT_INDEX"; export const SET_TELCO_SORT_DIR = "SET_TELCO_SORT_DIR"; export const SET_TELCO_PAGE = "SET_TELCO_PAGE"; @@ -72,3 +75,5 @@ export const SET_TELCO_FILTER_DATA = "SET_TELCO_FILTER_DATA"; export const SET_TELCO_APPLIED_FILTERS = "SET_TELCO_APPLIED_FILTERS"; export const SET_TELCO_SELECTED_FILTERS = "SET_TELCO_SELECTED_FILTERS"; export const SET_TELCO_SUMMARY = "SET_TELCO_SUMMARY"; +export const SET_TELCO_COLUMNS = "SET_TELCO_COLUMNS"; +export const SET_TELCO_GRAPH_DATA = "SET_TELCO_GRAPH_DATA"; diff --git a/frontend/src/assets/constants/metadataConstants.js b/frontend/src/assets/constants/metadataConstants.js index e459310e..122850d7 100644 --- a/frontend/src/assets/constants/metadataConstants.js +++ b/frontend/src/assets/constants/metadataConstants.js @@ -1,3 +1,6 @@ export const CLUSTER = "CLUSTER"; export const NODE_TYPE = "NODE_TYPE"; export const NODE_COUNT = "NODE_COUNT"; +export const API_RESULTS = "Quay API Status Codes"; +export const LATENCY_RESULTS = "Quay Latencies"; +export const IMAGE_RESULTS = "Quay Image Status Codes"; diff --git a/frontend/src/components/atoms/PlotGraph/index.jsx b/frontend/src/components/atoms/PlotGraph/index.jsx index f19c103a..182496f7 100644 --- a/frontend/src/components/atoms/PlotGraph/index.jsx +++ b/frontend/src/components/atoms/PlotGraph/index.jsx @@ -4,7 +4,7 @@ import PropTypes from "prop-types"; const PlotGraph = (props) => { return ( diff --git a/frontend/src/components/molecules/ExpandedRow/index.jsx b/frontend/src/components/molecules/ExpandedRow/index.jsx index 0edff39e..b141b2eb 100644 --- a/frontend/src/components/molecules/ExpandedRow/index.jsx +++ b/frontend/src/components/molecules/ExpandedRow/index.jsx @@ -9,6 +9,7 @@ import PlotGraph from "@/components/atoms/PlotGraph"; import PropTypes from "prop-types"; import TasksInfo from "@/components/molecules/TasksInfo"; import { uid } from "@/utils/helper.js"; +import { useMemo } from "react"; import { useSelector } from "react-redux"; const RowContent = (props) => { @@ -22,13 +23,23 @@ const RowContent = (props) => { return hasData; }; - const content = [ - { heading: "Cluster config", category: CONSTANTS.CLUSTER }, - { heading: "Node Type", category: CONSTANTS.NODE_TYPE }, - { heading: "Node Count", category: CONSTANTS.NODE_COUNT }, - ]; + + const content = useMemo(() => { + return [ + { heading: "Cluster config", category: CONSTANTS.CLUSTER }, + { heading: "Node Type", category: CONSTANTS.NODE_TYPE }, + { heading: "Node Count", category: CONSTANTS.NODE_COUNT }, + ]; + }, []); const isGraphLoading = useSelector((state) => state.loading.isGraphLoading); + const graphTitle = useMemo(() => { + return { + apiResults: CONSTANTS.API_RESULTS, + latencyResults: CONSTANTS.LATENCY_RESULTS, + imageResults: CONSTANTS.IMAGE_RESULTS, + }; + }, []); return ( @@ -56,10 +67,23 @@ const RowContent = (props) => { - {isGraphLoading ? ( + {isGraphLoading && !hasGraphData(props.item.uuid) ? (
) : hasGraphData(props.item.uuid) ? ( - + getGraphData(props.item.uuid)[0]?.data.length === 0 ? ( +
No data to plot
+ ) : ( + getGraphData(props.item.uuid)[0]?.data?.map((bit) => { + return ( + <> + + {graphTitle[bit[0]] ?? bit[0]} + + + + ); + }) + ) ) : (
No data to plot
)} diff --git a/frontend/src/components/molecules/MultiSelectBox/index.jsx b/frontend/src/components/molecules/MultiSelectBox/index.jsx index 7acbf263..72b56123 100644 --- a/frontend/src/components/molecules/MultiSelectBox/index.jsx +++ b/frontend/src/components/molecules/MultiSelectBox/index.jsx @@ -16,7 +16,6 @@ const MultiSelectBox = (props) => { const [isOpen, setIsOpen] = useState(false); const [isDirty, setIsDirty] = useState(false); const onSelect = (value) => { - console.log("selected", value); setIsDirty(true); props.onChange(props.currCategory, value); }; diff --git a/frontend/src/components/molecules/TableRows/index.jsx b/frontend/src/components/molecules/TableRows/index.jsx index e876b732..8f227391 100644 --- a/frontend/src/components/molecules/TableRows/index.jsx +++ b/frontend/src/components/molecules/TableRows/index.jsx @@ -36,6 +36,7 @@ const TableRows = (props) => {
{ : otherExpandedRunNames; }); if (isExpanding) { - dispatch(fetchGraphData(run.uuid)); + dispatch(fetchGraphData(run.uuid, run.benchmark)); } }; diff --git a/frontend/src/components/templates/Quay/index.jsx b/frontend/src/components/templates/Quay/index.jsx index efee6d1e..0e549649 100644 --- a/frontend/src/components/templates/Quay/index.jsx +++ b/frontend/src/components/templates/Quay/index.jsx @@ -1,6 +1,11 @@ -import { fetchQuayJobsData, setSelectedFilter } from "@/actions/quayActions.js"; +import { + fetchGraphData, + fetchQuayJobsData, + setSelectedFilter, + setTableColumns, +} from "@/actions/quayActions.js"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { useEffect, useMemo } from "react"; import MetricsTab from "@/components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; @@ -27,6 +32,7 @@ const Quay = () => { start_date, end_date, selectedFilters, + graphData, summary, } = useSelector((state) => state.quay); @@ -46,7 +52,27 @@ const Quay = () => { dispatch(setSelectedFilter(category, value, isFromMetrics)); }; //Filter Helper + //Row expansion + const [expandedRunNames, setExpandedRunNames] = useState([]); + const setRunExpanded = (run, isExpanding = true) => { + setExpandedRunNames((prevExpanded) => { + const otherExpandedRunNames = prevExpanded.filter((r) => r !== run.uuid); + return isExpanding + ? [...otherExpandedRunNames, run.uuid] + : otherExpandedRunNames; + }); + if (isExpanding) { + dispatch(fetchGraphData(run.uuid)); + } + }; + const isRunExpanded = useCallback( + (run) => expandedRunNames.includes(run.uuid), + [expandedRunNames] + ); + const setColumns = (value, isAdding) => { + dispatch(setTableColumns(value, isAdding)); + }; return ( <> { type={"quay"} selectedFilters={selectedFilters} updateSelectedFilter={updateSelectedFilter} - showColumnMenu={false} + showColumnMenu={true} + setColumns={setColumns} navigation={navigate} /> { perPage={perPage} totalItems={filteredResults.length} type={"quay"} - addExpansion={false} + addExpansion={true} + isRunExpanded={isRunExpanded} + setRunExpanded={setRunExpanded} + graphData={graphData} /> ); diff --git a/frontend/src/components/templates/Telco/index.jsx b/frontend/src/components/templates/Telco/index.jsx index 8dcd2fe4..799330d3 100644 --- a/frontend/src/components/templates/Telco/index.jsx +++ b/frontend/src/components/templates/Telco/index.jsx @@ -1,9 +1,11 @@ import { + fetchGraphData, fetchTelcoJobsData, setSelectedFilter, + setTableColumns, } from "@/actions/telcoActions.js"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { useEffect, useMemo } from "react"; import MetricsTab from "@/components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; @@ -31,6 +33,7 @@ const Telco = () => { end_date, selectedFilters, summary, + graphData, } = useSelector((state) => state.telco); useEffect(() => { @@ -49,6 +52,27 @@ const Telco = () => { dispatch(setSelectedFilter(category, value, isFromMetrics)); }; //Filter Helper + //Row expansion + const [expandedRunNames, setExpandedRunNames] = useState([]); + const setRunExpanded = (run, isExpanding = true) => { + setExpandedRunNames((prevExpanded) => { + const otherExpandedRunNames = prevExpanded.filter((r) => r !== run.uuid); + return isExpanding + ? [...otherExpandedRunNames, run.uuid] + : otherExpandedRunNames; + }); + if (isExpanding) { + dispatch(fetchGraphData(run.uuid, run.encryptedData)); + } + }; + + const isRunExpanded = useCallback( + (run) => expandedRunNames.includes(run.uuid), + [expandedRunNames] + ); + const setColumns = (value, isAdding) => { + dispatch(setTableColumns(value, isAdding)); + }; return ( <> { type={"telco"} updateSelectedFilter={updateSelectedFilter} selectedFilters={selectedFilters} - showColumnMenu={false} + showColumnMenu={true} + setColumns={setColumns} navigation={navigate} /> { perPage={perPage} totalItems={filteredResults.length} type={"telco"} - addExpansion={false} + addExpansion={true} + isRunExpanded={isRunExpanded} + setRunExpanded={setRunExpanded} + graphData={graphData} /> ); diff --git a/frontend/src/reducers/quayReducer.js b/frontend/src/reducers/quayReducer.js index a52d84b5..c8f2a37d 100644 --- a/frontend/src/reducers/quayReducer.js +++ b/frontend/src/reducers/quayReducer.js @@ -32,6 +32,27 @@ const initialState = { { name: "workerNodesCount", value: [] }, { name: "jobStatus", value: [] }, ], + clusterMetaData: [ + { name: "Release Binary", value: "releaseStream" }, + { name: "Cluster Name", value: "clusterName" }, + { name: "Cluster Type", value: "clusterType" }, + { name: "Network Type", value: "networkType" }, + { name: "Benchmark Status", value: "jobStatus" }, + { name: "Duration", value: "jobDuration" }, + { name: "Test ID", value: "uuid" }, + ], + nodeKeys: [ + { name: "Master", value: "masterNodesCount" }, + { name: "Worker", value: "workerNodesType" }, + { name: "Infra", value: "infraNodesType" }, + { name: "Workload", value: "benchmark" }, + ], + nodeCount: [ + { name: "Master", value: "masterNodesCount" }, + { name: "Worker", value: "workerNodesCount" }, + { name: "Infra", value: "infraNodesCount" }, + { name: "Total", value: "totalNodesCount" }, + ], filterData: [], filteredResults: [], filterOptions: [], @@ -40,6 +61,7 @@ const initialState = { activeSortDir: null, activeSortIndex: null, tableData: [], + graphData: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, summary: {}, @@ -84,6 +106,10 @@ const QuayReducer = (state = initialState, action = {}) => { return { ...state, selectedFilters: payload }; case TYPES.SET_QUAY_SUMMARY: return { ...state, summary: payload }; + case TYPES.SET_QUAY_COLUMNS: + return { ...state, tableColumns: payload }; + case TYPES.SET_QUAY_GRAPH_DATA: + return { ...state, graphData: [...state.graphData, payload] }; default: return state; } diff --git a/frontend/src/reducers/telcoReducer.js b/frontend/src/reducers/telcoReducer.js index 315d27ec..e87ff820 100644 --- a/frontend/src/reducers/telcoReducer.js +++ b/frontend/src/reducers/telcoReducer.js @@ -12,8 +12,7 @@ const initialState = { tableColumns: [ { name: "Benchmark", value: "benchmark" }, { name: "Release Stream", value: "releaseStream" }, - { name: "Build", value: "TELCOVersion" }, - { name: "CPU", value: "cpu_util" }, + { name: "CPU", value: "cpu" }, { name: "Node Name", value: "nodeName" }, { name: "Start Date", value: "startDate" }, { name: "End Date", value: "endDate" }, @@ -22,19 +21,40 @@ const initialState = { tableFilters: [ { name: "Benchmark", value: "benchmark" }, { name: "Release Stream", value: "releaseStream" }, - { name: "Build", value: "TELCOVersion" }, - { name: "CPU", value: "cpu_util" }, + { name: "Build", value: "ocpVersion" }, + { name: "CPU", value: "cpu" }, { name: "Node Name", value: "nodeName" }, { name: "Status", value: "jobStatus" }, ], selectedFilters: [ { name: "benchmark", value: [] }, { name: "releaseStream", value: [] }, - { name: "TELCOVersion", value: [] }, - { name: "cpu_util", value: [] }, + { name: "ocpVersion", value: [] }, + { name: "cpu", value: [] }, { name: "nodeName", value: [] }, { name: "jobStatus", value: [] }, ], + clusterMetaData: [ + { name: "Release Binary", value: "releaseStream" }, + { name: "Cluster Name", value: "clusterName" }, + { name: "Cluster Type", value: "clusterType" }, + { name: "Network Type", value: "networkType" }, + { name: "Benchmark Status", value: "jobStatus" }, + { name: "Duration", value: "jobDuration" }, + { name: "Test ID", value: "uuid" }, + ], + nodeKeys: [ + { name: "Master", value: "masterNodesCount" }, + { name: "Worker", value: "workerNodesType" }, + { name: "Infra", value: "infraNodesType" }, + { name: "Workload", value: "benchmark" }, + ], + nodeCount: [ + { name: "Master", value: "masterNodesCount" }, + { name: "Worker", value: "workerNodesCount" }, + { name: "Infra", value: "infraNodesCount" }, + { name: "Total", value: "totalNodesCount" }, + ], filterData: [], filteredResults: [], categoryFilterValue: "Benchmark", @@ -43,6 +63,7 @@ const initialState = { activeSortDir: null, activeSortIndex: null, tableData: [], + graphData: [], page: START_PAGE, perPage: DEFAULT_PER_PAGE, summary: {}, @@ -87,6 +108,10 @@ const TelcoReducer = (state = initialState, action = {}) => { return { ...state, selectedFilters: payload }; case TYPES.SET_TELCO_SUMMARY: return { ...state, summary: payload }; + case TYPES.SET_TELCO_COLUMNS: + return { ...state, tableColumns: payload }; + case TYPES.SET_TELCO_GRAPH_DATA: + return { ...state, graphData: [...state.graphData, payload] }; default: return state; } From da6a7541578703530d0d5077d586d0f9cf679926 Mon Sep 17 00:00:00 2001 From: MVarshini Date: Tue, 27 Aug 2024 14:07:52 +0530 Subject: [PATCH 4/8] telco type update --- frontend/src/actions/quayActions.js | 10 +++++----- frontend/src/actions/telcoActions.js | 4 ++-- frontend/src/actions/types.js | 2 +- .../src/components/molecules/MultiSelectBox/index.jsx | 1 - 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js index c558376e..fd65e821 100644 --- a/frontend/src/actions/quayActions.js +++ b/frontend/src/actions/quayActions.js @@ -13,9 +13,9 @@ import { getFilteredData, getSelectedFilter, } from "./commonActions"; -import { cloneDeep, result } from "lodash"; import API from "@/utils/axiosInstance"; +import { cloneDeep } from "lodash"; import { showFailureToast } from "@/actions/toastActions"; export const fetchQuayJobsData = () => async (dispatch, getState) => { @@ -25,10 +25,10 @@ export const fetchQuayJobsData = () => async (dispatch, getState) => { const response = await API.get(API_ROUTES.QUAY_JOBS_API_V1, { params: { pretty: true, - start_date: "2022-08-16", - end_date: "2024-08-16", - // ...(start_date && { start_date }), - // ...(end_date && { end_date }), + // start_date: "2022-08-16", + // end_date: "2024-08-16", + ...(start_date && { start_date }), + ...(end_date && { end_date }), }, }); if (response?.data?.results?.length > 0) { diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js index ac815997..f72d9623 100644 --- a/frontend/src/actions/telcoActions.js +++ b/frontend/src/actions/telcoActions.js @@ -127,7 +127,7 @@ export const applyFilters = () => (dispatch, getState) => { : results; dispatch({ - type: TYPES.SET_FILTERED_DATA, + type: TYPES.SET_TELCO_FILTERED_DATA, payload: filtered, }); dispatch(tableReCalcValues()); @@ -173,7 +173,7 @@ export const setSelectedFilter = ) ); dispatch({ - type: TYPES.TELCO_SET_SELECTED_FILTERS, + type: TYPES.SET_TELCO_SELECTED_FILTERS, payload: selectedFilters, }); }; diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index 1384d515..ee7654ae 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -67,7 +67,7 @@ export const SET_TELCO_SORT_INDEX = "SET_TELCO_SORT_INDEX"; export const SET_TELCO_SORT_DIR = "SET_TELCO_SORT_DIR"; export const SET_TELCO_PAGE = "SET_TELCO_PAGE"; export const SET_TELCO_PAGE_OPTIONS = "SET_TELCO_PAGE_OPTIONS"; -export const SET_TELCO_INIT_JOBS = "SET_OCP_INIT_JOBS"; +export const SET_TELCO_INIT_JOBS = "SET_TELCO_INIT_JOBS"; export const SET_TELCO_FILTERED_DATA = "SET_TELCO_FILTERED_DATA"; export const SET_TELCO_CATEGORY_FILTER = "SET_TELCO_CATEGORY_FILTER"; export const SET_TELCO_FILTER_OPTIONS = "SET_TELCO_FILTER_OPTIONS"; diff --git a/frontend/src/components/molecules/MultiSelectBox/index.jsx b/frontend/src/components/molecules/MultiSelectBox/index.jsx index 72b56123..9f601786 100644 --- a/frontend/src/components/molecules/MultiSelectBox/index.jsx +++ b/frontend/src/components/molecules/MultiSelectBox/index.jsx @@ -32,7 +32,6 @@ const MultiSelectBox = (props) => { setIsDirty(false); }; const toggle = (toggleRef) => { - console.log(props.selected); return ( Date: Tue, 27 Aug 2024 19:04:41 +0530 Subject: [PATCH 5/8] Splunk Links in Telco: --- frontend/src/actions/telcoActions.js | 19 ++-- .../src/assets/constants/splunkConstants.js | 22 +++++ .../components/atoms/GrafanaLink/index.jsx | 62 +++++++++++++ .../src/components/atoms/SplunkLink/index.jsx | 87 +++++++++++++++++++ .../molecules/ExpandedRow/index.jsx | 2 +- .../components/molecules/TasksInfo/index.jsx | 73 +++++----------- .../components/molecules/TasksInfo/index.less | 4 +- 7 files changed, 208 insertions(+), 61 deletions(-) create mode 100644 frontend/src/assets/constants/splunkConstants.js create mode 100644 frontend/src/components/atoms/GrafanaLink/index.jsx create mode 100644 frontend/src/components/atoms/SplunkLink/index.jsx diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js index f72d9623..f04ab3c4 100644 --- a/frontend/src/actions/telcoActions.js +++ b/frontend/src/actions/telcoActions.js @@ -29,11 +29,20 @@ export const fetchTelcoJobsData = () => async (dispatch, getState) => { ...(end_date && { end_date }), }, }); - if (response?.data?.results?.length > 0) { + if (response.status === 200) { const startDate = response.data.startDate, endDate = response.data.endDate; //on initial load startDate and endDate are empty, so from response append to url appendDateFilter(startDate, endDate); + dispatch({ + type: TYPES.SET_TELCO_DATE_FILTER, + payload: { + start_date: startDate, + end_date: endDate, + }, + }); + } + if (response?.data?.results?.length > 0) { dispatch({ type: TYPES.SET_TELCO_JOBS_DATA, payload: response.data.results, @@ -42,13 +51,7 @@ export const fetchTelcoJobsData = () => async (dispatch, getState) => { type: TYPES.SET_TELCO_FILTERED_DATA, payload: response.data.results, }); - dispatch({ - type: TYPES.SET_TELCO_DATE_FILTER, - payload: { - start_date: startDate, - end_date: endDate, - }, - }); + dispatch(applyFilters()); dispatch(tableReCalcValues()); } diff --git a/frontend/src/assets/constants/splunkConstants.js b/frontend/src/assets/constants/splunkConstants.js new file mode 100644 index 00000000..bd00b0be --- /dev/null +++ b/frontend/src/assets/constants/splunkConstants.js @@ -0,0 +1,22 @@ +export const SPLUNK_BASE_URL = + "https://rhcorporate.splunkcloud.com/en-GB/app/search/"; + +export const BENCHMARK_URL = { + cyclictest: "cyclictest_kpis", + cpu_util: "cpu_util_kpis", + deployment: "deployment_kpis", + oslat: "oslat_kpis", + ptp: "ptp_kpis", + reboot: "reboot_kpis", + "rfc-2544": "rfc2544_", +}; + +export const THRESHOLD_VALUE = 0.03; +export const CPU_UTIL_QUERY = `form.high_cpu_treshhold=${THRESHOLD_VALUE}&form.selected_duration=*`; +export const CHART_COMPARISON_QUERY = `form.charts_comparison=ocp_version`; +export const OCP_VIEW_QUERY = `form.ocp_view=ocp_version`; +export const REBOOT_QUERY = `form.reboot_type=soft_reboot`; + +export const BUBBLE_CHART_LEGEND_QUERY = "form.bubble_chart_legend="; +export const RFC_LEGEND_VALUE = "kernel"; +export const PTP_LEGEND_VALUE = "ocp_build"; diff --git a/frontend/src/components/atoms/GrafanaLink/index.jsx b/frontend/src/components/atoms/GrafanaLink/index.jsx new file mode 100644 index 00000000..f4b01c30 --- /dev/null +++ b/frontend/src/components/atoms/GrafanaLink/index.jsx @@ -0,0 +1,62 @@ +import * as CONSTANTS from "@/assets/constants/grafanaConstants"; + +import GrafanaIcon from "@/assets/images/grafana-icon.png"; +import LinkIcon from "@/components/atoms/LinkIcon"; +import Proptypes from "prop-types"; +import { useMemo } from "react"; + +const GrafanaLink = (props) => { + const { config, startDate, endDate } = props; + const grafanaLink = useMemo(() => { + const ciSystem_lCase = config.ciSystem?.toLowerCase(); + const isProw = ciSystem_lCase === "prow"; + const discreteBenchmark = + CONSTANTS.ciSystemMap[ciSystem_lCase]?.[ciSystem_lCase?.benchmark]; + + const hasBenchmark = Object.prototype.hasOwnProperty.call( + CONSTANTS.ciSystemMap?.[ciSystem_lCase], + config.benchmark + ); + const datasource = isProw + ? CONSTANTS.PROW_DATASOURCE + : hasBenchmark + ? discreteBenchmark?.dataSource + : CONSTANTS.DEFAULT_DATASOURCE; + + const dashboardURL = + discreteBenchmark?.dashboardURL ?? CONSTANTS.DASHBOARD_KUBE_BURNER; + + const datePart = `&from=${startDate}&to=${endDate}`; + const uuidPart = `&var-uuid=${config.uuid}`; + + if (config.benchmark === CONSTANTS.QUAY_LOAD_TEST) + return `${CONSTANTS.GRAFANA_BASE_URL}${CONSTANTS.DASHBOARD_QUAY}${datePart}${uuidPart}`; + return `${CONSTANTS.GRAFANA_BASE_URL}${dashboardURL}${datasource}${datePart}&var-platform=${config.platform}"&var-workload=${config.benchmark}${uuidPart}`; + }, [ + config.benchmark, + config.ciSystem, + config.platform, + config.uuid, + endDate, + startDate, + ]); + + return ( + + ); +}; + +GrafanaLink.propTypes = { + config: Proptypes.object, + endDate: Proptypes.number, + startDate: Proptypes.number, +}; + +export default GrafanaLink; diff --git a/frontend/src/components/atoms/SplunkLink/index.jsx b/frontend/src/components/atoms/SplunkLink/index.jsx new file mode 100644 index 00000000..7b4b86b0 --- /dev/null +++ b/frontend/src/components/atoms/SplunkLink/index.jsx @@ -0,0 +1,87 @@ +import * as CONSTANTS from "@/assets/constants/splunkConstants"; + +import LinkIcon from "@/components/atoms/LinkIcon"; +import Proptypes from "prop-types"; +import SplunkIcon from "@/assets/images/splunk-icon.png"; +import { useMemo } from "react"; + +const CONSTANTSLink = (props) => { + const { config, startDate, endDate } = props; + const splunkLink = useMemo(() => { + const url = `${CONSTANTS.SPLUNK_BASE_URL}${ + CONSTANTS.BENCHMARK_URL[config.benchmark] + }`; + + const query = `form.global_time.earliest=${encodeURIComponent( + new Date(startDate).toISOString() + )}&form.global_time.latest=${encodeURIComponent( + new Date(endDate).toISOString() + )}&form.formal_tag=${encodeURIComponent( + config.formal + )}&form.ocp_version=${encodeURIComponent( + config.shortVersion + )}&&form.ocp_build=${encodeURIComponent( + config.ocpVersion + )}&form.node_name=${encodeURIComponent(config.nodeName)}& + &form.general_statistics=${encodeURIComponent(config.shortVersion)}`; + + const kernelQuery = `form.dashboard_kernels=${encodeURIComponent( + config.kernel + )}`; + + const histogramQuery = `form.histogram=${encodeURIComponent( + config.ocpVersion + )}`; + + switch (config.benchmark) { + case "cyclictest": { + return `${url}?${query}&${CONSTANTS.OCP_VIEW_QUERY}&${kernelQuery}`; + } + case "cpu_util": { + return `${url}?${query}&${CONSTANTS.CPU_UTIL_QUERY}&${kernelQuery}`; + } + case "deployment": { + return `${url}?${query}`; + } + case "oslat": { + return `${url}?${query}&${CONSTANTS.OCP_VIEW_QUERY}&${CONSTANTS.CHART_COMPARISON_QUERY}&${kernelQuery}`; + } + case "ptp": { + return `${url}?${query}&${CONSTANTS.BUBBLE_CHART_LEGEND_QUERY}${CONSTANTS.PTP_LEGEND_VALUE}&${kernelQuery}`; + } + case "reboot": { + return `${url}?${query}&${CONSTANTS.CHART_COMPARISON_QUERY}&${CONSTANTS.REBOOT_QUERY}&${kernelQuery}`; + } + case "rfc-2544": { + return `${url}?${query}&${CONSTANTS.BUBBLE_CHART_LEGEND_QUERY}${CONSTANTS.RFC_LEGEND_VALUE}&${histogramQuery}&${kernelQuery}`; + } + } + }, [ + config.benchmark, + config.formal, + config.kernel, + config.nodeName, + config.ocpVersion, + config.shortVersion, + endDate, + startDate, + ]); + + return ( + + ); +}; + +CONSTANTSLink.propTypes = { + config: Proptypes.object, + endDate: Proptypes.number, + startDate: Proptypes.number, +}; +export default CONSTANTSLink; diff --git a/frontend/src/components/molecules/ExpandedRow/index.jsx b/frontend/src/components/molecules/ExpandedRow/index.jsx index b141b2eb..981d5660 100644 --- a/frontend/src/components/molecules/ExpandedRow/index.jsx +++ b/frontend/src/components/molecules/ExpandedRow/index.jsx @@ -60,7 +60,7 @@ const RowContent = (props) => { Tasks ran - + diff --git a/frontend/src/components/molecules/TasksInfo/index.jsx b/frontend/src/components/molecules/TasksInfo/index.jsx index 4c385ec3..8d24e995 100644 --- a/frontend/src/components/molecules/TasksInfo/index.jsx +++ b/frontend/src/components/molecules/TasksInfo/index.jsx @@ -1,18 +1,17 @@ import "./index.less"; -import * as CONSTANTS from "@/assets/constants/grafanaConstants"; - import { CheckCircleIcon, ExclamationCircleIcon, ExclamationTriangleIcon, } from "@patternfly/react-icons"; -import GrafanaIcon from "@/assets/images/grafana-icon.png"; +import GrafanaLink from "@/components/atoms/GrafanaLink"; import JenkinsIcon from "@/assets/images/jenkins-icon.svg"; import LinkIcon from "@/components/atoms/LinkIcon"; import Proptypes from "prop-types"; import ProwIcon from "@/assets/images/prow-icon.png"; +import SplunkLink from "@/components/atoms/SplunkLink"; import { formatTime } from "@/helpers/Formatters.js"; import { useMemo } from "react"; @@ -33,63 +32,36 @@ const TasksInfo = (props) => { [config.jobStatus] ); - const grafanaLink = useMemo(() => { - const ciSystem_lCase = config.ciSystem?.toLowerCase(); - const isProw = ciSystem_lCase === "prow"; - const discreteBenchmark = - CONSTANTS.ciSystemMap[ciSystem_lCase]?.[ciSystem_lCase?.benchmark]; - - const hasBenchmark = Object.prototype.hasOwnProperty.call( - CONSTANTS.ciSystemMap?.[ciSystem_lCase], - config.benchmark - ); - const datasource = isProw - ? CONSTANTS.PROW_DATASOURCE - : hasBenchmark - ? discreteBenchmark?.dataSource - : CONSTANTS.DEFAULT_DATASOURCE; - - const dashboardURL = - discreteBenchmark?.dashboardURL ?? CONSTANTS.DASHBOARD_KUBE_BURNER; - - const datePart = `&from=${startDate}&to=${endDate}`; - const uuidPart = `&var-uuid=${config.uuid}`; - - if (config.benchmark === CONSTANTS.QUAY_LOAD_TEST) - return `${CONSTANTS.GRAFANA_BASE_URL}${CONSTANTS.DASHBOARD_QUAY}${datePart}${uuidPart}`; - return `${CONSTANTS.GRAFANA_BASE_URL}${dashboardURL}${datasource}${datePart}&var-platform=${config.platform}"&var-workload=${config.benchmark}${uuidPart}`; - }, [ - config.benchmark, - config.ciSystem, - config.platform, - config.uuid, - endDate, - startDate, - ]); - const icons = useMemo( () => ({ - failed: , - failure: , - success: , - upstream_failed: , + failed: , + failure: , + success: , + upstream_failed: , }), [] ); + return ( <>
{icons[status] ?? status.toUpperCase()}
{config.benchmark}
-
{`(${formatTime(config?.jobDuration)})`}
- +
+ {status !== "upstream_failed" + ? `(${formatTime(config?.jobDuration)})` + : "Skipped"} +
+ {props.type === "ocp" && ( + + )} + {props.type === "telco" && ( + + )} { }; TasksInfo.propTypes = { config: Proptypes.object, + type: Proptypes.string, }; export default TasksInfo; diff --git a/frontend/src/components/molecules/TasksInfo/index.less b/frontend/src/components/molecules/TasksInfo/index.less index dd088b46..e51880b8 100644 --- a/frontend/src/components/molecules/TasksInfo/index.less +++ b/frontend/src/components/molecules/TasksInfo/index.less @@ -1,5 +1,5 @@ .info-wrapper { display: flex; - justify-content: space-between; - width: 50%; + justify-content: space-evenly; + width: 35%; } \ No newline at end of file From e6785196b1f8c8a40b93933f8a22452436d74635 Mon Sep 17 00:00:00 2001 From: MVarshini Date: Tue, 27 Aug 2024 19:38:33 +0530 Subject: [PATCH 6/8] set date --- frontend/src/actions/homeActions.js | 15 +++++++++------ frontend/src/actions/ocpActions.js | 13 ++++++++----- frontend/src/actions/quayActions.js | 20 ++++++++++---------- frontend/src/actions/types.js | 2 +- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/frontend/src/actions/homeActions.js b/frontend/src/actions/homeActions.js index b8edfca1..68109d60 100644 --- a/frontend/src/actions/homeActions.js +++ b/frontend/src/actions/homeActions.js @@ -30,16 +30,11 @@ export const fetchOCPJobsData = () => async (dispatch, getState) => { ...(end_date && { end_date }), }, }); - if (response?.data?.results?.length > 0) { + if (response.status === 200) { const startDate = response.data.startDate, endDate = response.data.endDate; //on initial load startDate and endDate are empty, so from response append to url appendDateFilter(startDate, endDate); - - dispatch({ - type: TYPES.SET_CPT_JOBS_DATA, - payload: response.data.results, - }); dispatch({ type: TYPES.SET_CPT_DATE_FILTER, payload: { @@ -47,6 +42,14 @@ export const fetchOCPJobsData = () => async (dispatch, getState) => { end_date: endDate, }, }); + } + + if (response?.data?.results?.length > 0) { + dispatch({ + type: TYPES.SET_CPT_JOBS_DATA, + payload: response.data.results, + }); + dispatch(applyFilters()); dispatch(sortTable("cpt")); dispatch(tableReCalcValues()); diff --git a/frontend/src/actions/ocpActions.js b/frontend/src/actions/ocpActions.js index aefca386..9a2f14c4 100644 --- a/frontend/src/actions/ocpActions.js +++ b/frontend/src/actions/ocpActions.js @@ -30,15 +30,11 @@ export const fetchOCPJobs = () => async (dispatch, getState) => { ...(end_date && { end_date }), }, }); - if (response?.data?.results?.length > 0) { + if (response.status === 200) { const startDate = response.data.startDate, endDate = response.data.endDate; //on initial load startDate and endDate are empty, so from response append to url appendDateFilter(startDate, endDate); - dispatch({ - type: TYPES.SET_OCP_JOBS_DATA, - payload: response.data.results, - }); dispatch({ type: TYPES.SET_OCP_DATE_FILTER, payload: { @@ -46,6 +42,13 @@ export const fetchOCPJobs = () => async (dispatch, getState) => { end_date: endDate, }, }); + } + if (response?.data?.results?.length > 0) { + dispatch({ + type: TYPES.SET_OCP_JOBS_DATA, + payload: response.data.results, + }); + dispatch(applyFilters()); dispatch(sortTable("ocp")); dispatch(tableReCalcValues()); diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js index fd65e821..2abea9b2 100644 --- a/frontend/src/actions/quayActions.js +++ b/frontend/src/actions/quayActions.js @@ -25,17 +25,24 @@ export const fetchQuayJobsData = () => async (dispatch, getState) => { const response = await API.get(API_ROUTES.QUAY_JOBS_API_V1, { params: { pretty: true, - // start_date: "2022-08-16", - // end_date: "2024-08-16", ...(start_date && { start_date }), ...(end_date && { end_date }), }, }); - if (response?.data?.results?.length > 0) { + if (response.status === 200) { const startDate = response.data.startDate, endDate = response.data.endDate; //on initial load startDate and endDate are empty, so from response append to url appendDateFilter(startDate, endDate); + dispatch({ + type: TYPES.SET_QUAY_DATE_FILTER, + payload: { + start_date: startDate, + end_date: endDate, + }, + }); + } + if (response?.data?.results?.length > 0) { dispatch({ type: TYPES.SET_QUAY_JOBS_DATA, payload: response.data.results, @@ -44,13 +51,6 @@ export const fetchQuayJobsData = () => async (dispatch, getState) => { type: TYPES.SET_QUAY_FILTERED_DATA, payload: response.data.results, }); - dispatch({ - type: TYPES.SET_QUAY_DATE_FILTER, - payload: { - start_date: startDate, - end_date: endDate, - }, - }); dispatch(applyFilters()); dispatch(tableReCalcValues()); } diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index ee7654ae..1804cf21 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -50,7 +50,7 @@ export const SET_QUAY_SORT_INDEX = "SET_QUAY_SORT_INDEX"; export const SET_QUAY_SORT_DIR = "SET_QUAY_SORT_DIR"; export const SET_QUAY_PAGE = "SET_QUAY_PAGE"; export const SET_QUAY_PAGE_OPTIONS = "SET_QUAY_PAGE_OPTIONS"; -export const SET_QUAY_INIT_JOBS = "SET_OCP_INIT_JOBS"; +export const SET_QUAY_INIT_JOBS = "SET_QUAY_INIT_JOBS"; export const SET_QUAY_FILTERED_DATA = "SET_QUAY_FILTERED_DATA"; export const SET_QUAY_CATEGORY_FILTER = "SET_QUAY_CATEGORY_FILTER"; export const SET_QUAY_FILTER_OPTIONS = "SET_QUAY_FILTER_OPTIONS"; From e2efcd20ae592e73313e0c26f8a3f54be8bb53c1 Mon Sep 17 00:00:00 2001 From: MVarshini Date: Tue, 27 Aug 2024 22:24:15 +0530 Subject: [PATCH 7/8] Telco missing value --- .../molecules/MetaDataRow/index.jsx | 33 +++++++++++++++++-- frontend/src/reducers/telcoReducer.js | 9 ++--- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/molecules/MetaDataRow/index.jsx b/frontend/src/components/molecules/MetaDataRow/index.jsx index c6d46e57..99ec7e91 100644 --- a/frontend/src/components/molecules/MetaDataRow/index.jsx +++ b/frontend/src/components/molecules/MetaDataRow/index.jsx @@ -1,9 +1,15 @@ import "./index.less"; +import { + CheckCircleIcon, + ExclamationCircleIcon, + ExclamationTriangleIcon, +} from "@patternfly/react-icons"; import { Table, Tbody, Th, Thead, Tr } from "@patternfly/react-table"; import PropTypes from "prop-types"; import { Title } from "@patternfly/react-core"; +import { formatTime } from "@/helpers/Formatters.js"; import { uid } from "@/utils/helper.js"; import { useMemo } from "react"; import { useSelector } from "react-redux"; @@ -25,7 +31,24 @@ const MetadataRow = (props) => { NODE_COUNT: nodeCount, }; }, [clusterMetaData, nodeKeys, nodeCount]); - + const defaultValue = useMemo(() => { + return { + clusterType: "SNO spoke", + networkType: "OVNKubernetes", + masterNodesCount: "1", + master_type: "Baremetal", + totalNodesCount: "1", + }; + }, []); + const icons = useMemo( + () => ({ + failed: , + failure: , + success: , + upstream_failed: , + }), + [] + ); return ( <> @@ -44,7 +67,13 @@ const MetadataRow = (props) => { {memoObj[props?.category].map((item) => ( <Tr key={uid()}> <Th>{item.name}</Th> - <Th>{props.metadata[item.value]}</Th> + <Th> + {item.value === "jobDuration" + ? formatTime(props.metadata[item.value]) + : item.value === "jobStatus" + ? icons[props.metadata[item.value]] + : props.metadata[item.value] ?? defaultValue[item.value]} + </Th> </Tr> ))} </Tbody> diff --git a/frontend/src/reducers/telcoReducer.js b/frontend/src/reducers/telcoReducer.js index e87ff820..15ab045f 100644 --- a/frontend/src/reducers/telcoReducer.js +++ b/frontend/src/reducers/telcoReducer.js @@ -36,23 +36,18 @@ const initialState = { ], clusterMetaData: [ { name: "Release Binary", value: "releaseStream" }, - { name: "Cluster Name", value: "clusterName" }, + { name: "Cluster Name", value: "nodeName" }, { name: "Cluster Type", value: "clusterType" }, { name: "Network Type", value: "networkType" }, { name: "Benchmark Status", value: "jobStatus" }, { name: "Duration", value: "jobDuration" }, - { name: "Test ID", value: "uuid" }, ], nodeKeys: [ - { name: "Master", value: "masterNodesCount" }, - { name: "Worker", value: "workerNodesType" }, - { name: "Infra", value: "infraNodesType" }, + { name: "Master", value: "master_type" }, { name: "Workload", value: "benchmark" }, ], nodeCount: [ { name: "Master", value: "masterNodesCount" }, - { name: "Worker", value: "workerNodesCount" }, - { name: "Infra", value: "infraNodesCount" }, { name: "Total", value: "totalNodesCount" }, ], filterData: [], From 6a80aa08d6e9b4b45b172f4270f0ef6343fb79f2 Mon Sep 17 00:00:00 2001 From: MVarshini <varm@redhat.com> Date: Fri, 30 Aug 2024 18:30:45 +0530 Subject: [PATCH 8/8] PANDA-569 Bugs --- frontend/src/actions/quayActions.js | 8 ++- frontend/src/actions/telcoActions.js | 29 +++++++-- .../components/molecules/TableRows/index.jsx | 63 ++++++++++--------- .../organisms/TableLayout/index.jsx | 16 ++++- .../src/components/templates/Quay/index.jsx | 25 +++++++- .../src/components/templates/Telco/index.jsx | 28 ++++++++- frontend/src/reducers/ocpReducer.js | 2 +- frontend/src/reducers/quayReducer.js | 2 +- 8 files changed, 129 insertions(+), 44 deletions(-) diff --git a/frontend/src/actions/quayActions.js b/frontend/src/actions/quayActions.js index 2abea9b2..59795ed7 100644 --- a/frontend/src/actions/quayActions.js +++ b/frontend/src/actions/quayActions.js @@ -117,6 +117,7 @@ export const removeQuayAppliedFilters = appendQueryString({ ...appliedFilters, start_date, end_date }, navigate); dispatch(applyFilters()); }; + export const applyFilters = () => (dispatch, getState) => { const { appliedFilters } = getState().quay; @@ -131,7 +132,7 @@ export const applyFilters = () => (dispatch, getState) => { : results; dispatch({ - type: TYPES.SET_FILTERED_DATA, + type: TYPES.SET_QUAY_FILTERED_DATA, payload: filtered, }); dispatch(tableReCalcValues()); @@ -166,6 +167,11 @@ export const setSelectedFilterFromUrl = (params) => (dispatch, getState) => { }); }; +export const setFilterFromURL = (searchParams) => ({ + type: TYPES.SET_QUAY_APPLIED_FILTERS, + payload: searchParams, +}); + export const setSelectedFilter = (selectedCategory, selectedOption, isFromMetrics) => (dispatch) => { const selectedFilters = dispatch( diff --git a/frontend/src/actions/telcoActions.js b/frontend/src/actions/telcoActions.js index f04ab3c4..beaf04f9 100644 --- a/frontend/src/actions/telcoActions.js +++ b/frontend/src/actions/telcoActions.js @@ -154,6 +154,11 @@ export const setTelcoAppliedFilters = (navigate) => (dispatch, getState) => { dispatch(applyFilters()); }; +export const setFilterFromURL = (searchParams) => ({ + type: TYPES.SET_TELCO_APPLIED_FILTERS, + payload: searchParams, +}); + export const setSelectedFilterFromUrl = (params) => (dispatch, getState) => { const selectedFilters = cloneDeep(getState().telco.selectedFilters); for (const key in params) { @@ -238,7 +243,7 @@ export const setTableColumns = (key, isAdding) => (dispatch, getState) => { }); }; export const fetchGraphData = - (uuid, encryption) => async (dispatch, getState) => { + (benchmark, uuid, encryption) => async (dispatch, getState) => { try { dispatch({ type: TYPES.GRAPH_LOADING }); @@ -250,10 +255,24 @@ export const fetchGraphData = ); if (response.status === 200) { - const result = Object.keys(response.data).map((key) => [ - key, - response.data[key], - ]); + let result; + if ( + benchmark === "oslat" || + benchmark === "cyclictest" || + benchmark === "deployment" + ) { + const benchmarkData = response.data[benchmark]; + result = Object.keys(response.data[benchmark]).map((key) => [ + key, + benchmarkData[key], + ]); + } else { + result = Object.keys(response.data).map((key) => [ + key, + response.data[key], + ]); + } + dispatch({ type: TYPES.SET_TELCO_GRAPH_DATA, payload: { uuid, data: result }, diff --git a/frontend/src/components/molecules/TableRows/index.jsx b/frontend/src/components/molecules/TableRows/index.jsx index 8f227391..9a45e6d1 100644 --- a/frontend/src/components/molecules/TableRows/index.jsx +++ b/frontend/src/components/molecules/TableRows/index.jsx @@ -1,6 +1,6 @@ import "./index.less"; -import { ExpandableRowContent, Td, Tr } from "@patternfly/react-table"; +import { ExpandableRowContent, Tbody, Td, Tr } from "@patternfly/react-table"; import RowContent from "@/components/molecules/ExpandedRow"; import TableCell from "@/components/atoms/TableCell"; @@ -12,40 +12,43 @@ const TableRows = (props) => { return ( rows?.length > 0 && rows.map((item, rowIndex) => { - return ( - <> - <Tr key={uid()}> - {addExpansion && ( - <Td - expand={{ - rowIndex, - isExpanded: props?.isRunExpanded(item), - onToggle: () => - props?.setRunExpanded(item, !props?.isRunExpanded(item)), - expandId: `expandable-row${uid()}`, - }} - /> - )} + return addExpansion ? ( + <Tbody isExpanded={props?.isRunExpanded(item)} key={uid()}> + <Tr> + <Td + expand={{ + rowIndex, + isExpanded: props?.isRunExpanded(item), + onToggle: () => + props?.setRunExpanded(item, !props?.isRunExpanded(item)), + expandId: `expandable-row${uid()}`, + }} + /> {columns.map((col) => ( <TableCell key={uid()} col={col} item={item} /> ))} </Tr> - {addExpansion && ( - <Tr isExpanded={props?.isRunExpanded(item)}> - <Td colSpan={8}> - <ExpandableRowContent> - <RowContent - key={uid()} - item={item} - graphData={props.graphData} - type={props.type} - /> - </ExpandableRowContent> - </Td> - </Tr> - )} - </> + + <Tr isExpanded={props?.isRunExpanded(item)}> + <Td colSpan={8}> + <ExpandableRowContent> + <RowContent + key={uid()} + item={item} + graphData={props.graphData} + type={props.type} + /> + </ExpandableRowContent> + </Td> + </Tr> + </Tbody> + ) : ( + <Tr> + {columns.map((col) => ( + <TableCell key={uid()} col={col} item={item} /> + ))} + </Tr> ); }) ); diff --git a/frontend/src/components/organisms/TableLayout/index.jsx b/frontend/src/components/organisms/TableLayout/index.jsx index caa62c0d..500c1bc9 100644 --- a/frontend/src/components/organisms/TableLayout/index.jsx +++ b/frontend/src/components/organisms/TableLayout/index.jsx @@ -52,7 +52,19 @@ const TableLayout = (props) => { ))} </Tr> </Thead> - <Tbody isExpanded={addExpansion}> + {!addExpansion ? ( + <Tbody> + <TableRows + rows={tableData} + columns={tableColumns} + addExpansion={addExpansion} + isRunExpanded={props?.isRunExpanded} + setRunExpanded={props?.setRunExpanded} + graphData={props?.graphData} + type={props.type} + /> + </Tbody> + ) : ( <TableRows rows={tableData} columns={tableColumns} @@ -62,7 +74,7 @@ const TableLayout = (props) => { graphData={props?.graphData} type={props.type} /> - </Tbody> + )} </Table> <RenderPagination items={totalItems} diff --git a/frontend/src/components/templates/Quay/index.jsx b/frontend/src/components/templates/Quay/index.jsx index 0e549649..2f193fdf 100644 --- a/frontend/src/components/templates/Quay/index.jsx +++ b/frontend/src/components/templates/Quay/index.jsx @@ -1,20 +1,24 @@ import { fetchGraphData, fetchQuayJobsData, + setFilterFromURL, + setQuayDateFilter, setSelectedFilter, + setSelectedFilterFromUrl, setTableColumns, } from "@/actions/quayActions.js"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useSearchParams } from "react-router-dom"; import MetricsTab from "@/components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; import TableLayout from "@/components/organisms/TableLayout"; -import { useNavigate } from "react-router-dom"; const Quay = () => { const dispatch = useDispatch(); const navigate = useNavigate(); + const [searchParams] = useSearchParams(); const { tableData, @@ -40,6 +44,25 @@ const Quay = () => { dispatch(fetchQuayJobsData()); }, [dispatch]); + useEffect(() => { + if (searchParams.size > 0) { + // date filter is set apart + const startDate = searchParams.get("start_date"); + const endDate = searchParams.get("end_date"); + + searchParams.delete("start_date"); + searchParams.delete("end_date"); + const params = Object.fromEntries(searchParams); + const obj = {}; + for (const key in params) { + obj[key] = params[key].split(","); + } + dispatch(setFilterFromURL(obj)); + dispatch(setSelectedFilterFromUrl(params)); + dispatch(setQuayDateFilter(startDate, endDate, navigate)); + } + }, []); + //Filter Helper const modifidedTableFilters = useMemo( () => diff --git a/frontend/src/components/templates/Telco/index.jsx b/frontend/src/components/templates/Telco/index.jsx index 799330d3..66c2defa 100644 --- a/frontend/src/components/templates/Telco/index.jsx +++ b/frontend/src/components/templates/Telco/index.jsx @@ -1,21 +1,24 @@ import { fetchGraphData, fetchTelcoJobsData, + setFilterFromURL, setSelectedFilter, + setSelectedFilterFromUrl, setTableColumns, + setTelcoDateFilter, } from "@/actions/telcoActions.js"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { useNavigate, useSearchParams } from "react-router-dom"; import MetricsTab from "@/components/organisms/MetricsTab"; import TableFilter from "@/components/organisms/TableFilters"; import TableLayout from "@/components/organisms/TableLayout"; -import { useNavigate } from "react-router-dom"; const Telco = () => { const dispatch = useDispatch(); const navigate = useNavigate(); - + const [searchParams] = useSearchParams(); const { tableData, tableColumns, @@ -40,6 +43,25 @@ const Telco = () => { dispatch(fetchTelcoJobsData()); }, [dispatch]); + useEffect(() => { + if (searchParams.size > 0) { + // date filter is set apart + const startDate = searchParams.get("start_date"); + const endDate = searchParams.get("end_date"); + + searchParams.delete("start_date"); + searchParams.delete("end_date"); + const params = Object.fromEntries(searchParams); + const obj = {}; + for (const key in params) { + obj[key] = params[key].split(","); + } + dispatch(setFilterFromURL(obj)); + dispatch(setSelectedFilterFromUrl(params)); + dispatch(setTelcoDateFilter(startDate, endDate, navigate)); + } + }, []); + //Filter Helper const modifidedTableFilters = useMemo( () => @@ -62,7 +84,7 @@ const Telco = () => { : otherExpandedRunNames; }); if (isExpanding) { - dispatch(fetchGraphData(run.uuid, run.encryptedData)); + dispatch(fetchGraphData(run.benchmark, run.uuid, run.encryptedData)); } }; diff --git a/frontend/src/reducers/ocpReducer.js b/frontend/src/reducers/ocpReducer.js index 99b4d160..c422ff5e 100644 --- a/frontend/src/reducers/ocpReducer.js +++ b/frontend/src/reducers/ocpReducer.js @@ -68,7 +68,7 @@ const initialState = { { name: "Control Plane Architecture", value: "controlPlaneArch" }, ], nodeKeys: [ - { name: "Master", value: "masterNodesCount" }, + { name: "Master", value: "masterNodesType" }, { name: "Worker", value: "workerNodesType" }, { name: "Infra", value: "infraNodesType" }, { name: "Workload", value: "benchmark" }, diff --git a/frontend/src/reducers/quayReducer.js b/frontend/src/reducers/quayReducer.js index c8f2a37d..bc3ff723 100644 --- a/frontend/src/reducers/quayReducer.js +++ b/frontend/src/reducers/quayReducer.js @@ -42,7 +42,7 @@ const initialState = { { name: "Test ID", value: "uuid" }, ], nodeKeys: [ - { name: "Master", value: "masterNodesCount" }, + { name: "Master", value: "masterNodesType" }, { name: "Worker", value: "workerNodesType" }, { name: "Infra", value: "infraNodesType" }, { name: "Workload", value: "benchmark" },