1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-03 01:18:43 +02:00

Merge pull request #638 from Unleash/fix/pnps

fix: pnps
This commit is contained in:
Youssef Khedher 2022-01-28 12:20:56 +01:00 committed by GitHub
commit d69c024bbe
12 changed files with 85 additions and 62 deletions

View File

@ -103,4 +103,21 @@ export const useCommonStyles = makeStyles(theme => ({
opacity: '0', opacity: '0',
transition: 'transform 1.25s ease, opacity 1s ease', transition: 'transform 1.25s ease, opacity 1s ease',
}, },
fadeInTopStart: {
opacity: '0',
position: 'fixed',
right: '40px',
top: '40px',
transform: 'translateY(-400px)',
},
fadeInTopEnter: {
transform: 'translateY(100px)',
opacity: '1',
transition: 'transform 0.6s ease, opacity 1s ease',
},
fadeInTopLeave: {
transform: 'translateY(-400px)',
opacity: '0',
transition: 'transform 1.25s ease, opacity 1s ease',
},
})); }));

View File

@ -12,7 +12,7 @@ import styles from './styles.module.scss';
import IAuthStatus from '../interfaces/user'; import IAuthStatus from '../interfaces/user';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import NotFound from './common/NotFound/NotFound'; import NotFound from './common/NotFound/NotFound';
import Feedback from './common/Feedback'; import Feedback from './common/Feedback/Feedback';
import SWRProvider from './providers/SWRProvider/SWRProvider'; import SWRProvider from './providers/SWRProvider/SWRProvider';
import ConditionallyRender from './common/ConditionallyRender'; import ConditionallyRender from './common/ConditionallyRender';
import EnvironmentSplash from './common/EnvironmentSplash/EnvironmentSplash'; import EnvironmentSplash from './common/EnvironmentSplash/EnvironmentSplash';
@ -109,6 +109,8 @@ const App = ({ location, user, fetchUiBootstrap }: IAppProps) => {
show={<Loader />} show={<Loader />}
elseShow={ elseShow={
<div className={styles.container}> <div className={styles.container}>
<ToastRenderer />
<ConditionallyRender <ConditionallyRender
condition={showSplash} condition={showSplash}
show={ show={
@ -139,8 +141,6 @@ const App = ({ location, user, fetchUiBootstrap }: IAppProps) => {
</LayoutPicker> </LayoutPicker>
} }
/> />
<ToastRenderer />
</div> </div>
} }
/> />

View File

@ -2,7 +2,7 @@ import { makeStyles } from '@material-ui/core/styles';
export const useStyles = makeStyles(theme => ({ export const useStyles = makeStyles(theme => ({
feedback: { feedback: {
borderRadius: '3px', borderRadius: '12.5px',
backgroundColor: '#fff', backgroundColor: '#fff',
zIndex: '9999', zIndex: '9999',
boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)', boxShadow: '2px 2px 4px 4px rgba(143,143,143, 0.25)',
@ -12,7 +12,7 @@ export const useStyles = makeStyles(theme => ({
height: '200px', height: '200px',
}, },
animateContainer: { animateContainer: {
zIndex: '9999', zIndex: 9999,
}, },
container: { container: {
display: 'flex', display: 'flex',

View File

@ -1,4 +1,4 @@
import { useState } from 'react'; import { useContext, useState } from 'react';
import { Button, IconButton } from '@material-ui/core'; import { Button, IconButton } from '@material-ui/core';
import classnames from 'classnames'; import classnames from 'classnames';
import CloseIcon from '@material-ui/icons/Close'; import CloseIcon from '@material-ui/icons/Close';
@ -10,6 +10,8 @@ import AnimateOnMount from '../AnimateOnMount/AnimateOnMount';
import ConditionallyRender from '../ConditionallyRender'; import ConditionallyRender from '../ConditionallyRender';
import { formatApiPath } from '../../../utils/format-path'; import { formatApiPath } from '../../../utils/format-path';
import { Action, Dispatch } from 'redux'; import { Action, Dispatch } from 'redux';
import UIContext from '../../../contexts/UIContext';
import useUser from '../../../hooks/api/getters/useUser/useUser';
interface IFeedbackProps { interface IFeedbackProps {
show?: boolean; show?: boolean;
@ -19,13 +21,9 @@ interface IFeedbackProps {
openUrl: string; openUrl: string;
} }
const Feedback = ({ const Feedback = ({ feedbackId, openUrl }: IFeedbackProps) => {
show, const { showFeedback, setShowFeedback } = useContext(UIContext);
hideFeedback, const { refetch, feedback } = useUser();
fetchUser,
feedbackId,
openUrl,
}: IFeedbackProps) => {
const [answeredNotNow, setAnsweredNotNow] = useState(false); const [answeredNotNow, setAnsweredNotNow] = useState(false);
const styles = useStyles(); const styles = useStyles();
const commonStyles = useCommonStyles(); const commonStyles = useCommonStyles();
@ -42,15 +40,15 @@ const Feedback = ({
}, },
body: JSON.stringify({ feedbackId }), body: JSON.stringify({ feedbackId }),
}); });
await fetchUser(); await refetch();
} catch { } catch {
hideFeedback(); setShowFeedback(false);
} }
// Await api call to register confirmation // Await api call to register confirmation
window.open(openUrl, '_blank'); window.open(openUrl, '_blank');
setTimeout(() => { setTimeout(() => {
hideFeedback(); setShowFeedback(false);
}, 200); }, 200);
}; };
@ -69,22 +67,28 @@ const Feedback = ({
}, },
body: JSON.stringify({ feedbackId, neverShow: true }), body: JSON.stringify({ feedbackId, neverShow: true }),
}); });
await fetchUser(); await refetch();
} catch { } catch {
hideFeedback(); setShowFeedback(false);
} }
setTimeout(() => { setTimeout(() => {
hideFeedback(); setShowFeedback(false);
}, 100); }, 100);
}; };
console.log(feedback);
const pnps = feedback.find(feedback => feedback.feedbackId === feedbackId);
if (pnps?.given || pnps?.neverShow) {
return null;
}
return ( return (
<AnimateOnMount <AnimateOnMount
mounted={show} mounted={showFeedback}
start={commonStyles.fadeInBottomStart} start={commonStyles.fadeInTopStart}
enter={commonStyles.fadeInBottomEnter} enter={commonStyles.fadeInTopEnter}
leave={commonStyles.fadeInBottomLeave} leave={commonStyles.fadeInTopLeave}
container={styles.animateContainer} container={styles.animateContainer}
> >
<div className={styles.feedback}> <div className={styles.feedback}>
@ -96,7 +100,7 @@ const Feedback = ({
> >
<IconButton <IconButton
className={styles.close} className={styles.close}
onClick={() => hideFeedback()} onClick={() => setShowFeedback(false)}
> >
<CloseIcon /> <CloseIcon />
</IconButton> </IconButton>

View File

@ -1,19 +0,0 @@
import { Dispatch } from 'react';
import { connect } from 'react-redux';
import { Action } from 'redux';
import { hideFeedback } from '../../../store/feedback/actions';
import { fetchUser } from '../../../store/user/actions';
import Feedback from './Feedback';
const mapStateToProps = (state: any) => ({
show: state.feedback.show,
});
const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
hideFeedback: () => {
hideFeedback(dispatch)();
},
fetchUser: () => fetchUser()(dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(Feedback);

View File

@ -0,0 +1,10 @@
import { makeStyles } from '@material-ui/core/styles';
export const useStyles = makeStyles(theme => ({
toastWrapper: {
right: 0,
left: 0,
margin: '0 auto',
maxWidth: '450px',
},
}));

View File

@ -2,13 +2,15 @@ import { Portal } from '@material-ui/core';
import { useContext, useEffect } from 'react'; import { useContext, useEffect } from 'react';
import { useCommonStyles } from '../../../common.styles'; import { useCommonStyles } from '../../../common.styles';
import UIContext, { IToastData } from '../../../contexts/UIContext'; import UIContext, { IToastData } from '../../../contexts/UIContext';
import { useStyles } from './ToastRenderer.styles';
import AnimateOnMount from '../AnimateOnMount/AnimateOnMount'; import AnimateOnMount from '../AnimateOnMount/AnimateOnMount';
import Toast from './Toast/Toast'; import Toast from './Toast/Toast';
const ToastRenderer = () => { const ToastRenderer = () => {
// @ts-ignore-next-line // @ts-ignore-next-line
const { toastData, setToast } = useContext(UIContext); const { toastData, setToast } = useContext(UIContext);
const styles = useCommonStyles(); const commonStyles = useCommonStyles();
const styles = useStyles();
const hide = () => { const hide = () => {
setToast((prev: IToastData) => ({ ...prev, show: false })); setToast((prev: IToastData) => ({ ...prev, show: false }));
@ -30,10 +32,10 @@ const ToastRenderer = () => {
<Portal> <Portal>
<AnimateOnMount <AnimateOnMount
mounted={toastData?.show} mounted={toastData?.show}
start={styles.fadeInBottomStartWithoutFixed} start={commonStyles.fadeInBottomStartWithoutFixed}
enter={styles.fadeInBottomEnter} enter={commonStyles.fadeInBottomEnter}
leave={styles.fadeInBottomLeave} leave={commonStyles.fadeInBottomLeave}
container={styles.fullWidth} container={styles.toastWrapper}
> >
<Toast {...toastData} /> <Toast {...toastData} />
</AnimateOnMount> </AnimateOnMount>

View File

@ -8,10 +8,13 @@ import useFeatureApi from '../../../../hooks/api/actions/useFeatureApi/useFeatur
import { CREATE_FEATURE } from '../../../providers/AccessProvider/permissions'; import { CREATE_FEATURE } from '../../../providers/AccessProvider/permissions';
import PermissionButton from '../../../common/PermissionButton/PermissionButton'; import PermissionButton from '../../../common/PermissionButton/PermissionButton';
import { CF_CREATE_BTN_ID } from '../../../../testIds'; import { CF_CREATE_BTN_ID } from '../../../../testIds';
import { useContext } from 'react';
import UIContext from '../../../../contexts/UIContext';
const CreateFeature = () => { const CreateFeature = () => {
/* @ts-ignore */ /* @ts-ignore */
const { setToastData, setToastApiError } = useToast(); const { setToastData, setToastApiError } = useToast();
const { setShowFeedback } = useContext(UIContext);
const { uiConfig } = useUiConfig(); const { uiConfig } = useUiConfig();
const history = useHistory(); const history = useHistory();
@ -46,6 +49,7 @@ const CreateFeature = () => {
confetti: true, confetti: true,
type: 'success', type: 'success',
}); });
setShowFeedback(true);
} catch (e: any) { } catch (e: any) {
setToastApiError(e.toString()); setToastApiError(e.toString());
} }

View File

@ -496,10 +496,10 @@ exports[`renders correctly with with variants 1`] = `
</svg> </svg>
<fieldset <fieldset
aria-hidden={true} aria-hidden={true}
className="PrivateNotchedOutline-root-23 MuiOutlinedInput-notchedOutline" className="PrivateNotchedOutline-root-26 MuiOutlinedInput-notchedOutline"
> >
<legend <legend
className="PrivateNotchedOutline-legendLabelled-25 PrivateNotchedOutline-legendNotched-26" className="PrivateNotchedOutline-legendLabelled-28 PrivateNotchedOutline-legendNotched-29"
> >
<span> <span>
Stickiness Stickiness

View File

@ -29,7 +29,7 @@ exports[`renders correctly with one feature 1`] = `
} }
> >
<div <div
className="MuiChip-root makeStyles-chip-21 MuiChip-colorPrimary MuiChip-outlined MuiChip-outlinedPrimary" className="MuiChip-root makeStyles-chip-24 MuiChip-colorPrimary MuiChip-outlined MuiChip-outlinedPrimary"
onKeyDown={[Function]} onKeyDown={[Function]}
onKeyUp={[Function]} onKeyUp={[Function]}
title="Feature toggle is active." title="Feature toggle is active."
@ -104,10 +104,10 @@ exports[`renders correctly with one feature 1`] = `
</svg> </svg>
<fieldset <fieldset
aria-hidden={true} aria-hidden={true}
className="PrivateNotchedOutline-root-22 MuiOutlinedInput-notchedOutline" className="PrivateNotchedOutline-root-25 MuiOutlinedInput-notchedOutline"
> >
<legend <legend
className="PrivateNotchedOutline-legendLabelled-24 PrivateNotchedOutline-legendNotched-25" className="PrivateNotchedOutline-legendLabelled-27 PrivateNotchedOutline-legendNotched-28"
> >
<span> <span>
Feature type Feature type
@ -163,10 +163,10 @@ exports[`renders correctly with one feature 1`] = `
</svg> </svg>
<fieldset <fieldset
aria-hidden={true} aria-hidden={true}
className="PrivateNotchedOutline-root-22 MuiOutlinedInput-notchedOutline" className="PrivateNotchedOutline-root-25 MuiOutlinedInput-notchedOutline"
> >
<legend <legend
className="PrivateNotchedOutline-legendLabelled-24 PrivateNotchedOutline-legendNotched-25" className="PrivateNotchedOutline-legendLabelled-27 PrivateNotchedOutline-legendNotched-28"
> >
<span> <span>
Project Project
@ -198,7 +198,7 @@ exports[`renders correctly with one feature 1`] = `
> >
<span <span
aria-disabled={true} aria-disabled={true}
className="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-26 MuiSwitch-switchBase MuiSwitch-colorSecondary PrivateSwitchBase-disabled-28 Mui-disabled Mui-disabled Mui-disabled" className="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-29 MuiSwitch-switchBase MuiSwitch-colorSecondary PrivateSwitchBase-disabled-31 Mui-disabled Mui-disabled Mui-disabled"
onBlur={[Function]} onBlur={[Function]}
onDragLeave={[Function]} onDragLeave={[Function]}
onFocus={[Function]} onFocus={[Function]}
@ -217,7 +217,7 @@ exports[`renders correctly with one feature 1`] = `
> >
<input <input
checked={false} checked={false}
className="PrivateSwitchBase-input-29 MuiSwitch-input" className="PrivateSwitchBase-input-32 MuiSwitch-input"
disabled={true} disabled={true}
onChange={[Function]} onChange={[Function]}
type="checkbox" type="checkbox"
@ -350,7 +350,7 @@ exports[`renders correctly with one feature 1`] = `
</div> </div>
<hr /> <hr />
<div <div
className="MuiPaper-root makeStyles-tabNav-30 MuiPaper-elevation1 MuiPaper-rounded" className="MuiPaper-root makeStyles-tabNav-33 MuiPaper-elevation1 MuiPaper-rounded"
> >
<div <div
className="MuiTabs-root" className="MuiTabs-root"
@ -398,7 +398,7 @@ exports[`renders correctly with one feature 1`] = `
Activation Activation
</span> </span>
<span <span
className="PrivateTabIndicator-root-31 PrivateTabIndicator-colorPrimary-32 MuiTabs-indicator" className="PrivateTabIndicator-root-34 PrivateTabIndicator-colorPrimary-35 MuiTabs-indicator"
style={Object {}} style={Object {}}
/> />
</button> </button>

View File

@ -11,13 +11,16 @@ const UIProvider: React.FC = ({ children }) => {
persist: false, persist: false,
type: '', type: '',
}); });
const [showFeedback, setShowFeedback] = useState();
const context = React.useMemo( const context = React.useMemo(
() => ({ () => ({
setToast, setToast,
toastData, toastData,
showFeedback,
setShowFeedback,
}), }),
[toastData] [toastData, showFeedback]
); );
return <UIContext.Provider value={context}>{children}</UIContext.Provider>; return <UIContext.Provider value={context}>{children}</UIContext.Provider>;

View File

@ -9,11 +9,13 @@ export interface IToastData {
confetti?: boolean; confetti?: boolean;
type: string; type: string;
} }
interface IFeatureStrategiesUIContext { interface IUIContext {
toastData: IToastData; toastData: IToastData;
setToast: React.Dispatch<React.SetStateAction<IToastData>>; setToast: React.Dispatch<React.SetStateAction<IToastData>>;
showFeedback: boolean;
setShowFeedback: React.Dispatch<React.SetStateAction<boolean>>;
} }
const UIContext = React.createContext<IFeatureStrategiesUIContext | null>(null); const UIContext = React.createContext<IUIContext | null>(null);
export default UIContext; export default UIContext;