Skip to content

Commit f4e696c

Browse files
brain-frogmolker
andauthored
feat(task): Create CampaginErrorDialog Component (#670)
Co-authored-by: molker <molker@cisco.com>
1 parent f566438 commit f4e696c

7 files changed

Lines changed: 469 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.campaign-error-dialog {
2+
width: 25rem;
3+
border-radius: 0.5rem;
4+
border-color: transparent;
5+
padding: 1rem;
6+
box-shadow: 0rem 0.25rem 0.5rem 0rem rgba(0, 0, 0, 0.16), 0rem 0rem 0.0625rem 0rem rgba(0, 0, 0, 0.16);
7+
8+
&::backdrop {
9+
background-color: rgba(0, 0, 0, 0.5);
10+
}
11+
12+
.campaign-error-dialog-title {
13+
margin: 0;
14+
flex: 1;
15+
}
16+
17+
.campaign-error-dialog-message {
18+
margin-bottom: 1.5rem;
19+
}
20+
21+
.campaign-error-dialog-actions {
22+
display: flex;
23+
justify-content: flex-end;
24+
gap: 0.5rem;
25+
}
26+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React, {useEffect, useRef} from 'react';
2+
import {Button, Text} from '@momentum-design/components/dist/react';
3+
import {CampaignErrorDialogProps, ERROR_TITLES, ERROR_MESSAGE} from './campaign-error-dialog.types';
4+
import {withMetrics} from '@webex/cc-ui-logging';
5+
import './campaign-error-dialog.style.scss';
6+
7+
const CampaignErrorDialog: React.FunctionComponent<CampaignErrorDialogProps> = ({errorType, isOpen, onClose}) => {
8+
const dialogRef = useRef<HTMLDialogElement>(null);
9+
10+
useEffect(() => {
11+
const dialog = dialogRef.current;
12+
if (!dialog) return;
13+
14+
if (isOpen && !dialog.open) {
15+
dialog.showModal();
16+
} else if (!isOpen && dialog.open) {
17+
dialog.close();
18+
}
19+
}, [isOpen]);
20+
21+
useEffect(() => {
22+
const dialog = dialogRef.current;
23+
if (!dialog) return;
24+
25+
const handleClose = () => {
26+
if (isOpen) {
27+
onClose();
28+
}
29+
};
30+
31+
dialog.addEventListener('close', handleClose);
32+
return () => dialog.removeEventListener('close', handleClose);
33+
}, [isOpen, onClose]);
34+
35+
return (
36+
<dialog
37+
ref={dialogRef}
38+
className="campaign-error-dialog"
39+
data-testid="campaign-error-dialog"
40+
aria-labelledby="campaign-error-dialog-title"
41+
>
42+
<Text
43+
id="campaign-error-dialog-title"
44+
tagname="h2"
45+
type="body-large-bold"
46+
className="campaign-error-dialog-title"
47+
data-testid="campaign-error-dialog-title"
48+
>
49+
{ERROR_TITLES[errorType]}
50+
</Text>
51+
<Text
52+
id="campaign-error-dialog-message"
53+
tagname="p"
54+
type="body-midsize-regular"
55+
className="campaign-error-dialog-message"
56+
data-testid="campaign-error-dialog-message"
57+
>
58+
{ERROR_MESSAGE}
59+
</Text>
60+
<div className="campaign-error-dialog-actions">
61+
<Button onClick={onClose} data-testid="campaign-error-dialog-ok-button">
62+
OK
63+
</Button>
64+
</div>
65+
</dialog>
66+
);
67+
};
68+
69+
const CampaignErrorDialogWithMetrics = withMetrics(CampaignErrorDialog, 'CampaignErrorDialog');
70+
export default CampaignErrorDialogWithMetrics;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export type CampaignErrorType = 'ACCEPT_FAILED' | 'SKIP_FAILED' | 'REMOVE_FAILED';
2+
3+
export interface CampaignErrorDialogProps {
4+
errorType: CampaignErrorType;
5+
isOpen: boolean;
6+
onClose: () => void;
7+
}
8+
9+
export const ERROR_TITLES: Record<CampaignErrorType, string> = {
10+
ACCEPT_FAILED: "Can't accept contact",
11+
SKIP_FAILED: "Can't skip contact",
12+
REMOVE_FAILED: "Can't remove contact",
13+
};
14+
15+
export const ERROR_MESSAGE =
16+
'We ran into an issue connecting you with this contact. Check your network connection and try again.';

packages/contact-center/cc-components/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import CallControlCADComponent from './components/task/CallControlCAD/call-contr
55
import IncomingTaskComponent from './components/task/IncomingTask/incoming-task';
66
import TaskListComponent from './components/task/TaskList/task-list';
77
import OutdialCallComponent from './components/task/OutdialCall/outdial-call';
8+
import CampaignErrorDialogComponent from './components/task/CampaignErrorDialog/campaign-error-dialog';
89
import RealTimeTranscriptComponent from './components/task/RealTimeTranscript/real-time-transcript';
910

1011
export {
@@ -15,9 +16,11 @@ export {
1516
IncomingTaskComponent,
1617
TaskListComponent,
1718
OutdialCallComponent,
19+
CampaignErrorDialogComponent,
1820
RealTimeTranscriptComponent,
1921
};
2022
export * from './components/StationLogin/constants';
2123
export * from './components/StationLogin/station-login.types';
2224
export * from './components/UserState/user-state.types';
2325
export * from './components/task/task.types';
26+
export * from './components/task/CampaignErrorDialog/campaign-error-dialog.types';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`CampaignErrorDialog Snapshots Rendering should match snapshot for ACCEPT_FAILED error type 1`] = `
4+
<div>
5+
<dialog
6+
aria-labelledby="campaign-error-dialog-title"
7+
class="campaign-error-dialog"
8+
data-testid="campaign-error-dialog"
9+
>
10+
<mdc-text
11+
class="campaign-error-dialog-title"
12+
data-testid="campaign-error-dialog-title"
13+
id="campaign-error-dialog-title"
14+
>
15+
Can't accept contact
16+
</mdc-text>
17+
<mdc-text
18+
class="campaign-error-dialog-message"
19+
data-testid="campaign-error-dialog-message"
20+
id="campaign-error-dialog-message"
21+
>
22+
We ran into an issue connecting you with this contact. Check your network connection and try again.
23+
</mdc-text>
24+
<div
25+
class="campaign-error-dialog-actions"
26+
>
27+
<mdc-button
28+
data-testid="campaign-error-dialog-ok-button"
29+
>
30+
OK
31+
</mdc-button>
32+
</div>
33+
</dialog>
34+
</div>
35+
`;
36+
37+
exports[`CampaignErrorDialog Snapshots Rendering should match snapshot for REMOVE_FAILED error type 1`] = `
38+
<div>
39+
<dialog
40+
aria-labelledby="campaign-error-dialog-title"
41+
class="campaign-error-dialog"
42+
data-testid="campaign-error-dialog"
43+
>
44+
<mdc-text
45+
class="campaign-error-dialog-title"
46+
data-testid="campaign-error-dialog-title"
47+
id="campaign-error-dialog-title"
48+
>
49+
Can't remove contact
50+
</mdc-text>
51+
<mdc-text
52+
class="campaign-error-dialog-message"
53+
data-testid="campaign-error-dialog-message"
54+
id="campaign-error-dialog-message"
55+
>
56+
We ran into an issue connecting you with this contact. Check your network connection and try again.
57+
</mdc-text>
58+
<div
59+
class="campaign-error-dialog-actions"
60+
>
61+
<mdc-button
62+
data-testid="campaign-error-dialog-ok-button"
63+
>
64+
OK
65+
</mdc-button>
66+
</div>
67+
</dialog>
68+
</div>
69+
`;
70+
71+
exports[`CampaignErrorDialog Snapshots Rendering should match snapshot for SKIP_FAILED error type 1`] = `
72+
<div>
73+
<dialog
74+
aria-labelledby="campaign-error-dialog-title"
75+
class="campaign-error-dialog"
76+
data-testid="campaign-error-dialog"
77+
>
78+
<mdc-text
79+
class="campaign-error-dialog-title"
80+
data-testid="campaign-error-dialog-title"
81+
id="campaign-error-dialog-title"
82+
>
83+
Can't skip contact
84+
</mdc-text>
85+
<mdc-text
86+
class="campaign-error-dialog-message"
87+
data-testid="campaign-error-dialog-message"
88+
id="campaign-error-dialog-message"
89+
>
90+
We ran into an issue connecting you with this contact. Check your network connection and try again.
91+
</mdc-text>
92+
<div
93+
class="campaign-error-dialog-actions"
94+
>
95+
<mdc-button
96+
data-testid="campaign-error-dialog-ok-button"
97+
>
98+
OK
99+
</mdc-button>
100+
</div>
101+
</dialog>
102+
</div>
103+
`;
104+
105+
exports[`CampaignErrorDialog Snapshots Rendering should match snapshot when dialog is closed 1`] = `
106+
<div>
107+
<dialog
108+
aria-labelledby="campaign-error-dialog-title"
109+
class="campaign-error-dialog"
110+
data-testid="campaign-error-dialog"
111+
>
112+
<mdc-text
113+
class="campaign-error-dialog-title"
114+
data-testid="campaign-error-dialog-title"
115+
id="campaign-error-dialog-title"
116+
>
117+
Can't accept contact
118+
</mdc-text>
119+
<mdc-text
120+
class="campaign-error-dialog-message"
121+
data-testid="campaign-error-dialog-message"
122+
id="campaign-error-dialog-message"
123+
>
124+
We ran into an issue connecting you with this contact. Check your network connection and try again.
125+
</mdc-text>
126+
<div
127+
class="campaign-error-dialog-actions"
128+
>
129+
<mdc-button
130+
data-testid="campaign-error-dialog-ok-button"
131+
>
132+
OK
133+
</mdc-button>
134+
</div>
135+
</dialog>
136+
</div>
137+
`;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React from 'react';
2+
import {render} from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import CampaignErrorDialogComponent from '../../../../src/components/task/CampaignErrorDialog/campaign-error-dialog';
5+
import {CampaignErrorDialogProps} from '../../../../src/components/task/CampaignErrorDialog/campaign-error-dialog.types';
6+
7+
// Mock HTMLDialogElement methods
8+
HTMLDialogElement.prototype.showModal = jest.fn();
9+
HTMLDialogElement.prototype.close = jest.fn();
10+
11+
describe('CampaignErrorDialog Snapshots', () => {
12+
const mockOnClose = jest.fn();
13+
14+
const defaultProps: CampaignErrorDialogProps = {
15+
errorType: 'ACCEPT_FAILED',
16+
isOpen: false,
17+
onClose: mockOnClose,
18+
};
19+
20+
beforeEach(() => {
21+
jest.clearAllMocks();
22+
(HTMLDialogElement.prototype.showModal as jest.Mock).mockClear();
23+
(HTMLDialogElement.prototype.close as jest.Mock).mockClear();
24+
});
25+
26+
describe('Rendering', () => {
27+
it('should match snapshot for ACCEPT_FAILED error type', () => {
28+
const {container} = render(
29+
<CampaignErrorDialogComponent {...defaultProps} errorType="ACCEPT_FAILED" isOpen={true} />
30+
);
31+
expect(container).toMatchSnapshot();
32+
});
33+
34+
it('should match snapshot for SKIP_FAILED error type', () => {
35+
const {container} = render(
36+
<CampaignErrorDialogComponent {...defaultProps} errorType="SKIP_FAILED" isOpen={true} />
37+
);
38+
expect(container).toMatchSnapshot();
39+
});
40+
41+
it('should match snapshot for REMOVE_FAILED error type', () => {
42+
const {container} = render(
43+
<CampaignErrorDialogComponent {...defaultProps} errorType="REMOVE_FAILED" isOpen={true} />
44+
);
45+
expect(container).toMatchSnapshot();
46+
});
47+
48+
it('should match snapshot when dialog is closed', () => {
49+
const {container} = render(<CampaignErrorDialogComponent {...defaultProps} isOpen={false} />);
50+
expect(container).toMatchSnapshot();
51+
});
52+
});
53+
});

0 commit comments

Comments
 (0)