INFRA-2867 | incident dashboard table changes

This commit is contained in:
dhruvjoshi
2024-03-11 18:22:33 +05:30
parent a3771cc6e5
commit d5c2930c2a
12 changed files with 167 additions and 55 deletions

View File

@@ -54,13 +54,6 @@
width: 458px !important;
}
.tooltip {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
width: 110px;
}
.tooltipWrapper {
display: flex;
align-items: center;
@@ -69,3 +62,17 @@
line-height: 1;
margin-top: -7px;
}
.moreToShow {
color: var(--navi-color-blue-base);
}
.productTooltipItem {
display: flex;
align-items: center;
.dot {
width: 7px;
height: 7px;
background-color: white;
border-radius: 50%; /* Makes the div round */
margin-right: 4px;
}
}

View File

@@ -11,9 +11,10 @@ import { FETCH_INCIDENTS_DATA } from './constants';
import SearchResultsTable from './partials/SearchResultsTable';
import DashboardHeader from './partials/DashboardHeader';
import styles from './Dashboard.module.scss';
import { RootState } from '@src/store';
const Dashboard: FC = () => {
const data = useSelector((state: any) => state.dashboard.data);
const data = useSelector((state: RootState) => state.dashboard.data);
const dispatch = useDispatch();
const navigate = useNavigate();
const [pageDetails, setPageDetails] = useState({

View File

@@ -1,21 +1,25 @@
import { FC } from 'react';
import { useNavigate } from 'react-router-dom';
import { AgTable, Pagination } from '@navi/web-ui/lib/components';
import { Tag, Tooltip } from '@navi/web-ui/lib/primitives';
import { Tag } from '@navi/web-ui/lib/primitives';
import { returnFormattedDate } from '@src/services/globalUtils';
import useClickStream from '@src/services/clickStream';
import { CLICK_STREAM_EVENT_FACTORY } from '@src/services/clickStream/constants/values';
import styles from '../SearchResultsTable.module.scss';
import { getSeverityColor } from '../constants';
import cx from 'classnames';
import { IncidentDashboard } from '@src/slices/dashboardSlice';
import { Team } from '../type';
import { Tooltip } from 'antd';
interface SearchResultTableProps {
currentPageData: any;
currentPageData: IncidentDashboard[];
pageDetails: any;
currentPageSize: number;
handlePageNumberChange: (pageNumber: number) => void;
handlePageSizeChange: (pageSize: number) => void;
fetchIncidentData: (props: any) => void;
}
const MAX_LENGTH = 12;
const defaultColDef = {
cellStyle: { lineHeight: 2 },
@@ -56,7 +60,9 @@ const SearchResultsTable: FC<SearchResultTableProps> = ({
title: item?.title,
statusName: item?.statusName,
severityName: item?.severityName,
teamName: item?.teamName,
responder: item?.teamName,
assignerTeam: item?.assignerTeam?.label,
products: item?.products,
createdAt: returnFormattedDate(item?.createdAt),
createdBy: item?.createdBy,
updatedBy: item?.updatedBy,
@@ -65,6 +71,50 @@ const SearchResultsTable: FC<SearchResultTableProps> = ({
};
});
const wrappedTextHandler = (param: string) => {
if (param?.length > MAX_LENGTH) {
const wrappedText = param?.substring(0, MAX_LENGTH - 3) + '...';
return (
<div className={styles.tooltipWrapper}>
<Tooltip title={param}>
<div className={styles.tooltip}>{wrappedText}</div>
</Tooltip>
</div>
);
}
return param;
};
const productRendered = (products: Team[]): JSX.Element | string => {
if (!products || products.length === 0) return '';
const productNames = products
.map((product: Team) => product.label)
.sort((a, b) => a.length - b.length)
.join(', ');
if (productNames.length <= MAX_LENGTH) return productNames;
const truncatedProducts = productNames.substring(0, MAX_LENGTH - 3) + '...';
const moreToShow = products.length - truncatedProducts.split(',').length;
const tooltipContent = products.map((product: Team, index) => (
<div className={styles['productTooltipItem']} key={index}>
<div className={styles['dot']}></div>
{product.label}
</div>
));
return (
<div className={styles.tooltipWrapper}>
<Tooltip title={tooltipContent}>
{truncatedProducts}
{moreToShow > 0 && (
<span className={styles.moreToShow}>{` +${moreToShow} More`}</span>
)}
</Tooltip>
</div>
);
};
const columnData = [
{
field: 'incidentName',
@@ -76,19 +126,8 @@ const SearchResultsTable: FC<SearchResultTableProps> = ({
headerName: 'Title',
suppressMovable: true,
cellStyle: cellStyle,
cellRenderer: params => {
if (params.value?.length > 15) {
return (
<div className={styles.tooltipWrapper}>
<Tooltip text={params?.value} withPointer position="right">
<div className={styles.tooltip}>{params?.value}</div>
</Tooltip>
</div>
);
}
return params?.value;
},
cellRenderer: params => wrappedTextHandler(params?.value),
width: 120,
},
{
field: 'statusName',
@@ -102,7 +141,7 @@ const SearchResultsTable: FC<SearchResultTableProps> = ({
cellStyle: {
zIndex: -1,
},
width: 120,
width: 100,
cellRenderer: params => (
<Tag
color={getSeverityColor(params?.value)}
@@ -112,31 +151,39 @@ const SearchResultsTable: FC<SearchResultTableProps> = ({
),
},
{
field: 'teamName',
headerName: 'Team name',
suppressMovable: true,
},
{
field: 'createdBy',
headerName: 'Created by',
field: 'products',
headerName: 'Product',
suppressMovable: true,
cellStyle: cellStyle,
cellRenderer: params => productRendered(params?.value),
},
{
field: 'assignerTeam',
headerName: 'Assigner',
suppressMovable: true,
width: 130,
cellRenderer: params => wrappedTextHandler(params?.value),
},
{
field: 'responder',
headerName: 'Responder',
suppressMovable: true,
width: 130,
cellStyle: cellStyle,
cellRenderer: params => wrappedTextHandler(params?.value),
},
{
field: 'createdAt',
headerName: 'Created on',
suppressMovable: true,
width: 175,
},
{
field: 'updatedAt',
headerName: 'Updated on',
suppressMovable: true,
},
{
field: 'updatedBy',
headerName: 'Updated by',
suppressMovable: true,
cellStyle: cellStyle,
width: 175,
},
];

View File

@@ -6,7 +6,13 @@
.description-content-body {
margin-top: 12px;
padding-bottom: 16px;
}
.description-content-assigner {
margin-top: 12px;
}
.description-content-link {
margin-top: 24px;
}

View File

@@ -7,15 +7,27 @@ import GoToLinkIcon from '@src/assets/GoToLinkIcon';
import { IncidentPageState } from '@src/types';
import JiraLinks from '../JiraLinks';
import styles from './DescriptionContent.module.scss';
import { generateMap, getCurrentData } from '../utils';
const DescriptionContent: React.FC = () => {
const { description, slackChannel, incidentName, rcaLink } = useSelector(
const {
description,
slackChannel,
incidentName,
rcaLink,
assignerTeam,
products,
} = useSelector(
(state: IncidentPageState) => state.incidentLog.incidentData || {},
);
const incidentParticipants = useSelector(
(state: IncidentPageState) => state.incidentLog.participantsData,
);
const headerData = useSelector(
(state: IncidentPageState) => state.incidentLog.headerData,
);
const teamsMap = generateMap(headerData?.teams || []);
const currentTeam = getCurrentData(assignerTeam, teamsMap, 'value');
const renderParticipantList = (type: string): JSX.Element | JSX.Element[] => {
const list =
type === 'participants'
@@ -46,6 +58,14 @@ const DescriptionContent: React.FC = () => {
{description || '-'}
</Typography>
</div>
<Typography variant="h6" color="var(--navi-color-gray-c3)">
ASSIGNER
</Typography>
<div className={styles['description-content-assigner']}>
<Typography variant="p3" color="var(--navi-color-gray-c2)">
{currentTeam}
</Typography>
</div>
</div>
<div className={styles['horizontal-line']} />
<div className={styles['description-content-link']}>

View File

@@ -383,9 +383,9 @@ const AllDailogBox: FC = () => {
>
<div>
<Typography variant="p3" color="var(--navi-color-gray-c2)">
You are updating this incident&lsquo;s &nbsp;
{"You are updating this incident's "}
{UpdateData?.type || '..'}
&nbsp; from
{' from'}
<Typography
variant="h4"
color="var(--navi-color-gray-c2)"
@@ -393,7 +393,7 @@ const AllDailogBox: FC = () => {
>
{UpdateData?.from || '..'}
</Typography>
to&nbsp;
{' to '}
<Typography
variant="h4"
color="var(--navi-color-gray-c2)"

View File

@@ -342,7 +342,7 @@ const Dropdowns: FC = () => {
<div className={styles['dropdown-team']}>
<div>
<Typography variant="p5" color="var(--navi-color-gray-c2)">
Team
Responder
</Typography>
</div>
<div ref={refTeam}>

View File

@@ -32,7 +32,7 @@ const stageColorMap = {
const changeTypeToTitleMap = {
SeverityId: 'Severity changed to',
Status: 'Status changed to',
TeamId: 'Team changed to',
TeamId: 'Responder changed to',
Default: 'Different Title',
};

View File

@@ -64,7 +64,7 @@ export const getCurrentData = (
dataMap: { [key: string]: string },
key: string,
): string => {
return dataMap && data[key] ? dataMap[data[key]] : '-';
return dataMap && data?.[key] ? dataMap?.[data?.[key]] : '-';
};
export const generateMap = (data: DataItem[]): { [key: number]: string } => {

View File

@@ -152,14 +152,6 @@ const useTeamApis = (): useTeamApiProps => {
.then(response => {
toast.success(response?.data?.data);
dispatch(fetchTeamDetails(teamId?.toString() || ''));
// dispatchData({
// type: actionTypes.SET_OPEN_ONCALL,
// payload: false,
// });
// dispatchData({
// type: actionTypes.SET_PSEC_OPEN_ONCALL,
// payload: false,
// });
})
.catch(error => {
const toastMessage = `${

View File

@@ -1,9 +1,46 @@
import { createSlice } from '@reduxjs/toolkit';
import { Team } from '@src/Pages/Dashboard/type';
export interface IncidentDashboard {
id: number;
title: string;
description: string;
status: number;
statusName: string;
severityId: number;
severityName: string;
incidentName: string;
slackChannel: string;
detectionTime: null;
startTime: Date;
endTime: Date | null;
teamId: number;
teamName: string;
jiraLinks: null;
confluenceId: null;
severityTat: Date;
remindMeAt: null;
enableReminder: boolean;
createdBy: string;
updatedBy: string;
createdAt: Date;
updatedAt: Date;
rcaLink: string;
assignerTeam: Team | null;
products: Team[] | null;
}
export interface Pages {
totalElements: number;
totalPages: number;
pageSize: number;
pageNumber: number;
}
const dashboardSlice = createSlice({
name: 'dashboard',
initialState: {
data: Array<any>(),
data: Array<IncidentDashboard>(),
},
reducers: {
setDashboardData: (state, action) => {

View File

@@ -81,6 +81,8 @@ export interface IncidentDatatype {
createdAt: Date | null;
updatedAt: Date | null;
rcaLink: string;
assignerTeam: Team;
products: Team[];
}
interface Severity {