Skip to content

Commit 8ace405

Browse files
Mehmetcan Güleşçimehmetcangulesci
authored andcommitted
refactor(overview): replace custom modal implementation with reusable Modal component and update trace display logic
1 parent fb17ed0 commit 8ace405

File tree

6 files changed

+142
-95
lines changed

6 files changed

+142
-95
lines changed
Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,5 @@
11
import styled, { css } from 'styled-components';
22

3-
export const ModalOverlay = styled.div`
4-
position: fixed;
5-
top: 0;
6-
left: 0;
7-
right: 0;
8-
bottom: 0;
9-
background-color: ${({ theme }) => theme.modal.overlay};
10-
display: flex;
11-
align-items: center;
12-
justify-content: center;
13-
z-index: 1000;
14-
`;
15-
16-
export const ModalContent = styled.div(
17-
({ theme: { modal } }) => css`
18-
background-color: ${modal.backgroundColor};
19-
color: ${modal.color};
20-
border-radius: 8px;
21-
padding: 24px;
22-
max-width: 65vw;
23-
max-height: 80vh;
24-
overflow: auto;
25-
position: relative;
26-
border: 1px solid ${modal.border.contrast};
27-
box-shadow: 0 4px 20px ${modal.shadow};
28-
`
29-
);
30-
31-
export const ModalHeader = styled.div(
32-
({ theme: { modal } }) => css`
33-
display: flex;
34-
justify-content: space-between;
35-
align-items: center;
36-
margin-bottom: 16px;
37-
border-bottom: 1px solid ${modal.border.bottom};
38-
padding-bottom: 12px;
39-
`
40-
);
41-
42-
export const ModalTitle = styled.h3`
43-
margin: 0;
44-
font-size: 18px;
45-
font-weight: 600;
46-
`;
47-
483
export const WorkerInfo = styled.p(
494
({ theme: { modal } }) => css`
505
margin: 4px 0 0 0;
@@ -68,14 +23,3 @@ export const TraceContent = styled.div(
6823
word-break: break-word;
6924
`
7025
);
71-
72-
export const ModalFooter = styled.div(
73-
({ theme: { modal } }) => css`
74-
margin-top: 16px;
75-
padding-top: 12px;
76-
border-top: 1px solid ${modal.border.top};
77-
text-align: center;
78-
display: flex;
79-
justify-content: center;
80-
`
81-
);

frontend/src/components/Connect/Details/Overview/Overview.tsx

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import React, { useState } from 'react';
22
import * as C from 'components/common/Tag/Tag.styled';
33
import * as Metrics from 'components/common/Metrics';
44
import { Button } from 'components/common/Button/Button';
5+
import Modal from 'components/common/Modal';
56
import getTagColor from 'components/common/Tag/getTagColor';
67
import { RouterParamsClusterConnectConnector } from 'lib/paths';
78
import useAppParams from 'lib/hooks/useAppParams';
89
import { useConnector, useConnectorTasks } from 'lib/hooks/api/kafkaConnect';
9-
import { ConnectorState } from 'generated-sources';
10+
import { ConnectorState, Connector } from 'generated-sources';
1011

