TP-52973 | minor refinement
This commit is contained in:
@@ -1,15 +1,24 @@
|
||||
import { FC } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Typography from '@navi/web-ui/lib/primitives/Typography';
|
||||
import IncidentCreated from '../StepperAssets/IncidentCreated';
|
||||
import IncidentChange from '../StepperAssets/IncidentChange';
|
||||
import styles from './ActivityLog.module.scss';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const ActivityLog: FC = () => {
|
||||
//To do: add type here
|
||||
const incidentLog = useSelector(
|
||||
(state: any) => state.incidentLog.incidentLogData,
|
||||
);
|
||||
const totalLog = incidentLog?.data?.logs?.length;
|
||||
const lastChangeIndex = (incidentLog?.data?.logs || [])
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex(log =>
|
||||
log.changes.some(change =>
|
||||
['Status', 'SeverityId', 'TeamId'].includes(change.attribute),
|
||||
),
|
||||
);
|
||||
const totalLog = incidentLog?.data?.logs?.length - lastChangeIndex;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -1,70 +1,25 @@
|
||||
import React, { FC, useState, useReducer, useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import {
|
||||
setIncidentData,
|
||||
setIncidentLogData,
|
||||
setHeaderData,
|
||||
setParticipantsData,
|
||||
} from '@src/slices/IncidentSlice';
|
||||
import {
|
||||
Typography,
|
||||
Avatar,
|
||||
BorderLessInput,
|
||||
} from '@navi/web-ui/lib/primitives';
|
||||
import {
|
||||
CloseIcon,
|
||||
DeleteIconOutlined,
|
||||
ArrowUpSolidIcon,
|
||||
ArrowDownSolidIcon,
|
||||
} from '@navi/web-ui/lib/icons';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Typography, Avatar } from '@navi/web-ui/lib/primitives';
|
||||
import SlackIcon from '@src/assets/SlackIcon';
|
||||
import LoadingIcon from '@src/assets/LoadingIcon';
|
||||
import ConfluenceIcon from '@src/assets/ConfluenceIcon';
|
||||
import GoToLinkIcon from '@src/assets/GoToLinkIcon';
|
||||
import { ApiService } from '@src/services/api';
|
||||
import {
|
||||
ActionType,
|
||||
initialState,
|
||||
reducer,
|
||||
JIRA_VALIDATION,
|
||||
} from './DescriptionContentProps';
|
||||
import styles from './DescriptionContent.module.scss';
|
||||
import {
|
||||
LINK_JIRA_INCIDENT,
|
||||
UNLINK_JIRA_INCIDENT,
|
||||
FETCH_INCIDENT_DATA,
|
||||
} from '../constants';
|
||||
import { truncateText, linkSanitization } from '../utils';
|
||||
import JiraLinks from '../JiraLinks';
|
||||
import styles from './DescriptionContent.module.scss';
|
||||
|
||||
const DescriptionContent: React.FC = () => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const { id, description, jiraIds, slackChannel, incidentName, rcaLink } =
|
||||
useSelector((state: any) => state.incidentLog.incidentData);
|
||||
|
||||
const { description, slackChannel, incidentName, rcaLink } = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
const incidentParticipants = useSelector(
|
||||
(state: any) => state.incidentLog.participantsData,
|
||||
);
|
||||
// console.log('incident participants desc', incidentParticipants);
|
||||
const reduxDispatch = useDispatch();
|
||||
|
||||
//move to hooks
|
||||
const storedEmail = localStorage.getItem('email-id');
|
||||
//import scss
|
||||
const goToLinkBlueColor = '#0276FE';
|
||||
|
||||
//use from hooks below three functions
|
||||
|
||||
//move to utils
|
||||
// console.log('incident participants', incidentParticipants);
|
||||
const renderParticipantList = (type: string): JSX.Element => {
|
||||
const list =
|
||||
type === 'participants'
|
||||
? incidentParticipants?.participants
|
||||
: incidentParticipants?.others;
|
||||
|
||||
return list?.length ? (
|
||||
list.map(participant => (
|
||||
<div key={participant?.id} className={styles['team-details-wrapper']}>
|
||||
@@ -127,7 +82,7 @@ const DescriptionContent: React.FC = () => {
|
||||
rel="noreferrer"
|
||||
className={styles['rca-text']}
|
||||
>
|
||||
<GoToLinkIcon color={goToLinkBlueColor} />
|
||||
<GoToLinkIcon color="var(--navi-color-blue-base)" />
|
||||
<Typography variant="h4" color="var(--navi-color-blue-base)">
|
||||
Go to document
|
||||
</Typography>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { FC, useEffect, useReducer } from 'react';
|
||||
import { useMatch } from 'react-router-dom';
|
||||
import { FC, useReducer } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { Tabs } from 'antd';
|
||||
import { ArrowDownIcon, AlertOutlineIcon } from '@navi/web-ui/lib/icons';
|
||||
import { AlertOutlineIcon } from '@navi/web-ui/lib/icons';
|
||||
import { SelectPickerOptionProps } from '@navi/web-ui/lib/components/SelectPicker/types';
|
||||
import {
|
||||
BorderedInput,
|
||||
@@ -11,9 +9,7 @@ import {
|
||||
Button,
|
||||
} from '@navi/web-ui/lib/primitives';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
|
||||
import GoToLinkIcon from '@src/assets/GoToLinkIcon';
|
||||
import styles from '../Incidents.module.scss';
|
||||
import LoadingIcon from '@src/assets/LoadingIcon';
|
||||
import {
|
||||
setOpenDialognotParticipants,
|
||||
@@ -22,7 +18,6 @@ import {
|
||||
setOpenDialogUpdate,
|
||||
} from '@src/slices/IncidentSlice';
|
||||
import { ApiService } from '@src/services/api';
|
||||
|
||||
import {
|
||||
actionTypes,
|
||||
SLACK_BASE_URL,
|
||||
@@ -32,17 +27,13 @@ import {
|
||||
ResponseType,
|
||||
DUPLICATE_STATUS,
|
||||
UPDATE_INCIDENT,
|
||||
SeverityType,
|
||||
StatusType,
|
||||
TeamType,
|
||||
RESOLVE_STATUS,
|
||||
} from '../constants';
|
||||
|
||||
import useIncidentApis from '../useIncidentApis';
|
||||
import styles from '../Incidents.module.scss';
|
||||
|
||||
const AllDailogBox: FC = () => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const openNotParticipants = useSelector(
|
||||
(state: any) => state.incidentLog.openDialognotParticipants,
|
||||
);
|
||||
@@ -61,32 +52,13 @@ const AllDailogBox: FC = () => {
|
||||
const selectedOption = useSelector(
|
||||
(state: any) => state.incidentLog.selectedOptions,
|
||||
);
|
||||
//console.log('updatedata', UpdateData);
|
||||
|
||||
const incidentData = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
const headerData = useSelector((state: any) => state.incidentLog.headerData);
|
||||
|
||||
const severityMap = headerData?.severities?.reduce((map, severity) => {
|
||||
map[severity.value] = severity.label;
|
||||
return map;
|
||||
}, {});
|
||||
const statusMap = headerData?.incidentStatuses?.reduce((map, status) => {
|
||||
map[status.value] = status.label;
|
||||
return map;
|
||||
}, {});
|
||||
const teamsMap = headerData?.teams?.reduce((map, Incidentteam) => {
|
||||
map[Incidentteam.value] = Incidentteam.label;
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
const { updateIncident, fetchIncidentLog, startIncidentSearch } =
|
||||
useIncidentApis();
|
||||
0;
|
||||
|
||||
const { updateIncident, startIncidentSearch } = useIncidentApis();
|
||||
const incidentId = incidentData?.id?.toString();
|
||||
console.log('incidentId', incidentId);
|
||||
const reduxDispatch = useDispatch();
|
||||
const incidentName = incidentData?.incidentName;
|
||||
|
||||
@@ -94,7 +66,7 @@ const AllDailogBox: FC = () => {
|
||||
reduxDispatch(setOpenDialognotParticipants(false));
|
||||
};
|
||||
|
||||
const handleGoToSlackChannel = () => {
|
||||
const handleGoToSlackChannel = (): void => {
|
||||
const slackChannelURL = `${SLACK_BASE_URL}/archives/${incidentData?.slackChannel}`;
|
||||
window.open(slackChannelURL, '_blank');
|
||||
handleopenNotParticipants();
|
||||
@@ -231,7 +203,6 @@ const AllDailogBox: FC = () => {
|
||||
const handleTeamSelectionChange = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
): void => {
|
||||
console.log('selectedOption', selectedOption);
|
||||
if (selectedOption) {
|
||||
dispatch({ type: actionTypes.SET_IS_TEAM_PICKER_OPEN, payload: false });
|
||||
toast('Updating ticket. Please wait a moment.', {
|
||||
@@ -248,10 +219,10 @@ const AllDailogBox: FC = () => {
|
||||
};
|
||||
|
||||
const handleCloseConfirmationDialog = () => {
|
||||
if (UpdateData?.type === SeverityType) {
|
||||
if (UpdateData?.type == 'severity') {
|
||||
handleSeveritySelectionChange(selectedOption);
|
||||
} else {
|
||||
if (UpdateData?.type === StatusType) {
|
||||
if (UpdateData?.type == 'status') {
|
||||
handleStatusSelectionChange(selectedOption);
|
||||
} else {
|
||||
handleTeamSelectionChange(selectedOption);
|
||||
@@ -263,7 +234,6 @@ const AllDailogBox: FC = () => {
|
||||
<div>
|
||||
{openNotParticipants && (
|
||||
<ModalDialog
|
||||
// add open to use reducer
|
||||
open={openNotParticipants}
|
||||
footerButtons={[
|
||||
{
|
||||
@@ -321,7 +291,6 @@ const AllDailogBox: FC = () => {
|
||||
Icon={<AlertOutlineIcon color="var(--navi-color-red-base)" />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className={styles['hint-text']}
|
||||
variant="text"
|
||||
@@ -386,9 +355,9 @@ const AllDailogBox: FC = () => {
|
||||
>
|
||||
<div>
|
||||
<Typography variant="p3" color="var(--navi-color-gray-c2)">
|
||||
You are updating this incident‘s
|
||||
You are updating this incident‘s
|
||||
{UpdateData?.type || '..'}
|
||||
from
|
||||
from
|
||||
<Typography
|
||||
variant="h4"
|
||||
color="var(--navi-color-gray-c2)"
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
import { FC, useEffect, useReducer, useState, MutableRefObject } from 'react';
|
||||
import { useMatch } from 'react-router-dom';
|
||||
import { FC, useReducer, MutableRefObject } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
import {
|
||||
BorderedInput,
|
||||
ModalDialog,
|
||||
Typography,
|
||||
Button,
|
||||
} from '@navi/web-ui/lib/primitives';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
import { ArrowDownIcon, AlertOutlineIcon } from '@navi/web-ui/lib/icons';
|
||||
import { Typography } from '@navi/web-ui/lib/primitives';
|
||||
import { ArrowDownIcon } from '@navi/web-ui/lib/icons';
|
||||
import { SelectPicker } from '@navi/web-ui/lib/components';
|
||||
import { SelectPickerOptionProps } from '@navi/web-ui/lib/components/SelectPicker/types';
|
||||
import LoadingIcon from '@src/assets/LoadingIcon';
|
||||
import useOutsideClick from '@src/services/hooks/useOustideClick';
|
||||
import { getUpdateTypeText } from '../utils';
|
||||
import { ApiService } from '@src/services/api';
|
||||
import {
|
||||
setIncidentData,
|
||||
setIncidentLogData,
|
||||
setHeaderData,
|
||||
setParticipantsData,
|
||||
setOpenDialogDuplicate,
|
||||
setOpenDialogResolve,
|
||||
setOpenDialogUpdate,
|
||||
@@ -29,8 +15,7 @@ import {
|
||||
setSelectedOptions,
|
||||
} from '@src/slices/IncidentSlice';
|
||||
import AllDailogBox from './AllDailogBox';
|
||||
import useIncidentApis from '../useIncidentApis';
|
||||
import { generateOptions, getCurrentData, isUserParticipant } from '../utils';
|
||||
import { generateOptions, getCurrentData, getUpdateTypeText } from '../utils';
|
||||
import {
|
||||
reducer,
|
||||
actionTypes,
|
||||
@@ -40,17 +25,12 @@ import {
|
||||
SeverityType,
|
||||
StatusType,
|
||||
TeamType,
|
||||
SLACK_BASE_URL,
|
||||
incidentRegrex,
|
||||
ResponseType,
|
||||
UPDATE_INCIDENT,
|
||||
} from '../constants';
|
||||
import styles from '../Incidents.module.scss';
|
||||
|
||||
const Dropdowns: FC = () => {
|
||||
const { updateIncident, fetchIncidentLog, startIncidentSearch } =
|
||||
useIncidentApis();
|
||||
const reduxDispatch = useDispatch();
|
||||
//To do: add types here
|
||||
const incidentData = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
@@ -58,50 +38,36 @@ const Dropdowns: FC = () => {
|
||||
(state: any) => state.incidentLog?.participantsData,
|
||||
);
|
||||
const headerData = useSelector((state: any) => state.incidentLog.headerData);
|
||||
|
||||
const incidentId = incidentData?.incidentId?.toString();
|
||||
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const incidentName = state.incidentName;
|
||||
|
||||
const updatedSeverities = generateOptions(headerData?.severities);
|
||||
const updatedStatuses = generateOptions(headerData?.incidentStatuses);
|
||||
const updatedTeams = generateOptions(headerData?.teams);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_SLACK_CHANNEL,
|
||||
payload: incidentData?.slackChannel,
|
||||
});
|
||||
dispatch({
|
||||
type: actionTypes.SET_SEVERITY,
|
||||
payload: {
|
||||
label: incidentData?.severityName,
|
||||
value: incidentData?.severityId,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: actionTypes.SET_STATUS,
|
||||
payload: {
|
||||
label: incidentData?.statusName,
|
||||
value: incidentData?.status,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: actionTypes.SET_TEAM,
|
||||
payload: {
|
||||
label: incidentData?.teamName,
|
||||
value: incidentData?.teamId,
|
||||
},
|
||||
});
|
||||
}, [incidentData]);
|
||||
const initialSeverity = {
|
||||
label: incidentData?.severityName,
|
||||
value: incidentData?.severityId,
|
||||
};
|
||||
|
||||
const userData = JSON.parse(localStorage.getItem('user-data') || '{}');
|
||||
const userEmail = userData?.emailId || [];
|
||||
const initialStatus = {
|
||||
label: incidentData?.statusName,
|
||||
value: incidentData?.status,
|
||||
};
|
||||
|
||||
const isUserParticipantList = isUserParticipant(
|
||||
userEmail,
|
||||
incidentParticipants,
|
||||
const initialTeam = {
|
||||
label: incidentData?.teamName,
|
||||
value: incidentData?.teamId,
|
||||
};
|
||||
|
||||
const { emailId: userEmail } =
|
||||
JSON.parse(localStorage.getItem('user-data') || '{}') || {};
|
||||
const participantsList = [
|
||||
...(incidentParticipants?.participants || []),
|
||||
...(incidentParticipants?.others || []),
|
||||
];
|
||||
//To do: add types here
|
||||
const isUserParticipantList = participantsList?.some(
|
||||
(participant: any) => participant.email === userEmail,
|
||||
);
|
||||
|
||||
const severityMap = headerData?.severities?.reduce((map, severity) => {
|
||||
@@ -117,6 +83,10 @@ const Dropdowns: FC = () => {
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
const currentSev = getCurrentData(incidentData, severityMap, 'severityId');
|
||||
const currentStatus = getCurrentData(incidentData, statusMap, 'status');
|
||||
const currentTeam = getCurrentData(incidentData, teamsMap, 'teamId');
|
||||
|
||||
const combinedSevClassNames = classnames(
|
||||
styles[isUserParticipantList ? 'dropdown-box' : 'dropdown-disabled'],
|
||||
{
|
||||
@@ -142,6 +112,121 @@ const Dropdowns: FC = () => {
|
||||
},
|
||||
);
|
||||
|
||||
const handleDropdownClick = (changeType: string) => {
|
||||
if (isUserParticipantList) {
|
||||
switch (changeType) {
|
||||
case 'severity':
|
||||
return () => handleSeverityDropdownClick();
|
||||
case 'status':
|
||||
return () => handleStatusDropdownClick();
|
||||
case 'team':
|
||||
return () => handleTeamDropdownClick();
|
||||
}
|
||||
} else {
|
||||
return handleDisabledDropdownClick;
|
||||
}
|
||||
};
|
||||
|
||||
const handleSeverityDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
payload: !state.isSeverityPickerOpen,
|
||||
});
|
||||
};
|
||||
const handleStatusDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_STATUS_PICKER_OPEN,
|
||||
payload: !state.isStatusPickerOpen,
|
||||
});
|
||||
};
|
||||
const handleTeamDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_TEAM_PICKER_OPEN,
|
||||
payload: !state.isTeamPickerOpen,
|
||||
});
|
||||
};
|
||||
|
||||
const handleDisabledDropdownClick = (): void => {
|
||||
reduxDispatch(setOpenDialognotParticipants(true));
|
||||
};
|
||||
|
||||
const handleOpenConfirmationDailog = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
updateType: number,
|
||||
): void => {
|
||||
const currentValue =
|
||||
updateType === SeverityType
|
||||
? initialSeverity?.value
|
||||
: updateType === StatusType
|
||||
? initialStatus?.value
|
||||
: initialTeam?.value;
|
||||
const currentState = currentValue.toString();
|
||||
const selectedvalue = Array.isArray(selectedOption)
|
||||
? selectedOption[0].value
|
||||
: selectedOption.value;
|
||||
if (currentState !== selectedvalue) {
|
||||
dispatch({ type: actionTypes.SET_IS_STATUS_PICKER_OPEN, payload: false });
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
payload: false,
|
||||
});
|
||||
dispatch({ type: actionTypes.SET_IS_TEAM_PICKER_OPEN, payload: false });
|
||||
if (updateType === StatusType && selectedvalue === RESOLVE_STATUS) {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_STATUS_PICKER_OPEN,
|
||||
payload: false,
|
||||
});
|
||||
reduxDispatch(setOpenDialogResolve(true));
|
||||
} else if (
|
||||
updateType === StatusType &&
|
||||
selectedvalue === DUPLICATE_STATUS
|
||||
) {
|
||||
dispatch({
|
||||
type: actionTypes.SET_DUPLICATE_DIALOG,
|
||||
payload: true,
|
||||
});
|
||||
reduxDispatch(setOpenDialogDuplicate(true));
|
||||
} else {
|
||||
reduxDispatch(
|
||||
setUpdateDetails({
|
||||
type: getUpdateTypeText(updateType),
|
||||
to: selectedOption,
|
||||
from: getUpdateValueText(updateType),
|
||||
}),
|
||||
);
|
||||
reduxDispatch(setSelectedOptions(selectedOption));
|
||||
reduxDispatch(setOpenDialogUpdate(true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getUpdateValueText = updateType => {
|
||||
switch (updateType) {
|
||||
case SeverityType:
|
||||
return ` ${
|
||||
severityMap && initialSeverity?.value
|
||||
? severityMap[initialSeverity.value]
|
||||
: '-'
|
||||
} `;
|
||||
case StatusType:
|
||||
return ` ${
|
||||
statusMap && initialStatus?.value
|
||||
? statusMap[initialStatus.value]
|
||||
: '-'
|
||||
} `;
|
||||
case TeamType:
|
||||
return ` ${
|
||||
teamsMap && initialTeam?.value ? teamsMap[initialTeam.value] : '-'
|
||||
} `;
|
||||
default:
|
||||
return ` ${
|
||||
severityMap && initialSeverity?.value
|
||||
? severityMap[initialSeverity.value]
|
||||
: '-'
|
||||
} `;
|
||||
}
|
||||
};
|
||||
|
||||
const handleSevClickOutside = () => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
@@ -175,209 +260,6 @@ const Dropdowns: FC = () => {
|
||||
callback: handleTeamClickOutside,
|
||||
}) as MutableRefObject<HTMLDivElement>;
|
||||
|
||||
const handleSeverityDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
payload: !state.isSeverityPickerOpen,
|
||||
});
|
||||
};
|
||||
const handleStatusDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_STATUS_PICKER_OPEN,
|
||||
payload: !state.isStatusPickerOpen,
|
||||
});
|
||||
};
|
||||
const handleTeamDropdownClick = (): void => {
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_TEAM_PICKER_OPEN,
|
||||
payload: !state.isTeamPickerOpen,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSevClick = () => {
|
||||
if (isUserParticipantList) {
|
||||
handleSeverityDropdownClick();
|
||||
} else {
|
||||
handleDisabledDropdownClick();
|
||||
}
|
||||
};
|
||||
const handleStatusClick = () => {
|
||||
if (isUserParticipantList) {
|
||||
handleStatusDropdownClick();
|
||||
} else {
|
||||
handleDisabledDropdownClick();
|
||||
}
|
||||
};
|
||||
const handleTeamClick = () => {
|
||||
if (isUserParticipantList) {
|
||||
handleTeamDropdownClick();
|
||||
} else {
|
||||
handleDisabledDropdownClick();
|
||||
}
|
||||
};
|
||||
|
||||
const handleDisabledDropdownClick = (): void => {
|
||||
reduxDispatch(setOpenDialognotParticipants(true));
|
||||
};
|
||||
|
||||
const getUpdateValueText = updateType => {
|
||||
switch (updateType) {
|
||||
case SeverityType:
|
||||
return ` ${
|
||||
severityMap && state.severity?.value
|
||||
? severityMap[state.severity.value]
|
||||
: '-'
|
||||
} `;
|
||||
case StatusType:
|
||||
return ` ${
|
||||
statusMap && state.status?.value ? statusMap[state.status.value] : '-'
|
||||
} `;
|
||||
case TeamType:
|
||||
return ` ${
|
||||
teamsMap && state.team?.value ? teamsMap[state.team.value] : '-'
|
||||
} `;
|
||||
default:
|
||||
return ` ${
|
||||
severityMap && state.severity?.value
|
||||
? severityMap[state.severity.value]
|
||||
: '-'
|
||||
} `;
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenConfirmationDailog = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
updateType: number,
|
||||
): void => {
|
||||
const currentValue =
|
||||
updateType === SeverityType
|
||||
? state.severity?.value
|
||||
: updateType === StatusType
|
||||
? state.status?.value
|
||||
: state.team?.value;
|
||||
const currentState = currentValue.toString();
|
||||
const selectedvalue = Array.isArray(selectedOption)
|
||||
? selectedOption[0].value
|
||||
: selectedOption.value;
|
||||
if (currentState !== selectedvalue) {
|
||||
dispatch({ type: actionTypes.SET_IS_STATUS_PICKER_OPEN, payload: false });
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
payload: false,
|
||||
});
|
||||
dispatch({ type: actionTypes.SET_IS_TEAM_PICKER_OPEN, payload: false });
|
||||
if (updateType === StatusType && selectedvalue === RESOLVE_STATUS) {
|
||||
handleStatusSelectionChange(selectedOption);
|
||||
} else if (
|
||||
updateType === StatusType &&
|
||||
selectedvalue === DUPLICATE_STATUS
|
||||
) {
|
||||
dispatch({
|
||||
type: actionTypes.SET_DUPLICATE_DIALOG,
|
||||
payload: true,
|
||||
});
|
||||
reduxDispatch(setOpenDialogDuplicate(true));
|
||||
} else {
|
||||
console.log('type', updateType);
|
||||
console.log('to', selectedOption);
|
||||
console.log('from', getUpdateValueText);
|
||||
reduxDispatch(
|
||||
setUpdateDetails({
|
||||
type: getUpdateTypeText(updateType),
|
||||
to: selectedOption,
|
||||
from: getUpdateValueText(updateType),
|
||||
}),
|
||||
);
|
||||
reduxDispatch(setSelectedOptions(selectedOption));
|
||||
reduxDispatch(setOpenDialogUpdate(true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseConfirmationDialog = () => {
|
||||
if (state.updateType === SeverityType) {
|
||||
handleSeveritySelectionChange(state.selectedOption);
|
||||
} else {
|
||||
if (state.updateType === StatusType) {
|
||||
handleStatusSelectionChange(state.selectedOption);
|
||||
} else {
|
||||
handleTeamSelectionChange(state.selectedOption);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleSeveritySelectionChange = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
): void => {
|
||||
if (selectedOption) {
|
||||
toast('Updating ticket. Please wait a moment.', {
|
||||
icon: <LoadingIcon />,
|
||||
});
|
||||
dispatch({
|
||||
type: actionTypes.SET_IS_SEVERITY_PICKER_OPEN,
|
||||
payload: false,
|
||||
});
|
||||
const value = Array.isArray(selectedOption)
|
||||
? selectedOption[0].value
|
||||
: selectedOption.value;
|
||||
updateIncident({
|
||||
id: parseInt(incidentId, 10),
|
||||
severityId: value.toString(),
|
||||
});
|
||||
}
|
||||
};
|
||||
const handleStatusSelectionChange = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
): void => {
|
||||
if (selectedOption) {
|
||||
dispatch({ type: actionTypes.SET_IS_STATUS_PICKER_OPEN, payload: false });
|
||||
const value = Array.isArray(selectedOption)
|
||||
? selectedOption[0].value
|
||||
: selectedOption.value;
|
||||
if (value === RESOLVE_STATUS) {
|
||||
dispatch({
|
||||
type: actionTypes.SET_DIALOG_TEXT,
|
||||
payload: 'Resolve incident',
|
||||
});
|
||||
dispatch({
|
||||
type: actionTypes.SET_DIALOG_BODY_TEXT,
|
||||
payload: 'resolved',
|
||||
});
|
||||
|
||||
reduxDispatch(setOpenDialogResolve(true));
|
||||
} else {
|
||||
toast('Updating ticket. Please wait a moment.', {
|
||||
icon: <LoadingIcon />,
|
||||
});
|
||||
updateIncident({
|
||||
id: parseInt(incidentId, 10),
|
||||
status: value.toString(),
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleTeamSelectionChange = (
|
||||
selectedOption: SelectPickerOptionProps | SelectPickerOptionProps[],
|
||||
): void => {
|
||||
if (selectedOption) {
|
||||
dispatch({ type: actionTypes.SET_IS_TEAM_PICKER_OPEN, payload: false });
|
||||
toast('Updating ticket. Please wait a moment.', {
|
||||
icon: <LoadingIcon />,
|
||||
});
|
||||
const value = Array.isArray(selectedOption)
|
||||
? selectedOption[0].value
|
||||
: selectedOption.value;
|
||||
updateIncident({
|
||||
id: parseInt(incidentId, 10),
|
||||
teamId: value.toString(),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const currentSev = getCurrentData(incidentData, severityMap, 'severityId');
|
||||
const currentStatus = getCurrentData(incidentData, statusMap, 'status');
|
||||
const currentTeam = getCurrentData(incidentData, teamsMap, 'teamId');
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles['log-update-dropdown']}>
|
||||
@@ -387,8 +269,11 @@ const Dropdowns: FC = () => {
|
||||
Severity
|
||||
</Typography>
|
||||
</div>
|
||||
<div>
|
||||
<div className={combinedSevClassNames} onClick={handleSevClick}>
|
||||
<div ref={refSeverity}>
|
||||
<div
|
||||
className={combinedSevClassNames}
|
||||
onClick={handleDropdownClick('severity')}
|
||||
>
|
||||
<div>
|
||||
<Typography
|
||||
variant="p4"
|
||||
@@ -414,7 +299,7 @@ const Dropdowns: FC = () => {
|
||||
handleOpenConfirmationDailog(selectedOption, SeverityType)
|
||||
}
|
||||
options={updatedSeverities}
|
||||
selectedValue={state.severity?.value.toString()}
|
||||
selectedValue={incidentData?.severityId?.toString()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -431,7 +316,7 @@ const Dropdowns: FC = () => {
|
||||
<div ref={refStatus}>
|
||||
<div
|
||||
className={combinedStatusClassNames}
|
||||
onClick={handleStatusClick}
|
||||
onClick={handleDropdownClick('status')}
|
||||
>
|
||||
<div>
|
||||
<Typography
|
||||
@@ -458,7 +343,7 @@ const Dropdowns: FC = () => {
|
||||
handleOpenConfirmationDailog(selectedOption, StatusType)
|
||||
}
|
||||
options={updatedStatuses}
|
||||
selectedValue={state.status?.value.toString()}
|
||||
selectedValue={incidentData?.status?.toString()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -473,7 +358,10 @@ const Dropdowns: FC = () => {
|
||||
</Typography>
|
||||
</div>
|
||||
<div ref={refTeam}>
|
||||
<div className={combinedTeamClassNames} onClick={handleTeamClick}>
|
||||
<div
|
||||
className={combinedTeamClassNames}
|
||||
onClick={handleDropdownClick('team')}
|
||||
>
|
||||
<div>
|
||||
<Typography
|
||||
variant="p4"
|
||||
@@ -501,7 +389,7 @@ const Dropdowns: FC = () => {
|
||||
handleOpenConfirmationDailog(selectedOption, TeamType)
|
||||
}
|
||||
options={updatedTeams}
|
||||
selectedValue={state.team?.value.toString()}
|
||||
selectedValue={incidentData?.teamId?.toString()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -14,8 +14,7 @@ const Header: FC = () => {
|
||||
const handleBacktoDashboard = (): void => {
|
||||
navigate(-1);
|
||||
};
|
||||
|
||||
//add type here and color to centralize
|
||||
//To do: add type here
|
||||
const incidentData = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
@@ -26,7 +25,11 @@ const Header: FC = () => {
|
||||
<div className={styles['back-btn']}>
|
||||
<div className={styles['back-btn-wrapper']}>
|
||||
<div className={styles['back-btn-icon']}>
|
||||
<ArrowBackIcon color="#0276FE" width={20} height={20} />
|
||||
<ArrowBackIcon
|
||||
color="var(--navi-color-blue-base)"
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['back-btn-text']}>
|
||||
<Typography variant="h4" color="var(--navi-color-blue-base)">
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
import { FC, useReducer, useEffect } from 'react';
|
||||
import { truncateText, linkSanitization } from '../utils';
|
||||
import styles from '../DescriptionContent/DescriptionContent.module.scss';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import {
|
||||
setIncidentData,
|
||||
setIncidentLogData,
|
||||
setHeaderData,
|
||||
setParticipantsData,
|
||||
} from '@src/slices/IncidentSlice';
|
||||
import {
|
||||
Typography,
|
||||
Avatar,
|
||||
BorderLessInput,
|
||||
} from '@navi/web-ui/lib/primitives';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Typography, BorderLessInput } from '@navi/web-ui/lib/primitives';
|
||||
import {
|
||||
CloseIcon,
|
||||
DeleteIconOutlined,
|
||||
@@ -20,67 +8,40 @@ import {
|
||||
ArrowDownSolidIcon,
|
||||
} from '@navi/web-ui/lib/icons';
|
||||
import { toast } from '@navi/web-ui/lib/primitives/Toast';
|
||||
import SlackIcon from '@src/assets/SlackIcon';
|
||||
import LinkIcon from '@src/assets/LinkIcon';
|
||||
import JiraLogo from '@src/assets/JiraLogo';
|
||||
import CopyIcon from '@src/assets/CopyIcon';
|
||||
import LoadingIcon from '@src/assets/LoadingIcon';
|
||||
import ConfluenceIcon from '@src/assets/ConfluenceIcon';
|
||||
import GoToLinkIcon from '@src/assets/GoToLinkIcon';
|
||||
import { ApiService } from '@src/services/api';
|
||||
import { handleCopyClick } from '@src/services/globalUtils';
|
||||
import { truncateText, linkSanitization } from '../utils';
|
||||
import useIncidentApis from '../useIncidentApis';
|
||||
import {
|
||||
ActionType,
|
||||
initialState,
|
||||
reducer,
|
||||
JIRA_VALIDATION,
|
||||
} from '../DescriptionContent/DescriptionContentProps';
|
||||
import {
|
||||
LINK_JIRA_INCIDENT,
|
||||
UNLINK_JIRA_INCIDENT,
|
||||
FETCH_INCIDENT_DATA,
|
||||
} from '../constants';
|
||||
import { LINK_JIRA_INCIDENT, UNLINK_JIRA_INCIDENT } from '../constants';
|
||||
import styles from '../DescriptionContent/DescriptionContent.module.scss';
|
||||
|
||||
const JiraLinks: FC = () => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const { id, description, jiraIds, slackChannel, incidentName, rcaLink } =
|
||||
useSelector((state: any) => state.incidentLog.incidentData);
|
||||
|
||||
const incidentParticipants = useSelector(
|
||||
(state: any) => state.incidentLog.participantsData,
|
||||
const { id, jiraLinks } = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
const reduxDispatch = useDispatch();
|
||||
|
||||
//move to hooks
|
||||
const storedEmail = localStorage.getItem('email-id');
|
||||
//import scss
|
||||
const goToLinkBlueColor = '#0276FE';
|
||||
|
||||
useEffect(() => {
|
||||
dispatch({ type: ActionType.SET_JIRA_LINKS, payload: jiraIds || [] });
|
||||
}, [jiraIds]);
|
||||
dispatch({ type: ActionType.SET_JIRA_LINKS, payload: jiraLinks || [] });
|
||||
}, [jiraLinks]);
|
||||
|
||||
//move to constant or utils
|
||||
const handleApiError = (error: any): void => {
|
||||
const errorMessage =
|
||||
error?.response?.data?.error?.message || 'An error occurred.';
|
||||
toast.error(errorMessage);
|
||||
};
|
||||
|
||||
//use from hooks below three functions
|
||||
const startIncidentSearch = (): void => {
|
||||
const endPoint = FETCH_INCIDENT_DATA(id);
|
||||
ApiService.get(endPoint)
|
||||
.then(response => {
|
||||
reduxDispatch(setIncidentData(response?.data?.data));
|
||||
dispatch({
|
||||
type: ActionType.SET_JIRA_LINKS,
|
||||
payload: response?.data?.data?.jiraLinks || [],
|
||||
});
|
||||
})
|
||||
.catch(handleApiError);
|
||||
};
|
||||
const { startIncidentSearch } = useIncidentApis();
|
||||
|
||||
const addJiraLink = (payload: any): void => {
|
||||
handleCloseIconClick();
|
||||
@@ -89,7 +50,7 @@ const JiraLinks: FC = () => {
|
||||
ApiService.post(endPoint, payload)
|
||||
.then(response => {
|
||||
toast.success(`${response?.data?.data}`);
|
||||
startIncidentSearch();
|
||||
startIncidentSearch(id);
|
||||
})
|
||||
.catch(handleApiError);
|
||||
};
|
||||
@@ -99,13 +60,12 @@ const JiraLinks: FC = () => {
|
||||
ApiService.post(endPoint, payload)
|
||||
.then(response => {
|
||||
toast.info(`${response?.data?.data}`);
|
||||
startIncidentSearch();
|
||||
startIncidentSearch(id);
|
||||
})
|
||||
.catch(handleApiError);
|
||||
};
|
||||
|
||||
const validateLink = (value: string): void => {
|
||||
//move to constants
|
||||
const urlPattern = /^https:\/\/navihq\.atlassian\.net\/browse\/.*/;
|
||||
const invalidChars = /,|\s/;
|
||||
if (value === '') {
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
import { FC } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import styles from '../Incidents.module.scss';
|
||||
import { Tooltip, Typography } from '@navi/web-ui/lib/primitives';
|
||||
import { AlertOutlineIcon } from '@navi/web-ui/lib/icons';
|
||||
import Dropdowns from '../Dropdowns';
|
||||
import styles from '../Incidents.module.scss';
|
||||
|
||||
const UpdateIncidentBox: FC = () => {
|
||||
//add type here and color to centralize
|
||||
const incidentData = useSelector(
|
||||
(state: any) => state.incidentLog.incidentData,
|
||||
);
|
||||
//To do: add types here
|
||||
const incidentParticipants = useSelector(
|
||||
(state: any) => state.incidentLog.incidentParticipants,
|
||||
(state: any) => state.incidentLog.participantsData,
|
||||
);
|
||||
|
||||
// use custom hook to fetch data
|
||||
const userData = JSON.parse(localStorage.getItem('user-data') || '{}');
|
||||
const userEmail = userData?.emailId || [];
|
||||
|
||||
const participants = incidentParticipants?.participants;
|
||||
const others = incidentParticipants?.others;
|
||||
|
||||
const participantsList = (participants || []).concat(others || []);
|
||||
const { emailId: userEmail } =
|
||||
JSON.parse(localStorage.getItem('user-data') || '{}') || {};
|
||||
const participantsList = [
|
||||
...(incidentParticipants?.participants || []),
|
||||
...(incidentParticipants?.others || []),
|
||||
];
|
||||
//To do: add types here
|
||||
const isUserParticipantList = participantsList?.some(
|
||||
(participant: any) => participant.email === userEmail,
|
||||
);
|
||||
@@ -46,7 +41,6 @@ const UpdateIncidentBox: FC = () => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Dropdowns />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -16,8 +16,7 @@ const Incident: FC = () => {
|
||||
});
|
||||
const incidentId = match?.params?.incidentId || '';
|
||||
|
||||
const { fetchIncidentLog, startIncidentSearch, fetchHeaderDetails } =
|
||||
useIncidentApis();
|
||||
const { startIncidentSearch, fetchHeaderDetails } = useIncidentApis();
|
||||
|
||||
useEffect(() => {
|
||||
startIncidentSearch(incidentId);
|
||||
@@ -36,14 +35,12 @@ const Incident: FC = () => {
|
||||
key: '1',
|
||||
label: 'Details',
|
||||
children: (
|
||||
<div>
|
||||
<div className={styles['content-wrapper']}>
|
||||
<div className={styles['audit-log']}>
|
||||
<UpdateIncidentBox />
|
||||
<ActivityLog />
|
||||
</div>
|
||||
<DescriptionContent />
|
||||
<div className={styles['content-wrapper']}>
|
||||
<div className={styles['audit-log']}>
|
||||
<UpdateIncidentBox />
|
||||
<ActivityLog />
|
||||
</div>
|
||||
<DescriptionContent />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -97,7 +97,7 @@ const useIncidentApis = () => {
|
||||
|
||||
const updateIncident = (payload: any): void => {
|
||||
const endPoint = UPDATE_INCIDENT;
|
||||
console.log('payload', payload);
|
||||
//console.log('payload', payload);
|
||||
ApiService.post(endPoint, payload)
|
||||
.then(response => {
|
||||
toast.success('Incident updated successfully');
|
||||
|
||||
@@ -3,13 +3,13 @@ import { useMatch } from 'react-router-dom';
|
||||
export const getUpdateTypeText = (updateType: number): string => {
|
||||
switch (updateType) {
|
||||
case SeverityType:
|
||||
return ' severity ';
|
||||
return 'severity';
|
||||
case StatusType:
|
||||
return ' status ';
|
||||
return 'status';
|
||||
case TeamType:
|
||||
return ' team ';
|
||||
return 'team';
|
||||
default:
|
||||
return ' severity ';
|
||||
return 'severity';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user