mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: feedback skeleton ui (#5727)
This adds component, which will allow to draw feedback component based on incoming data.
This commit is contained in:
parent
1dadd23594
commit
9d8487ad6e
@ -84,7 +84,7 @@ export const FilterDateItem: FC<IFilterDateItemProps> = ({
|
|||||||
const formattedValue = selectedDate
|
const formattedValue = selectedDate
|
||||||
? format(selectedDate, 'yyyy-MM-dd')
|
? format(selectedDate, 'yyyy-MM-dd')
|
||||||
: '';
|
: '';
|
||||||
onChange({ operator, values: [formattedValue] ?? [] });
|
onChange({ operator, values: [formattedValue] });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
90
frontend/src/component/feedbackNew/FeedbackComponent.tsx
Normal file
90
frontend/src/component/feedbackNew/FeedbackComponent.tsx
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { Box, styled } from '@mui/material';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useFeedback } from './useFeedback';
|
||||||
|
|
||||||
|
export const StyledContainer = styled('div')(({ theme }) => ({
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
width: '496px',
|
||||||
|
height: '100vh',
|
||||||
|
opacity: 1,
|
||||||
|
backgroundColor: theme.palette.primary.main,
|
||||||
|
zIndex: theme.zIndex.sticky,
|
||||||
|
|
||||||
|
'&::before': {
|
||||||
|
content: '""',
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
right: '496px',
|
||||||
|
width: '100vw',
|
||||||
|
height: '100vh',
|
||||||
|
backgroundColor: 'rgba(32, 32, 33, 0.40)',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledContent = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
padding: theme.spacing(6),
|
||||||
|
flexDirection: 'column',
|
||||||
|
height: '100vh',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: theme.spacing(8.5),
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledTitle = styled(Box)(({ theme }) => ({
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: theme.spacing(3),
|
||||||
|
fontWeight: 400,
|
||||||
|
lineHeight: theme.spacing(2.5),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledForm = styled(Box)(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
width: '400px',
|
||||||
|
padding: theme.spacing(3),
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: theme.spacing(3),
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: theme.spacing(1.5),
|
||||||
|
borderColor: 'rgba(0, 0, 0, 0.12)',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
boxShadow: '0px 4px 4px 0px rgba(0, 0, 0, 0.12)',
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const FormTitle = styled(Box)(({ theme }) => ({
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
fontSize: theme.spacing(2),
|
||||||
|
lineHeight: theme.spacing(2.75),
|
||||||
|
fontWeight: theme.typography.fontWeightBold,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const FeedbackComponent = () => {
|
||||||
|
const { feedbackData, showFeedback, closeFeedback } = useFeedback();
|
||||||
|
|
||||||
|
if (!feedbackData) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={showFeedback}
|
||||||
|
show={
|
||||||
|
<StyledContainer>
|
||||||
|
<StyledContent>
|
||||||
|
<StyledTitle>Help us to improve Unleash</StyledTitle>
|
||||||
|
<StyledForm>
|
||||||
|
<FormTitle>
|
||||||
|
How easy wasy it to configure the strategy?
|
||||||
|
</FormTitle>
|
||||||
|
</StyledForm>
|
||||||
|
</StyledContent>
|
||||||
|
<button type='button' onClick={closeFeedback}>
|
||||||
|
Close Feedback
|
||||||
|
</button>
|
||||||
|
</StyledContainer>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
34
frontend/src/component/feedbackNew/FeedbackContext.ts
Normal file
34
frontend/src/component/feedbackNew/FeedbackContext.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { createContext } from 'react';
|
||||||
|
import { ProvideFeedbackSchema } from '../../openapi';
|
||||||
|
|
||||||
|
interface IFeedbackContext {
|
||||||
|
feedbackData: ProvideFeedbackSchema;
|
||||||
|
openFeedback: (data: ProvideFeedbackSchema) => void;
|
||||||
|
closeFeedback: () => void;
|
||||||
|
showFeedback: boolean;
|
||||||
|
setShowFeedback: (visible: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_FEEDBACK_DATA = {
|
||||||
|
category: 'general',
|
||||||
|
};
|
||||||
|
|
||||||
|
const setShowFeedback = () => {
|
||||||
|
throw new Error('setShowFeedback called outside FeedbackContext');
|
||||||
|
};
|
||||||
|
|
||||||
|
const openFeedback = () => {
|
||||||
|
throw new Error('openFeedback called outside FeedbackContext');
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeFeedback = () => {
|
||||||
|
throw new Error('closeFeedback called outside FeedbackContext');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FeedbackContext = createContext<IFeedbackContext>({
|
||||||
|
feedbackData: DEFAULT_FEEDBACK_DATA,
|
||||||
|
showFeedback: true,
|
||||||
|
setShowFeedback: setShowFeedback,
|
||||||
|
openFeedback: openFeedback,
|
||||||
|
closeFeedback: closeFeedback,
|
||||||
|
});
|
36
frontend/src/component/feedbackNew/FeedbackProvider.tsx
Normal file
36
frontend/src/component/feedbackNew/FeedbackProvider.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { FeedbackComponent } from './FeedbackComponent';
|
||||||
|
import { DEFAULT_FEEDBACK_DATA, FeedbackContext } from './FeedbackContext';
|
||||||
|
import { FC, useState } from 'react';
|
||||||
|
import { ProvideFeedbackSchema } from '../../openapi';
|
||||||
|
|
||||||
|
export const FeedbackProvider: FC = ({ children }) => {
|
||||||
|
const [feedbackData, setFeedbackData] = useState<ProvideFeedbackSchema>(
|
||||||
|
DEFAULT_FEEDBACK_DATA,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [showFeedback, setShowFeedback] = useState(false);
|
||||||
|
const openFeedback = (data: ProvideFeedbackSchema) => {
|
||||||
|
setFeedbackData(data);
|
||||||
|
setShowFeedback(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeFeedback = () => {
|
||||||
|
setFeedbackData(DEFAULT_FEEDBACK_DATA);
|
||||||
|
setShowFeedback(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FeedbackContext.Provider
|
||||||
|
value={{
|
||||||
|
feedbackData,
|
||||||
|
openFeedback,
|
||||||
|
closeFeedback,
|
||||||
|
showFeedback,
|
||||||
|
setShowFeedback,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<FeedbackComponent />
|
||||||
|
</FeedbackContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
10
frontend/src/component/feedbackNew/useFeedback.tsx
Normal file
10
frontend/src/component/feedbackNew/useFeedback.tsx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { FeedbackContext } from './FeedbackContext';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
|
||||||
|
export const useFeedback = () => {
|
||||||
|
const context = useContext(FeedbackContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error('useFeedback must be used within a FeedbackProvider');
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
@ -16,6 +16,7 @@ import { AnnouncerProvider } from 'component/common/Announcer/AnnouncerProvider/
|
|||||||
import { InstanceStatus } from 'component/common/InstanceStatus/InstanceStatus';
|
import { InstanceStatus } from 'component/common/InstanceStatus/InstanceStatus';
|
||||||
import { UIProviderContainer } from 'component/providers/UIProvider/UIProviderContainer';
|
import { UIProviderContainer } from 'component/providers/UIProvider/UIProviderContainer';
|
||||||
import { StickyProvider } from 'component/common/Sticky/StickyProvider';
|
import { StickyProvider } from 'component/common/Sticky/StickyProvider';
|
||||||
|
import { FeedbackProvider } from './component/feedbackNew/FeedbackProvider';
|
||||||
|
|
||||||
window.global ||= window;
|
window.global ||= window;
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ ReactDOM.render(
|
|||||||
<QueryParamProvider adapter={ReactRouter6Adapter}>
|
<QueryParamProvider adapter={ReactRouter6Adapter}>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<AnnouncerProvider>
|
<AnnouncerProvider>
|
||||||
|
<FeedbackProvider>
|
||||||
<FeedbackCESProvider>
|
<FeedbackCESProvider>
|
||||||
<StickyProvider>
|
<StickyProvider>
|
||||||
<InstanceStatus>
|
<InstanceStatus>
|
||||||
@ -34,6 +36,7 @@ ReactDOM.render(
|
|||||||
</InstanceStatus>
|
</InstanceStatus>
|
||||||
</StickyProvider>
|
</StickyProvider>
|
||||||
</FeedbackCESProvider>
|
</FeedbackCESProvider>
|
||||||
|
</FeedbackProvider>
|
||||||
</AnnouncerProvider>
|
</AnnouncerProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</QueryParamProvider>
|
</QueryParamProvider>
|
||||||
|
Loading…
Reference in New Issue
Block a user