1112
import getTaskMetrics from './getTaskMetrics';
1213
import * as S from './Overview.styled';
@@ -24,10 +25,12 @@ const Overview: React.FC = () => {
2425

2526
const { running, failed } = getTaskMetrics(tasks);
2627

27-
const hasTraceInfo = connector.status.trace;
28+
const canShowTrace = (connector: Connector) =>
29+
connector.status.state === ConnectorState.FAILED &&
30+
!!connector.status.trace;
2831

2932
const handleStateClick = () => {
30-
if (connector.status.state === ConnectorState.FAILED && hasTraceInfo) {
33+
if (canShowTrace(connector)) {
3134
setShowTraceModal(true);
3235
}
3336
};
@@ -50,13 +53,7 @@ const Overview: React.FC = () => {
5053
<Metrics.Indicator label="State">
5154
<C.Tag
5255
color={getTagColor(connector.status.state)}
53-
style={{
54-
cursor:
55-
connector.status.state === ConnectorState.FAILED &&
56-
hasTraceInfo
57-
? 'pointer'
58-
: 'default',
59-
}}
56+
clickable={canShowTrace(connector)}
6057
onClick={handleStateClick}
6158
>
6259
{connector.status.state}
@@ -74,38 +71,30 @@ const Overview: React.FC = () => {
7471
</Metrics.Wrapper>
7572

7673
{showTraceModal && (
77-
<S.ModalOverlay onClick={() => setShowTraceModal(false)}>
78-
<S.ModalContent
79-
onClick={(e: React.MouseEvent) => e.stopPropagation()}
80-
>
81-
<S.ModalHeader>
82-
<div>
83-
<S.ModalTitle>Connector Error Details</S.ModalTitle>
84-
{connector.status.workerId && (
85-
<S.WorkerInfo>
86-
Worker: {connector.status.workerId}
87-
</S.WorkerInfo>
88-
)}
89-
</div>
90-
</S.ModalHeader>
74+
<Modal
75+
isOpen={showTraceModal}
76+
onClose={() => setShowTraceModal(false)}
77+
title="Connector Error Details"
78+
footer={
79+
<Button
80+
buttonType="primary"
81+
buttonSize="M"
82+
onClick={() => setShowTraceModal(false)}
83+
>
84+
Close
85+
</Button>
86+
}
87+
>
88+
{connector.status.workerId && (
89+
<S.WorkerInfo>Worker: {connector.status.workerId}</S.WorkerInfo>
90+
)}
9191

92+
{connector.status.trace && (
9293
<S.TraceContent>
93-
{connector.status.trace ? (
94-
<div>{connector.status.trace}</div>
95-
) : null}
94+
<div>{connector.status.trace}</div>
9695
</S.TraceContent>
97-
98-
<S.ModalFooter>
99-
<Button
100-
buttonType="primary"
101-
buttonSize="M"
102-
onClick={() => setShowTraceModal(false)}
103-
>
104-
Close
105-
</Button>
106-
</S.ModalFooter>
107-
</S.ModalContent>
108-
</S.ModalOverlay>
96+
)}
97+
</Modal>
10998
)}
11099
</>
111100
);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import styled, { css } from 'styled-components';
2+
3+
export const ModalOverlay = styled.div`
4+
position: fixed;
5+
top: 0;
6+
left: 0;
7+
right: 0;
8+
bottom: 0;
9+
background-color: ${({ theme }) => theme.modal.overlay};
10+
display: flex;
11+
align-items: center;
12+
justify-content: center;
13+
z-index: 1000;
14+
`;
15+
16+
export const ModalContent = styled.div<{
17+
maxWidth: string;
18+
maxHeight: string;
19+
}>(
20+
({ theme: { modal }, maxWidth, maxHeight }) => css`
21+
background-color: ${modal.backgroundColor};
22+
color: ${modal.color};
23+
border-radius: 8px;
24+
padding: 24px;
25+
max-width: ${maxWidth};
26+
max-height: ${maxHeight};
27+
overflow: auto;
28+
position: relative;
29+
border: 1px solid ${modal.border.contrast};
30+
box-shadow: 0 4px 20px ${modal.shadow};
31+
`
32+
);
33+
34+
export const ModalHeader = styled.div(
35+
({ theme: { modal } }) => css`
36+
display: flex;
37+
justify-content: space-between;
38+
align-items: center;
39+
margin-bottom: 16px;
40+
border-bottom: 1px solid ${modal.border.bottom};
41+
padding-bottom: 12px;
42+
`
43+
);
44+
45+
export const ModalTitle = styled.h3`
46+
margin: 0;
47+
font-size: 18px;
48+
font-weight: 600;
49+
`;
50+
51+
export const ModalBody = styled.div`
52+
margin-bottom: 16px;
53+
`;
54+
55+
export const ModalFooter = styled.div(
56+
({ theme: { modal } }) => css`
57+
margin-top: 16px;
58+
padding-top: 12px;
59+
border-top: 1px solid ${modal.border.top};
60+
text-align: center;
61+
display: flex;
62+
justify-content: center;
63+
`
64+
);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
3+
import * as S from './Modal.styled';
4+
5+
interface ModalProps {
6+
isOpen: boolean;
7+
onClose: () => void;
8+
title?: string;
9+
children: React.ReactNode;
10+
footer?: React.ReactNode;
11+
maxWidth?: string;
12+
maxHeight?: string;
13+
}
14+
15+
const Modal: React.FC<ModalProps> = ({
16+
isOpen,
17+
onClose,
18+
title,
19+
children,
20+
footer,
21+
maxWidth = '65vw',
22+
maxHeight = '80vh',
23+
}) => {
24+
if (!isOpen) return null;
25+
26+
return (
27+
<S.ModalOverlay onClick={onClose} role="dialog" aria-label="Modal">
28+
<S.ModalContent
29+
onClick={(e: React.MouseEvent) => e.stopPropagation()}
30+
maxWidth={maxWidth}
31+
maxHeight={maxHeight}
32+
>
33+
{title && (
34+
<S.ModalHeader>
35+
<S.ModalTitle>{title}</S.ModalTitle>
36+
</S.ModalHeader>
37+
)}
38+
39+
<S.ModalBody>{children}</S.ModalBody>
40+
41+
{footer && <S.ModalFooter>{footer}</S.ModalFooter>}
42+
</S.ModalContent>
43+
</S.ModalOverlay>
44+
);
45+
};
46+
47+
export default Modal;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Modal';

frontend/src/components/common/Tag/Tag.styled.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import styled from 'styled-components';
22

33
interface Props {
44
color: 'green' | 'gray' | 'yellow' | 'red' | 'white' | 'blue';
5+
clickable?: boolean;
56
}
67

78
export const Tag = styled.span.attrs({ role: 'widget' })<Props>`
@@ -18,6 +19,7 @@ export const Tag = styled.span.attrs({ role: 'widget' })<Props>`
1819
text-align: center;
1920
width: max-content;
2021
margin: 2px 0;
22+
cursor: ${({ clickable }) => (clickable ? 'pointer' : 'default')};
2123
`;
2224

2325
export const MultiLineTag = styled.div.attrs({ role: 'widget' })<Props>`

0 commit comments

Comments
 (0)