Skip to content

Commit

Permalink
Add an ilab UI tab
Browse files Browse the repository at this point in the history
This relies on the ilab API in cloud-bulldozer#123, which in turn builds on the crucible
service in cloud-bulldozer#122.
  • Loading branch information
MVarshini authored and dbutenhof committed Oct 17, 2024
1 parent 956d9c3 commit dd075e9
Show file tree
Hide file tree
Showing 27 changed files with 787 additions and 641 deletions.
2 changes: 1 addition & 1 deletion frontend/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# Openshift Performance Dashbaord
# Openshift Performance Dashboard

## Dashboard directory structure

Expand Down
58 changes: 0 additions & 58 deletions frontend/src/App.js

This file was deleted.

2 changes: 2 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as APP_ROUTES from "./utils/routeConstants";
import { BrowserRouter, Route, Routes } from "react-router-dom";

import Home from "./components/templates/Home";
import ILab from "./components/templates/ILab";
import MainLayout from "./containers/MainLayout";
import OCP from "./components/templates/OCP";
import Quay from "./components/templates/Quay";
Expand All @@ -26,6 +27,7 @@ function App() {
<Route path={APP_ROUTES.OCP} element={<OCP />} />
<Route path={APP_ROUTES.QUAY} element={<Quay />} />
<Route path={APP_ROUTES.TELCO} element={<Telco />} />
<Route path={APP_ROUTES.ILAB} element={<ILab />} />
</Route>
</Routes>
</BrowserRouter>
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/actions/filterActions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fetchILabJobs, setIlabDateFilter } from "./ilabActions";
import {
removeCPTAppliedFilters,
setCPTAppliedFilters,
Expand Down Expand Up @@ -76,6 +77,9 @@ export const setDateFilter = (date, key, navigation, currType) => {
dispatch(setQuayDateFilter(date, key, navigation));
} else if (currType === "telco") {
dispatch(setTelcoDateFilter(date, key, navigation));
} else if (currType === "ilab") {
dispatch(setIlabDateFilter(date, key, navigation));
dispatch(fetchILabJobs());
}
};

Expand Down
213 changes: 213 additions & 0 deletions frontend/src/actions/ilabActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import * as API_ROUTES from "@/utils/apiConstants";
import * as TYPES from "./types.js";

import API from "@/utils/axiosInstance";
import { appendQueryString } from "@/utils/helper";
import { cloneDeep } from "lodash";
import { showFailureToast } from "@/actions/toastActions";

export const fetchILabJobs =
(shouldStartFresh = false) =>
async (dispatch, getState) => {
try {
dispatch({ type: TYPES.LOADING });
const { start_date, end_date, size, offset, results } = getState().ilab;
const response = await API.get(API_ROUTES.ILABS_JOBS_API_V1, {
params: {
...(start_date && { start_date }),
...(end_date && { end_date }),
...(size && { size }),
...(offset && { offset }),
},
});
if (response.status === 200 && response?.data?.results.length > 0) {
const startDate = response.data.startDate,
endDate = response.data.endDate;
dispatch({
type: TYPES.SET_ILAB_JOBS_DATA,
payload: shouldStartFresh
? response.data.results
: [...results, ...response.data.results],
});

dispatch({
type: TYPES.SET_ILAB_DATE_FILTER,
payload: {
start_date: startDate,
end_date: endDate,
},
});

dispatch({
type: TYPES.SET_ILAB_TOTAL_ITEMS,
payload: response.data.total,
});
dispatch({
type: TYPES.SET_ILAB_OFFSET,
payload: response.data.next_offset,
});

dispatch(tableReCalcValues());
}
} catch (error) {
dispatch(showFailureToast());
}
dispatch({ type: TYPES.COMPLETED });
};
export const sliceIlabTableRows =
(startIdx, endIdx) => (dispatch, getState) => {
const results = [...getState().ilab.results];

dispatch({
type: TYPES.SET_ILAB_INIT_JOBS,
payload: results.slice(startIdx, endIdx),
});
};
export const setIlabDateFilter =
(start_date, end_date, navigate) => (dispatch, getState) => {
const appliedFilters = getState().ilab.appliedFilters;

dispatch({
type: TYPES.SET_ILAB_DATE_FILTER,
payload: {
start_date,
end_date,
},
});

appendQueryString({ ...appliedFilters, start_date, end_date }, navigate);
};

