Mirror of https://github.com/roostorg/osprey github.com/roostorg/osprey
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 126 lines 4.0 kB view raw
1import * as React from 'react'; 2import { DownloadOutlined } from '@ant-design/icons'; 3import { Alert, Form, Input, Modal, Radio } from 'antd'; 4import { Store } from 'antd/lib/form/interface'; 5import { RadioChangeEvent } from 'antd/lib/radio'; 6 7import { getTopNQueryResultCSV } from '../../actions/EventActions'; 8import useQueryStore from '../../stores/QueryStore'; 9import OspreyButton, { ButtonColors } from '../../uikit/OspreyButton'; 10import Text, { TextSizes } from '../../uikit/Text'; 11 12import styles from './CSVDownloadModal.module.css'; 13 14interface CSVDownloadModalProps { 15 disabled: boolean; 16 dimension: string; 17} 18 19enum RadioOptions { 20 MAXIMUM, 21 CUSTOM, 22} 23 24const MAXIMUM_ROWS = 100000; 25 26function validateLimitInput(_: any, limitStr: string): Promise<void> { 27 const limit = Number(limitStr); 28 29 if (isNaN(limit) || limit <= 0) { 30 return Promise.reject('Invalid number'); /* eslint-disable-line */ 31 } else if (limit > MAXIMUM_ROWS) { 32 return Promise.reject('Maximum 100,000 rows allowed per CSV'); /* eslint-disable-line */ 33 } 34 35 return Promise.resolve(); 36} 37 38const CSVDownloadModal = ({ disabled, dimension }: CSVDownloadModalProps) => { 39 const [isCSVDownloading, setIsCSVDownloading] = React.useState(false); 40 const [isModalOpen, setIsModalOpen] = React.useState(false); 41 const [limitOption, setLimitOption] = React.useState(RadioOptions.MAXIMUM); 42 43 const executedQuery = useQueryStore((state) => state.executedQuery); 44 const entityFeatureFilters = useQueryStore((state) => state.entityFeatureFilters); 45 const [form] = Form.useForm(); 46 47 const handleDownload = async (values?: Store) => { 48 const maybeLimit = Number(values?.limit); 49 const limit = isNaN(maybeLimit) ? MAXIMUM_ROWS : maybeLimit; 50 51 setIsCSVDownloading(true); 52 setIsModalOpen(false); 53 await getTopNQueryResultCSV({ ...executedQuery, entityFeatureFilters }, dimension, limit); 54 setIsCSVDownloading(false); 55 56 form.resetFields(); 57 setLimitOption(RadioOptions.MAXIMUM); 58 }; 59 60 const handleRadioClick = (e: RadioChangeEvent) => { 61 setLimitOption(e.target.value); 62 }; 63 64 const renderLimitForm = () => { 65 return ( 66 <Form form={form} onFinish={handleDownload}> 67 <Form.Item name="limit" rules={[{ required: true }, { validator: validateLimitInput }]} validateFirst> 68 <Input className={styles.limitInput} placeholder="Number of rows (maximum 100,000)" /> 69 </Form.Item> 70 </Form> 71 ); 72 }; 73 74 return ( 75 <> 76 <OspreyButton 77 color={ButtonColors.LINK_GRAY} 78 onClick={() => setIsModalOpen(true)} 79 disabled={disabled} 80 loading={isCSVDownloading} 81 key="download" 82 > 83 <DownloadOutlined /> 84 Download CSV 85 </OspreyButton> 86 <Modal 87 title={<Text size={TextSizes.H5}>Download CSV</Text>} 88 width={400} 89 visible={isModalOpen} 90 onCancel={() => setIsModalOpen(false)} 91 footer={ 92 <div className={styles.footer}> 93 <OspreyButton key="cancel" onClick={() => setIsModalOpen(false)}> 94 Cancel 95 </OspreyButton> 96 <OspreyButton 97 key="ok" 98 color={ButtonColors.DARK_BLUE} 99 onClick={limitOption === RadioOptions.CUSTOM ? form.submit : handleDownload} 100 > 101 OK 102 </OspreyButton> 103 </div> 104 } 105 > 106 <Alert 107 style={{ marginBottom: 12 }} 108 message="Large CSV downloads can take several minutes." 109 type="warning" 110 showIcon 111 /> 112 <Radio.Group value={limitOption} onChange={handleRadioClick}> 113 <Radio className={styles.radioOption} value={RadioOptions.MAXIMUM}> 114 Download Maximum Rows (up to 100,000) 115 </Radio> 116 <Radio className={styles.radioOption} value={RadioOptions.CUSTOM}> 117 Set Row Limit 118 </Radio> 119 </Radio.Group> 120 {limitOption === RadioOptions.CUSTOM ? renderLimitForm() : null} 121 </Modal> 122 </> 123 ); 124}; 125 126export default CSVDownloadModal;