Skip to content

Commit 6eda9d8

Browse files
Merge pull request #552 from karthikjeeyar/codemodal-footer-configuration
add footer action button text props in Attachment components.
2 parents 446fd02 + 6e3fa43 commit 6eda9d8

File tree

6 files changed

+172
-11
lines changed

6 files changed

+172
-11
lines changed

packages/module/src/AttachmentEdit/AttachmentEdit.test.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { fireEvent, render, screen } from '@testing-library/react';
1+
import { fireEvent, render, screen, within } from '@testing-library/react';
2+
import '@testing-library/jest-dom';
23
import AttachmentEdit, { AttachmentEditProps } from './AttachmentEdit';
34

45
describe('AttachmentEdit', () => {
@@ -51,4 +52,48 @@ describe('AttachmentEdit', () => {
5152
fireEvent.click(screen.getByText('Cancel'));
5253
expect(onCancelHandler).toHaveBeenCalled();
5354
});
55+
56+
it('should render custom button text for footer actions buttons', () => {
57+
render(
58+
<AttachmentEdit
59+
code="Hello world"
60+
fileName="greetings.txt"
61+
isModalOpen={true}
62+
onCancel={jest.fn()}
63+
onSave={jest.fn()}
64+
handleModalToggle={jest.fn()}
65+
primaryActionButtonText="Save"
66+
secondaryActionButtonText="Close"
67+
/>
68+
);
69+
70+
expect(screen.getByText('Save')).toBeInTheDocument();
71+
expect(screen.getByText('Close')).toBeInTheDocument();
72+
});
73+
74+
it('should render AttachmentEdit with custom classNames', async () => {
75+
render(
76+
<AttachmentEdit
77+
code="Hello world"
78+
fileName="greetings.txt"
79+
isModalOpen={true}
80+
onCancel={jest.fn()}
81+
onSave={jest.fn()}
82+
handleModalToggle={jest.fn()}
83+
primaryActionButtonText="Save"
84+
secondaryActionButtonText="Close"
85+
modalHeaderClassName="custom-header-class"
86+
modalBodyClassName="custom-body-class"
87+
modalFooterClassName="custom-footer-class"
88+
></AttachmentEdit>
89+
);
90+
91+
const modal = screen.getByRole('dialog');
92+
const modalHeader = within(modal).getByRole('banner');
93+
expect(modalHeader).toHaveClass('custom-header-class');
94+
const modalBody = modal.querySelector('#code-modal-body');
95+
expect(modalBody).toHaveClass('custom-body-class');
96+
const modalfooter = within(modal).getByRole('contentinfo');
97+
expect(modalfooter).toHaveClass('custom-footer-class');
98+
});
5499
});

packages/module/src/AttachmentEdit/AttachmentEdit.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ export interface AttachmentEditProps {
2424
displayMode?: ChatbotDisplayMode;
2525
/** Sets modal to compact styling. */
2626
isCompact?: boolean;
27+
/** Primary action button text */
28+
primaryActionButtonText?: string;
29+
/** Secondary action button text */
30+
secondaryActionButtonText?: string;
31+
/** Class applied to modal header */
32+
modalHeaderClassName?: string;
33+
/** Class applied to modal body */
34+
modalBodyClassName?: string;
35+
/** Class applied to modal footer */
36+
modalFooterClassName?: string;
2737
}
2838