export const fetchMetricsInfo = (uid) => async (dispatch) => {
try {
dispatch({ type: TYPES.LOADING });
const response = await API.get(`/api/v1/ilab/runs/${uid}/metrics`);
if (response.status === 200) {
if (
response.data.constructor === Object &&
Object.keys(response.data).length > 0
) {
dispatch({
type: TYPES.SET_ILAB_METRICS,
payload: { uid, metrics: Object.keys(response.data) },
});
}
}
} catch (error) {
console.error(error);
dispatch(showFailureToast());
}
dispatch({ type: TYPES.COMPLETED });
};

export const fetchPeriods = (uid) => async (dispatch) => {
try {
dispatch({ type: TYPES.LOADING });
const response = await API.get(`/api/v1/ilab/runs/${uid}/periods`);
if (response.status === 200) {
dispatch({
type: TYPES.SET_ILAB_PERIODS,
payload: { uid, periods: response.data },
});
}
} catch (error) {
console.error(
`ERROR (${error?.response?.status}): ${JSON.stringify(
error?.response?.data
)}`
);
dispatch(showFailureToast());
}
dispatch({ type: TYPES.COMPLETED });
};

export const fetchGraphData =
(uid, metric, primary_metric) => async (dispatch, getState) => {
try {
const periods = getState().ilab.periods.find((i) => i.uid == uid);
const graphData = cloneDeep(getState().ilab.graphData);
const filterData = graphData.filter((i) => i.uid !== uid);
dispatch({
type: TYPES.SET_ILAB_GRAPH_DATA,
payload: filterData,
});
const copyData = cloneDeep(filterData);
dispatch({ type: TYPES.GRAPH_LOADING });
let graphs = [];
periods?.periods?.forEach((p) => {
graphs.push({ metric: p.primary_metric, periods: [p.id] });
graphs.push({
metric,
aggregate: true,
periods: [p.id],
});
});
const response = await API.post(`/api/v1/ilab/runs/multigraph`, {
run: uid,
name: primary_metric,
graphs,
});
if (response.status === 200) {
copyData.push({
uid,
data: response.data.data,
layout: response.data.layout,
});
dispatch({
type: TYPES.SET_ILAB_GRAPH_DATA,
payload: copyData,
});
}
} catch (error) {
console.error(
`ERROR (${error?.response?.status}): ${JSON.stringify(
error?.response?.data
)}`
);
dispatch(showFailureToast());
}
dispatch({ type: TYPES.GRAPH_COMPLETED });
};

export const setIlabPage = (pageNo) => ({
type: TYPES.SET_ILAB_PAGE,
payload: pageNo,
});

export const setIlabPageOptions = (page, perPage) => ({
type: TYPES.SET_ILAB_PAGE_OPTIONS,
payload: { page, perPage },
});

export const checkIlabJobs = (newPage) => (dispatch, getState) => {
const results = cloneDeep(getState().ilab.results);
const { totalItems, perPage } = getState().ilab;

const startIdx = (newPage - 1) * perPage;
const endIdx = newPage * perPage;

if (
(typeof results[startIdx] === "undefined" ||
typeof results[endIdx] === "undefined") &&
results.length < totalItems
) {
dispatch(fetchILabJobs());
}
};

export const setSelectedMetrics = (id, metrics) => (dispatch, getState) => {
const metrics_selected = cloneDeep(getState().ilab.metrics_selected);
metrics_selected[id] = metrics;
dispatch({
type: TYPES.SET_ILAB_SELECTED_METRICS,
payload: metrics_selected,
});
};

