mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: read productivity report from profile (#8662)
This commit is contained in:
		
							parent
							
								
									7aa74cccd3
								
							
						
					
					
						commit
						b00d449c72
					
				| @ -0,0 +1,105 @@ | ||||
| import { render } from 'utils/testRenderer'; | ||||
| import { screen } from '@testing-library/react'; | ||||
| import { testServerRoute, testServerSetup } from 'utils/testServer'; | ||||
| import { ProductivityEmailSubscription } from './ProductivityEmailSubscription'; | ||||
| import ToastRenderer from '../../../common/ToastRenderer/ToastRenderer'; | ||||
| 
 | ||||
| const server = testServerSetup(); | ||||
| 
 | ||||
| const setupSubscribeApi = () => { | ||||
|     testServerRoute( | ||||
|         server, | ||||
|         '/api/admin/email-subscription/productivity-report', | ||||
|         {}, | ||||
|         'put', | ||||
|         202, | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const setupUnsubscribeApi = () => { | ||||
|     testServerRoute( | ||||
|         server, | ||||
|         '/api/admin/email-subscription/productivity-report', | ||||
|         {}, | ||||
|         'delete', | ||||
|         202, | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| const setupErrorApi = () => { | ||||
|     testServerRoute( | ||||
|         server, | ||||
|         '/api/admin/email-subscription/productivity-report', | ||||
|         { message: 'user error' }, | ||||
|         'delete', | ||||
|         400, | ||||
|     ); | ||||
| }; | ||||
| 
 | ||||
| test('unsubscribe', async () => { | ||||
|     setupUnsubscribeApi(); | ||||
|     let changed = false; | ||||
|     render( | ||||
|         <> | ||||
|             <ProductivityEmailSubscription | ||||
|                 status='subscribed' | ||||
|                 onChange={() => { | ||||
|                     changed = true; | ||||
|                 }} | ||||
|             /> | ||||
|             <ToastRenderer /> | ||||
|         </>, | ||||
|     ); | ||||
|     const checkbox = screen.getByLabelText('Productivity Email Subscription'); | ||||
|     expect(checkbox).toBeChecked(); | ||||
| 
 | ||||
|     checkbox.click(); | ||||
| 
 | ||||
|     await screen.findByText('Unsubscribed from productivity report'); | ||||
|     expect(changed).toBe(true); | ||||
| }); | ||||
| 
 | ||||
| test('subscribe', async () => { | ||||
|     setupSubscribeApi(); | ||||
|     let changed = false; | ||||
|     render( | ||||
|         <> | ||||
|             <ProductivityEmailSubscription | ||||
|                 status='unsubscribed' | ||||
|                 onChange={() => { | ||||
|                     changed = true; | ||||
|                 }} | ||||
|             /> | ||||
|             <ToastRenderer /> | ||||
|         </>, | ||||
|     ); | ||||
|     const checkbox = screen.getByLabelText('Productivity Email Subscription'); | ||||
|     expect(checkbox).not.toBeChecked(); | ||||
| 
 | ||||
|     checkbox.click(); | ||||
| 
 | ||||
|     await screen.findByText('Subscribed to productivity report'); | ||||
|     expect(changed).toBe(true); | ||||
| }); | ||||
| 
 | ||||
| test('handle error', async () => { | ||||
|     setupErrorApi(); | ||||
|     let changed = false; | ||||
|     render( | ||||
|         <> | ||||
|             <ProductivityEmailSubscription | ||||
|                 status='subscribed' | ||||
|                 onChange={() => { | ||||
|                     changed = true; | ||||
|                 }} | ||||
|             /> | ||||
|             <ToastRenderer /> | ||||
|         </>, | ||||
|     ); | ||||
|     const checkbox = screen.getByLabelText('Productivity Email Subscription'); | ||||
| 
 | ||||
|     checkbox.click(); | ||||
| 
 | ||||
|     await screen.findByText('user error'); | ||||
|     expect(changed).toBe(true); | ||||
| }); | ||||
| @ -1,14 +1,14 @@ | ||||
| import { Box, Switch } from '@mui/material'; | ||||
| import { Box, FormControlLabel, Switch } from '@mui/material'; | ||||
| import { formatUnknownError } from 'utils/formatUnknownError'; | ||||
| import { useState } from 'react'; | ||||
| import type { FC } from 'react'; | ||||
| import { useEmailSubscriptionApi } from 'hooks/api/actions/useEmailSubscriptionApi/useEmailSubscriptionApi'; | ||||
| import useToast from 'hooks/useToast'; | ||||
| import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; | ||||
| 
 | ||||
| export const ProductivityEmailSubscription = () => { | ||||
|     // TODO: read data from user profile when available
 | ||||
|     const [receiveProductivityReportEmail, setReceiveProductivityReportEmail] = | ||||
|         useState(false); | ||||
| export const ProductivityEmailSubscription: FC<{ | ||||
|     status: 'subscribed' | 'unsubscribed'; | ||||
|     onChange: () => void; | ||||
| }> = ({ status, onChange }) => { | ||||
|     const { | ||||
|         subscribe, | ||||
|         unsubscribe, | ||||
| @ -19,44 +19,46 @@ export const ProductivityEmailSubscription = () => { | ||||
| 
 | ||||
|     return ( | ||||
|         <Box> | ||||
|             Productivity Email Subscription | ||||
|             <Switch | ||||
|                 onChange={async () => { | ||||
|                     try { | ||||
|                         if (receiveProductivityReportEmail) { | ||||
|                             await unsubscribe('productivity-report'); | ||||
|                             setToastData({ | ||||
|                                 title: 'Unsubscribed from productivity report', | ||||
|                                 type: 'success', | ||||
|                             }); | ||||
|                             trackEvent('productivity-report', { | ||||
|                                 props: { | ||||
|                                     eventType: 'subscribe', | ||||
|                                 }, | ||||
|                             }); | ||||
|                         } else { | ||||
|                             await subscribe('productivity-report'); | ||||
|                             setToastData({ | ||||
|                                 title: 'Subscribed to productivity report', | ||||
|                                 type: 'success', | ||||
|                             }); | ||||
|                             trackEvent('productivity-report', { | ||||
|                                 props: { | ||||
|                                     eventType: 'unsubscribe', | ||||
|                                 }, | ||||
|                             }); | ||||
|                         } | ||||
|                     } catch (error) { | ||||
|                         setToastApiError(formatUnknownError(error)); | ||||
|                     } | ||||
|             <FormControlLabel | ||||
|                 label='Productivity Email Subscription' | ||||
|                 control={ | ||||
|                     <Switch | ||||
|                         onChange={async () => { | ||||
|                             try { | ||||
|                                 if (status === 'subscribed') { | ||||
|                                     await unsubscribe('productivity-report'); | ||||
|                                     setToastData({ | ||||
|                                         title: 'Unsubscribed from productivity report', | ||||
|                                         type: 'success', | ||||
|                                     }); | ||||
|                                     trackEvent('productivity-report', { | ||||
|                                         props: { | ||||
|                                             eventType: 'subscribe', | ||||
|                                         }, | ||||
|                                     }); | ||||
|                                 } else { | ||||
|                                     await subscribe('productivity-report'); | ||||
|                                     setToastData({ | ||||
|                                         title: 'Subscribed to productivity report', | ||||
|                                         type: 'success', | ||||
|                                     }); | ||||
|                                     trackEvent('productivity-report', { | ||||
|                                         props: { | ||||
|                                             eventType: 'unsubscribe', | ||||
|                                         }, | ||||
|                                     }); | ||||
|                                 } | ||||
|                             } catch (error) { | ||||
|                                 setToastApiError(formatUnknownError(error)); | ||||
|                             } | ||||
| 
 | ||||
|                     setReceiveProductivityReportEmail( | ||||
|                         !receiveProductivityReportEmail, | ||||
|                     ); | ||||
|                 }} | ||||
|                 name='productivity-email' | ||||
|                 checked={receiveProductivityReportEmail} | ||||
|                 disabled={changingSubscriptionStatus} | ||||
|                             onChange(); | ||||
|                         }} | ||||
|                         name='productivity-email' | ||||
|                         checked={status === 'subscribed'} | ||||
|                         disabled={changingSubscriptionStatus} | ||||
|                     /> | ||||
|                 } | ||||
|             /> | ||||
|         </Box> | ||||
|     ); | ||||
|  | ||||
| @ -87,7 +87,7 @@ interface IProfileTabProps { | ||||
| } | ||||
| 
 | ||||
| export const ProfileTab = ({ user }: IProfileTabProps) => { | ||||
|     const { profile } = useProfile(); | ||||
|     const { profile, refetchProfile } = useProfile(); | ||||
|     const navigate = useNavigate(); | ||||
|     const { locationSettings, setLocationSettings } = useLocationSettings(); | ||||
|     const [currentLocale, setCurrentLocale] = useState<string>(); | ||||
| @ -223,7 +223,18 @@ export const ProfileTab = ({ user }: IProfileTabProps) => { | ||||
|                     <> | ||||
|                         <StyledDivider /> | ||||
|                         <StyledSectionLabel>Email Settings</StyledSectionLabel> | ||||
|                         <ProductivityEmailSubscription /> | ||||
|                         {profile?.subscriptions && ( | ||||
|                             <ProductivityEmailSubscription | ||||
|                                 status={ | ||||
|                                     profile.subscriptions.includes( | ||||
|                                         'productivity-report', | ||||
|                                     ) | ||||
|                                         ? 'subscribed' | ||||
|                                         : 'unsubscribed' | ||||
|                                 } | ||||
|                                 onChange={refetchProfile} | ||||
|                             /> | ||||
|                         )} | ||||
|                     </> | ||||
|                 ) : null} | ||||
|             </PageContent> | ||||
|  | ||||
| @ -1,10 +1,10 @@ | ||||
| import useSWR from 'swr'; | ||||
| import { formatApiPath } from 'utils/formatPath'; | ||||
| import handleErrorResponses from '../httpErrorResponseHandler'; | ||||
| import type { IProfile } from 'interfaces/profile'; | ||||
| import type { ProfileSchema } from '../../../../openapi'; | ||||
| 
 | ||||
| export interface IUseProfileOutput { | ||||
|     profile?: IProfile; | ||||
|     profile?: ProfileSchema; | ||||
|     refetchProfile: () => void; | ||||
|     loading: boolean; | ||||
|     error?: Error; | ||||
|  | ||||
| @ -1,6 +0,0 @@ | ||||
| import type { IRole } from './role'; | ||||
| 
 | ||||
| export interface IProfile { | ||||
|     rootRole: IRole; | ||||
|     projects: string[]; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user