-
-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5191 from kobotoolbox/task-884-implement-reusable…
…-export-button [TASK-884] Implement reusable export button
- Loading branch information
Showing
4 changed files
with
123 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
jsapp/js/components/exportToEmailButton/exportToEmailButton.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import Button from '../common/button'; | ||
import KoboPrompt from '../modals/koboPrompt'; | ||
import {useState} from 'react'; | ||
import {handleApiFail} from 'jsapp/js/api'; | ||
import type {FailResponse} from 'jsapp/js/dataInterface'; | ||
|
||
const MessageModal = ({onClose}: {onClose: () => void}) => ( | ||
<KoboPrompt | ||
isOpen | ||
onRequestClose={onClose} | ||
title={t('Exporting data')} | ||
buttons={[ | ||
{ | ||
label: 'Ok', | ||
onClick: onClose, | ||
}, | ||
]} | ||
> | ||
{t( | ||
"Your export request is currently being processed. Once the export is complete, you'll receive an email with all the details." | ||
)} | ||
</KoboPrompt> | ||
); | ||
|
||
/** | ||
* Button to be used in views that export data to email. | ||
* The button receives a label and an export function that should return a promise. | ||
* The function is called when the button is clicked and if no error occurs, a message is shown to the user. | ||
*/ | ||
export default function ExportToEmailButton({ | ||
exportFunction, | ||
label, | ||
}: { | ||
exportFunction: () => Promise<void>; | ||
label: string; | ||
}) { | ||
const [isMessageOpen, setIsMessageOpen] = useState(false); | ||
const [isPending, setIsPending] = useState(false); | ||
|
||
const handleClick = () => { | ||
setIsPending(true); | ||
exportFunction() | ||
.then(() => { | ||
setIsMessageOpen(true); | ||
}) | ||
.catch((error) => handleApiFail(error as FailResponse)) | ||
.finally(() => { | ||
setIsPending(false); | ||
}); | ||
}; | ||
|
||
return ( | ||
<> | ||
<Button | ||
size='m' | ||
type='primary' | ||
label={label} | ||
startIcon='download' | ||
onClick={handleClick} | ||
isPending={isPending} | ||
/> | ||
{isMessageOpen && ( | ||
<MessageModal onClose={() => setIsMessageOpen(false)} /> | ||
)} | ||
</> | ||
); | ||
} |
23 changes: 23 additions & 0 deletions
23
jsapp/js/components/exportToEmailButton/exportToEmailButton.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type {Meta, StoryFn} from '@storybook/react'; | ||
|
||
import ExportToEmailButton from './exportToEmailButton.component'; | ||
|
||
export default { | ||
title: 'misc/ExportToEmailButton', | ||
component: ExportToEmailButton, | ||
argTypes: { | ||
label: { | ||
control: 'text', | ||
}, | ||
}, | ||
} as Meta<typeof ExportToEmailButton>; | ||
|
||
const Template: StoryFn<typeof ExportToEmailButton> = (args) => ( | ||
<ExportToEmailButton {...args} /> | ||
); | ||
|
||
export const Primary = Template.bind({}); | ||
Primary.args = { | ||
label: 'Export all data', | ||
exportFunction: () => new Promise((resolve) => setTimeout(resolve, 500)), | ||
}; |