export const tableReCalcValues = () => (dispatch, getState) => {
const { page, perPage } = getState().ilab;

const startIdx = page !== 1 ? (page - 1) * perPage : 0;
const endIdx = page !== 1 ? page * perPage - 1 : perPage;
dispatch(sliceIlabTableRows(startIdx, endIdx));
};
18 changes: 18 additions & 0 deletions frontend/src/actions/paginationActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@ import {
setCPTPageOptions,
sliceCPTTableRows,
} from "./homeActions";
import {
setIlabPage,
setIlabPageOptions,
sliceIlabTableRows,
} from "./ilabActions";
import { setOCPPage, setOCPPageOptions, sliceOCPTableRows } from "./ocpActions";
import { setQuayPage, setQuayPageOptions } from "./quayActions";
import { setTelcoPage, setTelcoPageOptions } from "./telcoActions";

import { checkIlabJobs } from "./ilabActions";

export const setPage = (newPage, currType) => (dispatch) => {
if (currType === "cpt") {
dispatch(setCPTPage(newPage));
Expand All @@ -15,6 +23,8 @@ export const setPage = (newPage, currType) => (dispatch) => {
dispatch(setQuayPage(newPage));
} else if (currType === "telco") {
dispatch(setTelcoPage(newPage));
} else if (currType === "ilab") {
dispatch(setIlabPage(newPage));
}
};

Expand All @@ -27,6 +37,8 @@ export const setPageOptions = (newPage, newPerPage, currType) => (dispatch) => {
dispatch(setQuayPageOptions(newPage, newPerPage));
} else if (currType === "telco") {
dispatch(setTelcoPageOptions(newPage, newPerPage));
} else if (currType === "ilab") {
dispatch(setIlabPageOptions(newPage, newPerPage));
}
};

Expand All @@ -35,5 +47,11 @@ export const sliceTableRows = (startIdx, endIdx, currType) => (dispatch) => {
dispatch(sliceCPTTableRows(startIdx, endIdx));
} else if (currType === "ocp") {
dispatch(sliceOCPTableRows(startIdx, endIdx));
} else if (currType === "ilab") {
dispatch(sliceIlabTableRows(startIdx, endIdx));
}
};

export const fetchNextJobs = (newPage) => (dispatch) => {
dispatch(checkIlabJobs(newPage));
};
12 changes: 12 additions & 0 deletions frontend/src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,15 @@ 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";
/* ILAB JOBS */
export const SET_ILAB_JOBS_DATA = "SET_ILAB_JOBS_DATA";
export const SET_ILAB_DATE_FILTER = "SET_ILAB_DATE_FILTER";
export const SET_ILAB_GRAPH_DATA = "SET_ILAB_GRAPH_DATA";
export const SET_ILAB_TOTAL_ITEMS = "SET_ILAB_TOTAL_ITEMS";
export const SET_ILAB_OFFSET = "SET_ILAB_OFFSET";
export const SET_ILAB_PAGE = "SET_ILAB_PAGE";
export const SET_ILAB_PAGE_OPTIONS = "SET_ILAB_PAGE_OPTIONS";
export const SET_ILAB_METRICS = "SET_ILAB_METRICS";
export const SET_ILAB_SELECTED_METRICS = "SET_ILAB_SELECTED_METRICS";
export const SET_ILAB_PERIODS = "SET_ILAB_PERIODS";
export const SET_ILAB_INIT_JOBS = "SET_ILAB_INIT_JOBS";
1 change: 1 addition & 0 deletions frontend/src/assets/constants/SidemenuConstants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export const HOME_NAV = "home";
export const QUAY_NAV = "quay";
export const OCP_NAV = "ocp";
export const TELCO_NAV = "telco";
export const ILAB_NAV = "ilab";
2 changes: 1 addition & 1 deletion frontend/src/components/molecules/ExpandedRow/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const RowContent = (props) => {
}, []);
return (
<Grid hasGutter>
<GridItem span={7}>
<GridItem span={3}>
<Card>
<CardBody>
{content.map((unit) => (
Expand Down
Loading

0 comments on commit dd075e9

Please sign in to comment.