2939
export const AttachmentEdit: FunctionComponent<AttachmentEditProps> = ({
@@ -35,7 +45,12 @@ export const AttachmentEdit: FunctionComponent<AttachmentEditProps> = ({
3545
onSave,
3646
title = 'Edit attachment',
3747
displayMode = ChatbotDisplayMode.default,
38-
isCompact
48+
isCompact,
49+
modalHeaderClassName,
50+
modalBodyClassName,
51+
modalFooterClassName,
52+
primaryActionButtonText = 'Save',
53+
secondaryActionButtonText = 'Cancel'
3954
}: AttachmentEditProps) => {
4055
const handleSave = (_event: ReactMouseEvent | MouseEvent | KeyboardEvent, code) => {
4156
handleModalToggle(_event);
@@ -55,11 +70,14 @@ export const AttachmentEdit: FunctionComponent<AttachmentEditProps> = ({
5570
isModalOpen={isModalOpen}
5671
onPrimaryAction={handleSave}
5772
onSecondaryAction={handleCancel}
58-
primaryActionBtn="Save"
59-
secondaryActionBtn="Cancel"
73+
primaryActionBtn={primaryActionButtonText}
74+
secondaryActionBtn={secondaryActionButtonText}
6075
title={title}
6176
displayMode={displayMode}
6277
isCompact={isCompact}
78+
modalHeaderClassName={modalHeaderClassName}
79+
modalBodyClassName={modalBodyClassName}
80+
modalFooterClassName={modalFooterClassName}
6381
/>
6482
);
6583
};

packages/module/src/CodeModal/CodeModal.test.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, screen } from '@testing-library/react';
1+
import { render, screen, within } from '@testing-library/react';
22
import '@testing-library/jest-dom';
33
import CodeModal from './CodeModal';
44

@@ -20,4 +20,32 @@ describe('ChatbotModal', () => {
2020
);
2121
expect(screen.getByRole('dialog')).toHaveClass('pf-m-compact');
2222
});
23+
24+
it('should render CodeModal with custom classNames', async () => {
25+
render(
26+
<CodeModal
27+
isCompact
28+
code="Hello world"
29+
fileName="greetings.txt"
30+
isModalOpen={true}
31+
handleModalToggle={jest.fn()}
32+
onPrimaryAction={jest.fn()}
33+
onSecondaryAction={jest.fn()}
34+
title="Preview attachment"
35+
primaryActionBtn="Submit"
36+
secondaryActionBtn="Cancel"
37+
modalHeaderClassName="custom-header-class"
38+
modalBodyClassName="custom-body-class"
39+
modalFooterClassName="custom-footer-class"
40+
></CodeModal>
41+
);
42+
43+
const modal = screen.getByRole('dialog');
44+
const modalHeader = within(modal).getByRole('banner');
45+
expect(modalHeader).toHaveClass('custom-header-class');
46+
const modalBody = modal.querySelector('#code-modal-body');
47+
expect(modalBody).toHaveClass('custom-body-class');
48+
const modalfooter = within(modal).getByRole('contentinfo');
49+
expect(modalfooter).toHaveClass('custom-footer-class');
50+
});
2351
});

packages/module/src/CodeModal/CodeModal.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ export interface CodeModalProps {
4343
displayMode?: ChatbotDisplayMode;
4444
/** Sets modal to compact styling. */
4545
isCompact?: boolean;
46+
/** Class applied to modal header */
47+
modalHeaderClassName?: string;
48+
/** Class applied to modal body */
49+
modalBodyClassName?: string;
50+
/** Class applied to modal footer */
51+
modalFooterClassName?: string;
4652
}
4753

