mirror of
https://github.com/datahub-project/datahub.git
synced 2025-12-28 02:17:53 +00:00
refactor(): Fix incidents feedback on QA (#13044)
Co-authored-by: Aseem Bansal <asmbansal2@gmail.com> Co-authored-by: John Joyce <john@Mac-307.lan>
This commit is contained in:
parent
18aa1f076d
commit
87af4b9d53
@ -31,7 +31,8 @@ export const IncidentDetailDrawer = ({
|
||||
}: IncidentDetailDrawerProps) => {
|
||||
const [isEditView, setIsEditView] = useState<boolean>(false);
|
||||
const showEditor = isEditView || mode === IncidentAction.CREATE;
|
||||
const modalClosePopup = () => {
|
||||
|
||||
const onCloseModal = () => {
|
||||
if (showEditor) {
|
||||
Modal.confirm({
|
||||
title: 'Exit Editor',
|
||||
@ -48,15 +49,21 @@ export const IncidentDetailDrawer = ({
|
||||
onCancel?.();
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (i?: Incident) => {
|
||||
setIsEditView(false);
|
||||
onSubmit?.(i);
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickOutside onClickOutside={modalClosePopup} wrapperClassName="incident-monitor-builder-modal">
|
||||
<ClickOutside onClickOutside={onCloseModal} wrapperClassName="incident-monitor-builder-modal">
|
||||
<Drawer
|
||||
width={600}
|
||||
placement="right"
|
||||
closable={false}
|
||||
visible
|
||||
bodyStyle={modalBodyStyle}
|
||||
onClose={modalClosePopup}
|
||||
onClose={onCloseModal}
|
||||
>
|
||||
<IncidentDrawerHeader
|
||||
mode={mode}
|
||||
@ -73,8 +80,8 @@ export const IncidentDetailDrawer = ({
|
||||
data={incident}
|
||||
mode={mode}
|
||||
incidentUrn={incident?.urn}
|
||||
onSubmit={onSubmit}
|
||||
entity={entity}
|
||||
onSubmit={handleSubmit}
|
||||
/>
|
||||
) : (
|
||||
<IncidentView incident={incident as IncidentTableRow} />
|
||||
|
||||
@ -34,7 +34,6 @@ export const IncidentEditor = ({
|
||||
incidentUrn,
|
||||
onSubmit,
|
||||
data,
|
||||
onClose,
|
||||
mode = IncidentAction.CREATE,
|
||||
entity,
|
||||
}: IncidentEditorProps) => {
|
||||
@ -60,7 +59,6 @@ export const IncidentEditor = ({
|
||||
incidentUrn,
|
||||
mode,
|
||||
onSubmit,
|
||||
onClose,
|
||||
user,
|
||||
assignees: cachedAssignees,
|
||||
linkedAssets: cachedLinkedAssets,
|
||||
|
||||
@ -70,7 +70,7 @@ export const getCacheIncident = ({
|
||||
return newIncident;
|
||||
};
|
||||
|
||||
export const useIncidentHandler = ({ mode, onSubmit, incidentUrn, onClose, user, assignees, linkedAssets, entity }) => {
|
||||
export const useIncidentHandler = ({ mode, onSubmit, incidentUrn, user, assignees, linkedAssets, entity }) => {
|
||||
const [raiseIncidentMutation] = useRaiseIncidentMutation();
|
||||
const [updateIncidentMutation] = useUpdateIncidentMutation();
|
||||
const [form] = Form.useForm();
|
||||
@ -118,7 +118,6 @@ export const useIncidentHandler = ({ mode, onSubmit, incidentUrn, onClose, user,
|
||||
|
||||
const finalizeSubmission = () => {
|
||||
onSubmit?.();
|
||||
onClose?.();
|
||||
};
|
||||
|
||||
const handleSubmissionError = (error: any) => {
|
||||
|
||||
@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Empty } from 'antd';
|
||||
|
||||
import { useGetEntityIncidentsQuery } from '../../../../../graphql/incident.generated';
|
||||
import { useEntityData } from '../../../../entity/shared/EntityContext';
|
||||
import { useEntityData, useRefetch } from '../../../../entity/shared/EntityContext';
|
||||
import { PAGE_SIZE } from './incidentUtils';
|
||||
import { EntityPrivileges, Incident } from '../../../../../types.generated';
|
||||
import { combineEntityDataWithSiblings } from '../../../../entity/shared/siblingUtils';
|
||||
@ -19,6 +19,7 @@ import { getQueryParams } from '../Dataset/Validations/assertionUtils';
|
||||
|
||||
export const IncidentList = () => {
|
||||
const { urn } = useEntityData();
|
||||
const refetchEntity = useRefetch();
|
||||
const [showIncidentBuilder, setShowIncidentBuilder] = useState(false);
|
||||
const [entity, setEntity] = useState<EntityStagedForIncident>();
|
||||
const [visibleIncidents, setVisibleIncidents] = useState<IncidentTable>({
|
||||
@ -36,7 +37,11 @@ export const IncidentList = () => {
|
||||
|
||||
const [selectedFilters, setSelectedFilters] = useState<IncidentListFilter>(incidentDefaultFilters);
|
||||
// Fetch filtered incidents.
|
||||
const { loading, data, refetch } = useGetEntityIncidentsQuery({
|
||||
const {
|
||||
loading,
|
||||
data,
|
||||
refetch: refetchIncidents,
|
||||
} = useGetEntityIncidentsQuery({
|
||||
variables: {
|
||||
urn,
|
||||
start: 0,
|
||||
@ -76,6 +81,11 @@ export const IncidentList = () => {
|
||||
|
||||
const privileges = (data?.entity as any)?.privileges as EntityPrivileges;
|
||||
|
||||
const refetch = () => {
|
||||
refetchEntity();
|
||||
refetchIncidents();
|
||||
};
|
||||
|
||||
const renderListTable = () => {
|
||||
if (loading) {
|
||||
return <IncidentListLoading />;
|
||||
@ -94,6 +104,7 @@ export const IncidentList = () => {
|
||||
}
|
||||
return <Empty description="No incidents yet" image={Empty.PRESENTED_IMAGE_SIMPLE} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<IncidentTitleContainer
|
||||
@ -115,10 +126,10 @@ export const IncidentList = () => {
|
||||
urn={urn}
|
||||
mode={IncidentAction.CREATE}
|
||||
onSubmit={() => {
|
||||
setShowIncidentBuilder(false);
|
||||
setTimeout(() => {
|
||||
refetch();
|
||||
}, 2000);
|
||||
setShowIncidentBuilder(false);
|
||||
}, 3000);
|
||||
}}
|
||||
onCancel={() => setShowIncidentBuilder(false)}
|
||||
entity={entity}
|
||||
|
||||
@ -4,7 +4,7 @@ import { Table } from '@src/alchemy-components';
|
||||
import { SortingState } from '@src/alchemy-components/components/Table/types';
|
||||
import { EntityPrivileges } from '@src/types.generated';
|
||||
import { IncidentDetailDrawer } from './AcrylComponents/IncidentDetailDrawer';
|
||||
import { IncidentListFilter, IncidentTable, IncidentTableRow } from './types';
|
||||
import { IncidentListFilter, IncidentTable } from './types';
|
||||
import { useIncidentsTableColumns, useOpenIncidentDetailModal } from './hooks';
|
||||
import { getSiblingWithUrn } from '../Dataset/Validations/acrylUtils';
|
||||
import { StyledTableContainer } from './styledComponents';
|
||||
@ -31,40 +31,28 @@ export const IncidentListTable = ({ incidentData, filter, refetch, privileges }:
|
||||
);
|
||||
|
||||
// get columns data from the custom hooks
|
||||
const incidentsTableCols = useIncidentsTableColumns(privileges);
|
||||
const incidentsTableCols = useIncidentsTableColumns(refetch, privileges);
|
||||
const [sortedOptions, setSortedOptions] = useState<{ sortColumn: string; sortOrder: SortingState }>({
|
||||
sortColumn: '',
|
||||
sortOrder: SortingState.ORIGINAL,
|
||||
});
|
||||
|
||||
const [focusIncidentUrn, setFocusIncidentUrn] = useState<string | null>(null);
|
||||
const [focusIncidentData, setFocusIncidentData] = useState<IncidentTableRow>();
|
||||
|
||||
const focusedIncident = incidentData.incidents.find((incident) => incident.urn === focusIncidentUrn);
|
||||
const focusedEntityUrn = focusedIncident ? entityData?.urn : undefined;
|
||||
const focusedIncidentEntity =
|
||||
focusedEntityUrn && entityData ? getSiblingWithUrn(entityData, focusedEntityUrn) : undefined;
|
||||
|
||||
const getGroupData = () => {
|
||||
return (incidentData?.groupBy && incidentData?.groupBy[groupBy]) || [];
|
||||
};
|
||||
|
||||
const updateIncidentData = (selectedURN: string) => {
|
||||
const data = groupBy ? getGroupData() : incidentData.incidents || [];
|
||||
const urnExists = data
|
||||
.map((item) => item.incidents)
|
||||
.flat()
|
||||
.filter((incident) => selectedURN.includes(incident.urn));
|
||||
setFocusIncidentData(urnExists[0]);
|
||||
};
|
||||
|
||||
useOpenIncidentDetailModal(setFocusIncidentUrn, updateIncidentData);
|
||||
|
||||
const focusedIncidentEntity =
|
||||
focusedEntityUrn && entityData ? getSiblingWithUrn(entityData, focusedEntityUrn) : undefined;
|
||||
useOpenIncidentDetailModal(setFocusIncidentUrn);
|
||||
|
||||
useEffect(() => {
|
||||
if (focusIncidentUrn && !focusedIncident) {
|
||||
setFocusIncidentUrn(null);
|
||||
setFocusIncidentData(undefined);
|
||||
}
|
||||
}, [focusIncidentUrn, focusedIncident]);
|
||||
|
||||
@ -84,7 +72,6 @@ export const IncidentListTable = ({ incidentData, filter, refetch, privileges }:
|
||||
};
|
||||
|
||||
const onRowClick = (record) => {
|
||||
setFocusIncidentData(record);
|
||||
setFocusIncidentUrn(record.urn);
|
||||
};
|
||||
|
||||
@ -139,14 +126,13 @@ export const IncidentListTable = ({ incidentData, filter, refetch, privileges }:
|
||||
<IncidentDetailDrawer
|
||||
urn={focusIncidentUrn}
|
||||
mode={IncidentAction.EDIT}
|
||||
incident={focusIncidentData}
|
||||
incident={focusedIncident}
|
||||
privileges={privileges}
|
||||
onCancel={() => setFocusIncidentUrn(null)}
|
||||
onSubmit={() => {
|
||||
setTimeout(() => {
|
||||
refetch();
|
||||
}, 2000);
|
||||
setFocusIncidentUrn(null);
|
||||
}, 3000);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -19,6 +19,7 @@ import { PAGE_SIZE, updateActiveIncidentInCache } from './incidentUtils';
|
||||
|
||||
type IncidentResolutionPopupProps = {
|
||||
incident: IncidentTableRow;
|
||||
refetch: () => void;
|
||||
handleClose: () => void;
|
||||
};
|
||||
|
||||
@ -32,7 +33,7 @@ const ModalTitle = () => (
|
||||
</ModalTitleContainer>
|
||||
);
|
||||
|
||||
export const IncidentResolutionPopup = ({ incident, handleClose }: IncidentResolutionPopupProps) => {
|
||||
export const IncidentResolutionPopup = ({ incident, refetch, handleClose }: IncidentResolutionPopupProps) => {
|
||||
const client = useApolloClient();
|
||||
const { user } = useUserContext();
|
||||
const { urn, entityType } = useEntityData();
|
||||
@ -79,10 +80,10 @@ export const IncidentResolutionPopup = ({ incident, handleClose }: IncidentResol
|
||||
incidentUrn: incident.urn,
|
||||
user,
|
||||
});
|
||||
|
||||
updateActiveIncidentInCache(client, urn, updatedIncident, PAGE_SIZE);
|
||||
message.success({ content: 'Incident updated!', duration: 2 });
|
||||
handleClose?.();
|
||||
setTimeout(() => refetch(), 3000);
|
||||
})
|
||||
.catch((error) => {
|
||||
handleGraphQLError({
|
||||
|
||||
@ -30,13 +30,14 @@ const ResolveButton = styled(Button)`
|
||||
|
||||
export const IncidentResolveButton = ({
|
||||
incident,
|
||||
refetch,
|
||||
privileges,
|
||||
}: {
|
||||
incident: IncidentTableRow;
|
||||
refetch: () => void;
|
||||
privileges?: EntityPrivileges;
|
||||
}) => {
|
||||
const canEditIncidents = privileges?.canEditIncidents || false;
|
||||
|
||||
const me = useUserContext();
|
||||
const [showResolvePopup, setShowResolvePopup] = useState(false);
|
||||
const [incidentResolver, setIncidentResolver] = useState<CorpUser | any>(null);
|
||||
@ -45,6 +46,7 @@ export const IncidentResolveButton = ({
|
||||
me?.urn === incidentResolver?.urn
|
||||
? ME
|
||||
: incidentResolver?.properties?.displayName || incidentResolver?.username;
|
||||
|
||||
useEffect(() => {
|
||||
if (incident?.lastUpdated?.actor) {
|
||||
getAssigneeEntities({
|
||||
@ -132,7 +134,9 @@ export const IncidentResolveButton = ({
|
||||
showPopoverWithResolver
|
||||
)}
|
||||
|
||||
{showResolvePopup && <IncidentResolutionPopup incident={incident} handleClose={handleShowPopup} />}
|
||||
{showResolvePopup && (
|
||||
<IncidentResolutionPopup incident={incident} refetch={refetch} handleClose={handleShowPopup} />
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
@ -15,7 +15,7 @@ import { IncidentResolveButton } from './IncidentResolveButton';
|
||||
import { IncidentAssigneeAvatarStack } from './IncidentAssigneeAvatarStack';
|
||||
import { CategoryType } from './styledComponents';
|
||||
|
||||
export const useIncidentsTableColumns = (privileges?: EntityPrivileges) => {
|
||||
export const useIncidentsTableColumns = (refetch: () => void, privileges?: EntityPrivileges) => {
|
||||
return useMemo(() => {
|
||||
const columns = [
|
||||
{
|
||||
@ -107,13 +107,17 @@ export const useIncidentsTableColumns = (privileges?: EntityPrivileges) => {
|
||||
key: 'actions',
|
||||
width: '15%',
|
||||
render: (record) => {
|
||||
return !record.groupName && <IncidentResolveButton incident={record} privileges={privileges} />;
|
||||
return (
|
||||
!record.groupName && (
|
||||
<IncidentResolveButton incident={record} privileges={privileges} refetch={refetch} />
|
||||
)
|
||||
);
|
||||
},
|
||||
alignment: 'right' as AlignmentOptions,
|
||||
},
|
||||
];
|
||||
return columns;
|
||||
}, [privileges]);
|
||||
}, [privileges, refetch]);
|
||||
};
|
||||
|
||||
export const useIncidentURNCopyLink = (Urn: string) => {
|
||||
@ -172,7 +176,7 @@ export const getOnOpenAssertionLink = (Urn: string) => {
|
||||
* @param {Function} setFocusAssertionUrn - Function to set details of the viewing assertion and open detail Modal.
|
||||
* @returns {Object} Object containing the 'assertionUrnParam' from the URL.
|
||||
*/
|
||||
export const useOpenIncidentDetailModal = (setFocusIncidentUrn, updateIncidentData) => {
|
||||
export const useOpenIncidentDetailModal = (setFocusIncidentUrn) => {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const incidentUrnParam = getQueryParams('incident_urn', location);
|
||||
@ -182,7 +186,6 @@ export const useOpenIncidentDetailModal = (setFocusIncidentUrn, updateIncidentDa
|
||||
const decodedIncidentUrn = decodeURIComponent(incidentUrnParam);
|
||||
|
||||
setFocusIncidentUrn(decodedIncidentUrn);
|
||||
updateIncidentData(decodedIncidentUrn);
|
||||
|
||||
// Remove the query parameter from the URL
|
||||
const newUrlParams = new URLSearchParams(location.search);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user