diff --git a/litmus-portal/frontend/package-lock.json b/litmus-portal/frontend/package-lock.json index a6bda1492..eb16f1185 100644 --- a/litmus-portal/frontend/package-lock.json +++ b/litmus-portal/frontend/package-lock.json @@ -7682,11 +7682,6 @@ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", "dev": true }, - "deep-diff": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", - "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=" - }, "deep-equal": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", @@ -18613,14 +18608,6 @@ "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz", "integrity": "sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==" }, - "redux-logger": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", - "integrity": "sha1-91VZZvMJjzyIYExEnPC69XeCdL8=", - "requires": { - "deep-diff": "^0.3.5" - } - }, "redux-persist": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", diff --git a/litmus-portal/frontend/package.json b/litmus-portal/frontend/package.json index dedac484b..2c6d15524 100644 --- a/litmus-portal/frontend/package.json +++ b/litmus-portal/frontend/package.json @@ -47,7 +47,6 @@ "react-simple-maps": "^2.1.2", "redux": "^4.0.1", "redux-devtools-extension": "^2.13.8", - "redux-logger": "^3.0.6", "redux-persist": "^6.0.0", "redux-thunk": "^2.3.0", "subscriptions-transport-ws": "^0.9.17", @@ -89,7 +88,6 @@ "@types/react-redux": "^7.1.7", "@types/react-router-dom": "^5.1.3", "@types/react-simple-maps": "^1.0.3", - "@types/redux-logger": "^3.0.7", "@typescript-eslint/eslint-plugin": "^3.5.0", "@typescript-eslint/parser": "^3.5.0", "cross-env": "^5.2.0", diff --git a/litmus-portal/frontend/src/components/InfoFilled/index.tsx b/litmus-portal/frontend/src/components/InfoFilled/index.tsx index a690ec1bd..127342164 100644 --- a/litmus-portal/frontend/src/components/InfoFilled/index.tsx +++ b/litmus-portal/frontend/src/components/InfoFilled/index.tsx @@ -1,10 +1,10 @@ -import React from 'react'; -import Typography from '@material-ui/core/Typography'; -import { useSelector } from 'react-redux'; import { useTheme } from '@material-ui/core/styles'; -import useStyles from './styles'; +import Typography from '@material-ui/core/Typography'; +import React from 'react'; +import { useSelector } from 'react-redux'; import { RootState } from '../../redux/reducers'; import formatCount from '../../utils/formatCount'; +import useStyles from './styles'; interface CardValueData { color: string; @@ -51,6 +51,7 @@ const InfoFilledWrap: React.FC = () => { const cardArray = cardData.map((individualCard) => { return (
diff --git a/litmus-portal/frontend/src/containers/layouts/Unimodal/index.tsx b/litmus-portal/frontend/src/containers/layouts/Unimodal/index.tsx index b78ae061f..c9a2b5b12 100644 --- a/litmus-portal/frontend/src/containers/layouts/Unimodal/index.tsx +++ b/litmus-portal/frontend/src/containers/layouts/Unimodal/index.tsx @@ -1,11 +1,10 @@ -import React from 'react'; -import Modal from '@material-ui/core/Modal'; import Button from '@material-ui/core/Button'; +import Modal from '@material-ui/core/Modal'; +import React from 'react'; import useStyles from './styles'; /* DelUser, NewUserModal, ResetModal need to be shifted */ interface UnimodalProps { - children?: React.ReactNode; isOpen: boolean; handleClose: () => void; hasCloseBtn: boolean; @@ -21,7 +20,8 @@ const Unimodal: React.FC = ({ isDark, textAlign, }) => { - const styleProps = { textAlign, isDark }; + const isDarkBg = isDark ?? false; + const styleProps = { textAlign, isDarkBg }; const classes = useStyles(styleProps); return ( diff --git a/litmus-portal/frontend/src/containers/layouts/Unimodal/styles.ts b/litmus-portal/frontend/src/containers/layouts/Unimodal/styles.ts index 3687968b9..c3932bb32 100644 --- a/litmus-portal/frontend/src/containers/layouts/Unimodal/styles.ts +++ b/litmus-portal/frontend/src/containers/layouts/Unimodal/styles.ts @@ -6,7 +6,7 @@ const useStyles = makeStyles((theme: Theme) => ({ width: '70%', padding: '1rem', margin: '2rem auto', - background: props.isDark + background: props.isDarkBg ? theme.palette.editorBackground : theme.palette.common.white, borderRadius: 3, @@ -30,14 +30,14 @@ const useStyles = makeStyles((theme: Theme) => ({ minHeight: 0, minWidth: 0, borderRadius: 3, - color: props.isDark + color: props.isDarkBg ? theme.palette.secondary.contrastText : theme.palette.customColors.black(0.4), border: '1px solid', - borderColor: props.isDark + borderColor: props.isDarkBg ? theme.palette.customColors.white(0.2) : theme.palette.customColors.black(0.4), - marginLeft: props.isDark ? '82.5%' : '60%', + marginLeft: props.isDarkBg ? '82.5%' : '60%', marginTop: theme.spacing(5), }), diff --git a/litmus-portal/frontend/src/graphql/quries.ts b/litmus-portal/frontend/src/graphql/quries.ts index 62e01fbb1..7b92b0243 100644 --- a/litmus-portal/frontend/src/graphql/quries.ts +++ b/litmus-portal/frontend/src/graphql/quries.ts @@ -11,6 +11,7 @@ export const WORKFLOW_DETAILS = gql` cluster_name last_updated cluster_type + cluster_id } } `; diff --git a/litmus-portal/frontend/src/graphql/subscriptions.ts b/litmus-portal/frontend/src/graphql/subscriptions.ts index 3d89274f3..8b53ad56f 100644 --- a/litmus-portal/frontend/src/graphql/subscriptions.ts +++ b/litmus-portal/frontend/src/graphql/subscriptions.ts @@ -1,4 +1,3 @@ -/* eslint-disable import/prefer-default-export */ import { gql } from '@apollo/client'; export const WORKFLOW_EVENTS = gql` @@ -11,6 +10,15 @@ export const WORKFLOW_EVENTS = gql` project_id cluster_name last_updated + cluster_id + } + } +`; + +export const WORKFLOW_LOGS = gql` + subscription podLog($podDetails: PodLogRequest!) { + getPodLog(podDetails: $podDetails) { + log } } `; diff --git a/litmus-portal/frontend/src/models/graphql/podLog.ts b/litmus-portal/frontend/src/models/graphql/podLog.ts new file mode 100644 index 000000000..f9449bdb3 --- /dev/null +++ b/litmus-portal/frontend/src/models/graphql/podLog.ts @@ -0,0 +1,25 @@ +export interface PodLogRequest { + cluster_id: string; + workflow_run_id: string; + pod_name: string; + pod_namespace: string; + pod_type: string; + exp_pod?: string; + runner_pod?: string; + chaos_namespace?: string; +} + +export interface PodLogResponse { + workflow_run_id: string; + pod_name: string; + pod_type: string; + log: string; +} + +export interface PodLogVars { + podDetails: PodLogRequest; +} + +export interface PodLog { + getPodLog: PodLogResponse; +} diff --git a/litmus-portal/frontend/src/models/graphql/workflowData.ts b/litmus-portal/frontend/src/models/graphql/workflowData.ts index 6a9328936..768e7e3fd 100644 --- a/litmus-portal/frontend/src/models/graphql/workflowData.ts +++ b/litmus-portal/frontend/src/models/graphql/workflowData.ts @@ -15,6 +15,7 @@ export interface ChaosData { export interface Node { children: string[] | null; finishedAt: string; + message: string; name: string; phase: string; startedAt: string; @@ -47,6 +48,7 @@ export interface WorkflowRun { workflow_name: string; workflow_run_id: string; cluster_type: string; + cluster_id: string; } export interface Workflow { diff --git a/litmus-portal/frontend/src/models/redux/nodeSelection.ts b/litmus-portal/frontend/src/models/redux/nodeSelection.ts index e66f0b4b4..53352275b 100644 --- a/litmus-portal/frontend/src/models/redux/nodeSelection.ts +++ b/litmus-portal/frontend/src/models/redux/nodeSelection.ts @@ -1,5 +1,9 @@ import { Node } from '../graphql/workflowData'; +export interface SelectedNode extends Node { + pod_name: string; +} + export enum NodeSelectionActions { SELECT_NODE = 'SELECT_NODE', } @@ -11,5 +15,5 @@ interface NodeSelectionActionType { export type NodeSelectionAction = NodeSelectionActionType< typeof NodeSelectionActions.SELECT_NODE, - Node + SelectedNode >; diff --git a/litmus-portal/frontend/src/models/redux/tabs.ts b/litmus-portal/frontend/src/models/redux/tabs.ts index 1661f351d..8aabe3a42 100644 --- a/litmus-portal/frontend/src/models/redux/tabs.ts +++ b/litmus-portal/frontend/src/models/redux/tabs.ts @@ -1,11 +1,13 @@ export interface TabState { workflows: number; settings: number; + node: number; } export enum TabActions { CHANGE_WORKFLOWS_TAB = 'CHANGE_WORKFLOWS_TAB', CHANGE_SETTINGS_TAB = 'CHANGE_SETTINGS_TAB', + CHANGE_WORKFLOW_DETAILS_TAB = 'CHANGE_WORKFLOW_DETAILS_TAB', } interface TabActionType { @@ -15,4 +17,5 @@ interface TabActionType { export type TabAction = | TabActionType - | TabActionType; + | TabActionType + | TabActionType; diff --git a/litmus-portal/frontend/src/pages/WorkflowDetails/TopNavButtons.tsx b/litmus-portal/frontend/src/pages/WorkflowDetails/TopNavButtons.tsx index f0c58cf79..f3047a5ea 100644 --- a/litmus-portal/frontend/src/pages/WorkflowDetails/TopNavButtons.tsx +++ b/litmus-portal/frontend/src/pages/WorkflowDetails/TopNavButtons.tsx @@ -91,10 +91,10 @@ const TopNavButtons: React.FC = ({ isToggled, setIsToggled }) => { return (
-
+
-
+
{AnalyticsButton()} {ExportButton()} {InfoButton()} diff --git a/litmus-portal/frontend/src/pages/WorkflowDetails/index.tsx b/litmus-portal/frontend/src/pages/WorkflowDetails/index.tsx index 408cfcf21..dfd43e2d2 100644 --- a/litmus-portal/frontend/src/pages/WorkflowDetails/index.tsx +++ b/litmus-portal/frontend/src/pages/WorkflowDetails/index.tsx @@ -11,19 +11,18 @@ import Scaffold from '../../containers/layouts/Scaffold'; import { WORKFLOW_DETAILS, WORKFLOW_EVENTS } from '../../graphql'; import { ExecutionData, - Node, Workflow, WorkflowDataVars, WorkflowSubscription, } from '../../models/graphql/workflowData'; +import useActions from '../../redux/actions'; +import * as TabActions from '../../redux/actions/tabs'; import { RootState } from '../../redux/reducers'; import ArgoWorkflow from '../../views/WorkflowDetails/ArgoWorkflow'; import WorkflowInfo from '../../views/WorkflowDetails/WorkflowInfo'; +import WorkflowNodeInfo from '../../views/WorkflowDetails/WorkflowNodeInfo'; import useStyles from './styles'; import TopNavButtons from './TopNavButtons'; -import WorkflowNodeInfo from '../../views/WorkflowDetails/NodeInfo'; -import ButtonFilled from '../../components/Button/ButtonFilled'; -import ButtonOutline from '../../components/Button/ButtonOutline'; interface TopNavButtonsProps { isAnalyticsToggled: boolean; @@ -40,6 +39,7 @@ const WorkflowDetails: React.FC = () => { isInfoToggled: false, }); + const tabs = useActions(TabActions); const { pathname } = useLocation(); // Getting the workflow nome from the pathname const workflowRunId = pathname.split('/')[3]; @@ -49,8 +49,9 @@ const WorkflowDetails: React.FC = () => { const selectedProjectID = useSelector( (state: RootState) => state.userData.selectedProjectID ); - // get Selected Node - const selectedNode = useSelector((state: RootState) => state.selectedNode); + const workflowDetailsTabValue = useSelector( + (state: RootState) => state.tabNumber.node + ); // Query to get workflows const { subscribeToMore, data, error } = useQuery( @@ -97,12 +98,17 @@ const WorkflowDetails: React.FC = () => { } }, [data]); - const [value, setValue] = React.useState(0); const theme = useTheme(); + const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => { - setValue(newValue); + tabs.changeWorkflowDetailsTabs(newValue); }; + // On fresh screen refresh 'Workflow' Tab would be selected + useEffect(() => { + tabs.changeWorkflowDetailsTabs(0); + }, []); + return ( @@ -116,75 +122,60 @@ const WorkflowDetails: React.FC = () => { {t('workflowDetails.detailedLog')} {/* Argo Workflow DAG Graph */} - {isToggled.isInfoToggled ? ( -
- -
- ) : ( -
- -
- )} +
{isToggled.isInfoToggled ? ( -
- <> - + + - - - - - - -
- -
-
- -
- -
-
- -
- {}} - > - Events - - {}}> - Logs - -
+ + + +
+ +
+ +
+
+ +
+ +
+
) : ( <> diff --git a/litmus-portal/frontend/src/pages/WorkflowDetails/styles.ts b/litmus-portal/frontend/src/pages/WorkflowDetails/styles.ts index 6250ded3e..1d04d0f65 100644 --- a/litmus-portal/frontend/src/pages/WorkflowDetails/styles.ts +++ b/litmus-portal/frontend/src/pages/WorkflowDetails/styles.ts @@ -3,6 +3,7 @@ import { makeStyles, Theme } from '@material-ui/core/styles'; const useStyles = makeStyles((theme: Theme) => ({ root: { display: 'flex', + justifyContent: 'flex-end', marginTop: theme.spacing(3), height: '75vh', }, @@ -10,25 +11,11 @@ const useStyles = makeStyles((theme: Theme) => ({ margin: theme.spacing(-0.4, 1), width: '1rem', }, - w100: { - width: '100%', - height: '100%', - }, - w140: { - width: '141%', - height: '100%', - }, button: { position: 'relative', display: 'flex', - margin: theme.spacing(4, 4, 0, 4), - }, - buttonLeft: { - float: 'left', - }, - buttonRight: { - position: 'absolute', - right: '4%', + justifyContent: 'space-between', + margin: theme.spacing(4, 0, 0, 4), }, heading: { fontSize: '2rem', @@ -36,7 +23,10 @@ const useStyles = makeStyles((theme: Theme) => ({ }, workflowGraph: { padding: '0 3rem', - width: '70%', + width: '100%', + }, + workflowSideBar: { + width: '20rem', }, loaderDiv: { height: '100%', @@ -48,12 +38,6 @@ const useStyles = makeStyles((theme: Theme) => ({ display: 'flex', flexDirection: 'column', }, - footerButton: { - marginLeft: 'auto', - display: 'flex', - flexDirection: 'row', - padding: theme.spacing(3, 4, 4, 0), - }, })); export default useStyles; diff --git a/litmus-portal/frontend/src/redux/actions/nodeSelection.ts b/litmus-portal/frontend/src/redux/actions/nodeSelection.ts index 95ea7612f..36bb680b8 100644 --- a/litmus-portal/frontend/src/redux/actions/nodeSelection.ts +++ b/litmus-portal/frontend/src/redux/actions/nodeSelection.ts @@ -1,11 +1,11 @@ /* eslint-disable import/prefer-default-export */ -import { Node } from '../../models/graphql/workflowData'; import { NodeSelectionAction, NodeSelectionActions, + SelectedNode, } from '../../models/redux/nodeSelection'; -export function selectNode(node: Node): NodeSelectionAction { +export function selectNode(node: SelectedNode): NodeSelectionAction { return { type: NodeSelectionActions.SELECT_NODE, payload: node, diff --git a/litmus-portal/frontend/src/redux/actions/tabs.ts b/litmus-portal/frontend/src/redux/actions/tabs.ts index 4c260dbcd..f90ead6b0 100644 --- a/litmus-portal/frontend/src/redux/actions/tabs.ts +++ b/litmus-portal/frontend/src/redux/actions/tabs.ts @@ -13,3 +13,10 @@ export function changeSettingsTabs(tabNumber: number): TabAction { payload: tabNumber, }; } + +export function changeWorkflowDetailsTabs(tabNumber: number): TabAction { + return { + type: TabActions.CHANGE_WORKFLOW_DETAILS_TAB, + payload: tabNumber, + }; +} diff --git a/litmus-portal/frontend/src/redux/configureStore.tsx b/litmus-portal/frontend/src/redux/configureStore.tsx index 6b29f7c65..119589757 100644 --- a/litmus-portal/frontend/src/redux/configureStore.tsx +++ b/litmus-portal/frontend/src/redux/configureStore.tsx @@ -2,7 +2,6 @@ import { createBrowserHistory } from 'history'; // eslint-disable-line import/no import * as localforage from 'localforage'; import { applyMiddleware, createStore } from 'redux'; import { composeWithDevTools } from 'redux-devtools-extension'; -import { createLogger } from 'redux-logger'; import { PersistConfig, persistReducer, persistStore } from 'redux-persist'; import thunk from 'redux-thunk'; import rootReducer from './reducers'; @@ -14,12 +13,11 @@ const persistConfig: PersistConfig = { blacklist: [], }; -const logger = (createLogger as any)(); const history = createBrowserHistory(); const dev = process.env.NODE_ENV === 'development'; -let middleware = dev ? applyMiddleware(thunk, logger) : applyMiddleware(thunk); +let middleware = applyMiddleware(thunk); if (dev) { middleware = composeWithDevTools(middleware); diff --git a/litmus-portal/frontend/src/redux/reducers/index.ts b/litmus-portal/frontend/src/redux/reducers/index.ts index e1431bcaf..c8f9b2ee4 100644 --- a/litmus-portal/frontend/src/redux/reducers/index.ts +++ b/litmus-portal/frontend/src/redux/reducers/index.ts @@ -1,6 +1,6 @@ import { combineReducers } from 'redux'; -import { Node } from '../../models/graphql/workflowData'; import { CommunityData } from '../../models/redux/analytics'; +import { SelectedNode } from '../../models/redux/nodeSelection'; import { TabState } from '../../models/redux/tabs'; import { TemplateData } from '../../models/redux/template'; import { UserData } from '../../models/redux/user'; @@ -16,7 +16,7 @@ export interface RootState { communityData: CommunityData; userData: UserData; workflowData: WorkflowData; - selectedNode: Node; + selectedNode: SelectedNode; tabNumber: TabState; selectTemplate: TemplateData; } diff --git a/litmus-portal/frontend/src/redux/reducers/nodeSelection.ts b/litmus-portal/frontend/src/redux/reducers/nodeSelection.ts index 21e85d95e..74afc632e 100644 --- a/litmus-portal/frontend/src/redux/reducers/nodeSelection.ts +++ b/litmus-portal/frontend/src/redux/reducers/nodeSelection.ts @@ -1,21 +1,26 @@ -import { Node } from '../../models/graphql/workflowData'; import { NodeSelectionAction, NodeSelectionActions, + SelectedNode, } from '../../models/redux/nodeSelection'; import createReducer from './createReducer'; -const initialState: Node = { +const initialState: SelectedNode = { children: null, finishedAt: '', + message: '', name: '', + pod_name: '', phase: '', startedAt: '', type: '', }; -export const selectedNode = createReducer(initialState, { - [NodeSelectionActions.SELECT_NODE](state: Node, action: NodeSelectionAction) { +export const selectedNode = createReducer(initialState, { + [NodeSelectionActions.SELECT_NODE]( + state: SelectedNode, + action: NodeSelectionAction + ) { return { ...state, ...action.payload, diff --git a/litmus-portal/frontend/src/redux/reducers/tabs.ts b/litmus-portal/frontend/src/redux/reducers/tabs.ts index 7970fb834..4aef39bf5 100644 --- a/litmus-portal/frontend/src/redux/reducers/tabs.ts +++ b/litmus-portal/frontend/src/redux/reducers/tabs.ts @@ -5,6 +5,7 @@ import createReducer from './createReducer'; const initialState: TabState = { workflows: 0, settings: 0, + node: 0, }; export const tabNumber = createReducer(initialState, { @@ -20,6 +21,12 @@ export const tabNumber = createReducer(initialState, { settings: action.payload, }; }, + [TabActions.CHANGE_WORKFLOW_DETAILS_TAB](state: TabState, action: TabAction) { + return { + ...state, + node: action.payload, + }; + }, }); export default tabNumber; diff --git a/litmus-portal/frontend/src/views/ChaosWorkflows/BrowseWorkflow/TableData.tsx b/litmus-portal/frontend/src/views/ChaosWorkflows/BrowseWorkflow/TableData.tsx index 0248a353f..1484e2081 100644 --- a/litmus-portal/frontend/src/views/ChaosWorkflows/BrowseWorkflow/TableData.tsx +++ b/litmus-portal/frontend/src/views/ChaosWorkflows/BrowseWorkflow/TableData.tsx @@ -7,13 +7,13 @@ import { } from '@material-ui/core'; import MoreVertIcon from '@material-ui/icons/MoreVert'; import React from 'react'; +import LinearProgressBar from '../../../components/ProgressBar/LinearProgressBar'; import { ExecutionData, WorkflowRun, } from '../../../models/graphql/workflowData'; import { history } from '../../../redux/configureStore'; import timeDifferenceForDate from '../../../utils/datesModifier'; -import LinearProgressBar from '../../../components/ProgressBar/LinearProgressBar'; import CustomStatus from '../CustomStatus/Status'; import useStyles from './styles'; @@ -109,9 +109,9 @@ const TableData: React.FC = ({ data, exeData }) => { > - history.push(`/workflows/details/${data.workflow_run_id}`) - } + onClick={() => { + history.push(`/workflows/details/${data.workflow_run_id}`); + }} >
= ({ nodes }) => { const classes = useStyles(); // Redux action call for updating selected node const nodeSelection = useActions(NodeSelectionActions); + const tabs = useActions(TabActions); const [graphData, setGraphData] = useState({ nodes: [], links: [], }); + // Get the selected Node + const [selectedNodeID, setSelectedNodeID] = useState( + Object.keys(nodes)[0] + ); + useEffect(() => { const data: GraphData = { nodes: [], @@ -58,6 +65,13 @@ const ArgoWorkflow: React.FC = ({ nodes }) => { }); }, [nodes]); + useEffect(() => { + nodeSelection.selectNode({ + ...nodes[selectedNodeID], + pod_name: selectedNodeID, + }); + }, [selectedNodeID]); + return graphData.nodes.length ? ( = ({ nodes }) => { const nodeID = Object.keys(nodes).filter( (key) => key === original?.id )[0]; - nodeSelection.selectNode(nodes[nodeID]); + setSelectedNodeID(nodeID); + tabs.changeWorkflowDetailsTabs(1); }} /> ) : ( diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/index.tsx b/litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/index.tsx deleted file mode 100644 index b8f25a662..000000000 --- a/litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/index.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { Typography } from '@material-ui/core'; -import React from 'react'; -import { Node } from '../../../models/graphql/workflowData'; -import timeDifference from '../../../utils/datesModifier'; -import useStyles from './styles'; - -interface NodeInfoProps { - nodeDetails: Node; -} - -const WorkflowNodeInfo: React.FC = ({ nodeDetails }) => { - const classes = useStyles(); - return ( -
- {/* Node Name */} -
- - Node name: -
- {nodeDetails.name} -
-
-
- - {/* Node Phase */} -
-
- - Phase: {nodeDetails.phase} - -
-
-
- - {/* Node Durations */} -
-
- - Start time:{' '} - {timeDifference(nodeDetails.startedAt)} - - - End time:{' '} - {timeDifference(nodeDetails.finishedAt)} - - - Duration: {' '} - {( - (parseInt(nodeDetails.finishedAt, 10) - - parseInt(nodeDetails.startedAt, 10)) / - 60 - ).toFixed(1)}{' '} - minutes - -
-
-
- ); -}; - -export default WorkflowNodeInfo; diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/index.tsx b/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/index.tsx new file mode 100644 index 000000000..6107a1866 --- /dev/null +++ b/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/index.tsx @@ -0,0 +1,59 @@ +import { useSubscription } from '@apollo/client'; +import { Typography } from '@material-ui/core'; +import React from 'react'; +import Unimodal from '../../../containers/layouts/Unimodal'; +import { WORKFLOW_LOGS } from '../../../graphql'; +import { + PodLog, + PodLogRequest, + PodLogVars, +} from '../../../models/graphql/podLog'; +import useStyles from './styles'; + +interface NodeLogsProps extends PodLogRequest { + logsOpen: boolean; + handleClose: () => void; +} + +const NodeLogs: React.FC = ({ + logsOpen, + handleClose, + cluster_id, + workflow_run_id, + pod_namespace, + pod_name, + pod_type, +}) => { + const classes = useStyles(); + + const { data } = useSubscription(WORKFLOW_LOGS, { + variables: { + podDetails: { + cluster_id, + workflow_run_id, + pod_name, + pod_namespace, + pod_type, + }, + }, + }); + + return ( + +
+ {data !== undefined ? ( + {data.getPodLog.log} + ) : ( + Fetching Logs... + )} +
+
+ ); +}; + +export default NodeLogs; diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/styles.ts b/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/styles.ts new file mode 100644 index 000000000..2011917b4 --- /dev/null +++ b/litmus-portal/frontend/src/views/WorkflowDetails/NodeLogs/styles.ts @@ -0,0 +1,12 @@ +import { makeStyles, Theme } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme: Theme) => ({ + root: { + width: '100%', + height: '90%', + background: theme.palette.common.black, + color: theme.palette.common.white, + }, +})); + +export default useStyles; diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowInfo/index.tsx b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowInfo/index.tsx index 4eb6efbc8..713f0554e 100644 --- a/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowInfo/index.tsx +++ b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowInfo/index.tsx @@ -1,10 +1,6 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -// TODO: remove this after creating UI for node details sidebar import { Typography } from '@material-ui/core'; import React, { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { ExecutionData } from '../../../models/graphql/workflowData'; -import { RootState } from '../../../redux/reducers'; import timeDifference from '../../../utils/datesModifier'; import useStyles from './styles'; @@ -26,7 +22,6 @@ const WorkflowInfo: React.FC = ({ }) => { const classes = useStyles(); // Get selected node data from redux - const selectedNode = useSelector((state: RootState) => state.selectedNode); const [duration, setDuration] = useState(0); const [data, setData] = useState({ diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/index.tsx b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/index.tsx new file mode 100644 index 000000000..2f9faaf6c --- /dev/null +++ b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/index.tsx @@ -0,0 +1,116 @@ +/* eslint-disable */ +import { Typography } from '@material-ui/core'; +import React, { useState } from 'react'; +import { useSelector } from 'react-redux'; +import ButtonOutline from '../../../components/Button/ButtonOutline'; +import { RootState } from '../../../redux/reducers'; +import timeDifference from '../../../utils/datesModifier'; +import NodeLogs from '../NodeLogs'; +import useStyles from './styles'; + +interface WorkflowNodeInfoProps { + cluster_id: string; + workflow_run_id: string; + pod_namespace: string; +} + +const WorkflowNodeInfo: React.FC = ({ + cluster_id, + workflow_run_id, + pod_namespace, +}) => { + const classes = useStyles(); + const [logsOpen, setLogsOpen] = useState(false); + + // Get the nelected node from redux + const { name, phase, pod_name, type, startedAt, finishedAt } = useSelector( + (state: RootState) => state.selectedNode + ); + + const handleClose = () => { + setLogsOpen(false); + }; + + return ( +
+ {/* Logs Modal */} + {logsOpen ? ( + + ) : ( + <> + )} + + {/* Node Name */} +
+ + Name: +
+ {pod_name} +
+
+ {/* Node Type */} +
+ + Type: {type} + +
+
+ + {/* Node Phase */} +
+
+ + Phase: {phase} + +
+
+
+ + {/* Node Durations */} +
+
+ + Start time:{' '} + {timeDifference(startedAt)} + + + End time:{' '} + {timeDifference(finishedAt)} + + + Duration: {' '} + {( + (parseInt(finishedAt, 10) - parseInt(startedAt, 10)) / + 60 + ).toFixed(1)}{' '} + minutes + +
+
+
+ {/* Node Name */} +
+
+ + Node Name: {name} + +
+
+
+ setLogsOpen(true)}> + Logs + +
+
+ ); +}; + +export default WorkflowNodeInfo; diff --git a/litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/styles.ts b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/styles.ts similarity index 74% rename from litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/styles.ts rename to litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/styles.ts index b590d65d4..90a995be2 100644 --- a/litmus-portal/frontend/src/views/WorkflowDetails/NodeInfo/styles.ts +++ b/litmus-portal/frontend/src/views/WorkflowDetails/WorkflowNodeInfo/styles.ts @@ -17,6 +17,12 @@ const useStyles = makeStyles((theme: Theme) => ({ heightMaintainer: { lineHeight: '2rem', }, + footerButton: { + marginLeft: 'auto', + display: 'flex', + flexDirection: 'row', + padding: theme.spacing(3, 4, 4, 0), + }, })); export default useStyles;