4854
export const CodeModal: FunctionComponent<CodeModalProps> = ({
@@ -61,6 +67,9 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
6167
title,
6268
displayMode = ChatbotDisplayMode.default,
6369
isCompact,
70+
modalHeaderClassName,
71+
modalBodyClassName,
72+
modalFooterClassName,
6473
...props
6574
}: CodeModalProps) => {
6675
const [newCode, setNewCode] = useState(code);
@@ -102,8 +111,8 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
102111
displayMode={displayMode}
103112
isCompact={isCompact}
104113
>
105-
<ModalHeader title={title} labelId="code-modal-title" />
106-
<ModalBody id="code-modal-body">
114+
<ModalHeader className={modalHeaderClassName} title={title} labelId="code-modal-title" />
115+
<ModalBody className={modalBodyClassName} id="code-modal-body">
107116
<Stack className="pf-chatbot__code-modal-body">
108117
<StackItem className="pf-chatbot__code-modal-file-details">
109118
<FileDetails fileName={fileName} />
@@ -130,7 +139,7 @@ export const CodeModal: FunctionComponent<CodeModalProps> = ({
130139
</StackItem>
131140
</Stack>
132141
</ModalBody>
133-
<ModalFooter>
142+
<ModalFooter className={modalFooterClassName}>
134143
<Button isBlock key="code-modal-primary" variant="primary" onClick={handlePrimaryAction} form="code-modal-form">
135144
{primaryActionBtn}
136145
</Button>

packages/module/src/PreviewAttachment/PreviewAttachment.test.tsx

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { fireEvent, render, screen } from '@testing-library/react';
1+
import { fireEvent, render, screen, within } from '@testing-library/react';
2+
import '@testing-library/jest-dom';
23
import { PreviewAttachment } from './PreviewAttachment';
34

45
describe('PreviewAttachment', () => {
@@ -47,4 +48,46 @@ describe('PreviewAttachment', () => {
4748

4849
expect(onDismiss).toHaveBeenCalled();
4950
});
51+
52+
it('should render custom button text for footer actions buttons', () => {
53+
render(
54+
<PreviewAttachment
55+
code="Hello world"
56+
fileName="greetings.txt"
57+
isModalOpen={true}
58+
onEdit={jest.fn()}
59+
handleModalToggle={jest.fn()}
60+
primaryActionButtonText="Edit"
61+
secondaryActionButtonText="Close"
62+
/>
63+
);
64+
65+
screen.getByText('Edit');
66+
screen.getByText('Close');
67+
});
68+
69+
it('should render PreviewAttachment with custom classNames', async () => {
70+
render(
71+
<PreviewAttachment
72+
code="Hello world"
73+
fileName="greetings.txt"
74+
isModalOpen={true}
75+
onEdit={jest.fn()}
76+
handleModalToggle={jest.fn()}
77+
primaryActionButtonText="Edit"
78+
secondaryActionButtonText="Close"
79+
modalHeaderClassName="custom-header-class"
80+
modalBodyClassName="custom-body-class"
81+
modalFooterClassName="custom-footer-class"
82+
></PreviewAttachment>
83+
);
84+
85+
const modal = screen.getByRole('dialog');
86+
const modalHeader = within(modal).getByRole('banner');
87+
expect(modalHeader).toHaveClass('custom-header-class');
88+
const modalBody = modal.querySelector('#code-modal-body');
89+
expect(modalBody).toHaveClass('custom-body-class');
90+
const modalfooter = within(modal).getByRole('contentinfo');
91+
expect(modalfooter).toHaveClass('custom-footer-class');
92+
});
5093
});

packages/module/src/PreviewAttachment/PreviewAttachment.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ export interface PreviewAttachmentProps {
2424
displayMode?: ChatbotDisplayMode;
2525
/** Sets modal to compact styling. */
2626
isCompact?: boolean;
27+
/** Primary action button text */
28+
primaryActionButtonText?: string;
29+
/** Secondary action button text */
30+
secondaryActionButtonText?: string;
31+
/** Class applied to modal header */
32+
modalHeaderClassName?: string;
33+
/** Class applied to modal body */
34+
modalBodyClassName?: string;
35+
/** Class applied to modal footer */
36+
modalFooterClassName?: string;
2737
}
2838

2939
export const PreviewAttachment: FunctionComponent<PreviewAttachmentProps> = ({
@@ -34,7 +44,12 @@ export const PreviewAttachment: FunctionComponent<PreviewAttachmentProps> = ({
3444
onDismiss = undefined,
3545
onEdit,
3646
title = 'Preview attachment',
47+
primaryActionButtonText = 'Edit',
48+
secondaryActionButtonText = 'Dismiss',
3749
displayMode = ChatbotDisplayMode.default,
50+
modalHeaderClassName,
51+
modalBodyClassName,
52+
modalFooterClassName,
3853
isCompact
3954
}: PreviewAttachmentProps) => {
4055
const handleEdit = (_event: MouseEvent | MouseEvent | KeyboardEvent) => {
@@ -58,12 +73,15 @@ export const PreviewAttachment: FunctionComponent<PreviewAttachmentProps> = ({
5873
isModalOpen={isModalOpen}
5974
onPrimaryAction={handleEdit}
6075
onSecondaryAction={handleDismiss}
61-
primaryActionBtn="Edit"
62-
secondaryActionBtn="Dismiss"
76+
primaryActionBtn={primaryActionButtonText}
77+
secondaryActionBtn={secondaryActionButtonText}
6378
title={title}
6479
isReadOnly
6580
displayMode={displayMode}
6681
isCompact={isCompact}
82+
modalHeaderClassName={modalHeaderClassName}
83+
modalBodyClassName={modalBodyClassName}
84+
modalFooterClassName={modalFooterClassName}
6785
/>
6886
);
6987
};

0 commit comments

Comments
 (0)