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

timeline component (#2963)

This commit is contained in:
Mateusz Kwasniewski 2023-01-23 13:06:24 +01:00 committed by GitHub
parent bfb038c725
commit bc627b428e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 240 additions and 90 deletions

View File

@ -17,14 +17,41 @@ import useToast from 'hooks/useToast';
import { ImportOptions } from './ImportOptions';
import { ImportExplanation } from './ImportExplanation';
import { PulsingAvatar } from './PulsingAvatar';
import Timeline from '@mui/lab/Timeline';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import TimelineSeparator from '@mui/lab/TimelineSeparator';
import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineContent from '@mui/lab/TimelineContent';
import TimelineDot from '@mui/lab/TimelineDot';
import { ImportTimeline } from './ImportTimeline';
const LayoutContainer = styled('div')(({ theme }) => ({
backgroundColor: '#fff',
const ModalContentContainer = styled('div')(({ theme }) => ({
minHeight: '100vh',
display: 'flex',
}));
const TimelineContainer = styled('div')(({ theme }) => ({
backgroundColor: theme.palette.primary.main,
padding: theme.spacing(6, 8, 3, 4),
flexBasis: '30%',
}));
const TimelineHeader = styled('div')(({ theme }) => ({
textTransform: 'uppercase',
fontSize: theme.fontSizes.smallBody,
color: theme.palette.text.tertiaryContrast,
fontWeight: theme.typography.fontWeightBold,
paddingLeft: theme.spacing(2),
marginBottom: theme.spacing(4),
}));
const ImportLayoutContainer = styled('div')(({ theme }) => ({
backgroundColor: '#fff',
padding: theme.spacing(3, 8, 3, 8),
display: 'flex',
flexDirection: 'column',
gap: theme.spacing(3),
flexBasis: '70%',
}));
const StyledTextField = styled(TextField)(({ theme }) => ({
@ -91,95 +118,101 @@ export const ImportModal = ({ open, setOpen, project }: IImportModalProps) => {
}}
label="Import toggles"
>
<LayoutContainer>
<Box
sx={{
borderBottom: 1,
borderColor: 'divider',
}}
>
<Tabs value={activeTab}>
<Tab
label="Upload file"
value="file"
onClick={() => setActiveTab('file')}
/>
<Tab
label="Code editor"
value="code"
onClick={() => setActiveTab('code')}
/>
</Tabs>
</Box>
<ImportOptions
project={project}
environment={environment}
onChange={setEnvironment}
/>
<ConditionallyRender
condition={activeTab === 'file'}
show={
<StyledFileDropZone
onSuccess={data => {
setImportPayload(data);
setActiveTab('code');
setToastData({
type: 'success',
title: 'File uploaded',
});
}}
onError={error => {
setToastData({
type: 'error',
title: error,
});
}}
onDragStatusChange={setDragActive}
>
<PulsingAvatar active={dragActive}>
<ArrowUpward fontSize="large" />
</PulsingAvatar>
<DropMessage>
{dragActive
? 'Drop your file to upload'
: 'Drop your file here'}
</DropMessage>
<SelectFileMessage>
or select a file from your device
</SelectFileMessage>
<Button variant="outlined">Select file</Button>
<MaxSizeMessage>
JSON format: max 500 kB
</MaxSizeMessage>
</StyledFileDropZone>
}
elseShow={
<StyledTextField
label="Exported toggles"
variant="outlined"
onChange={event =>
setImportPayload(event.target.value)
}
value={importPayload}
multiline
minRows={13}
maxRows={13}
/>
}
/>
<ImportExplanation />
<ActionsContainer>
<Button
sx={{ position: 'static' }}
variant="contained"
color="primary"
type="submit"
onClick={onSubmit}
<ModalContentContainer>
<TimelineContainer>
<TimelineHeader>Process</TimelineHeader>
<ImportTimeline stage={'configure'} />
</TimelineContainer>
<ImportLayoutContainer>
<Box
sx={{
borderBottom: 1,
borderColor: 'divider',
}}
>
Import
</Button>
</ActionsContainer>
</LayoutContainer>
<Tabs value={activeTab}>
<Tab
label="Upload file"
value="file"
onClick={() => setActiveTab('file')}
/>
<Tab
label="Code editor"
value="code"
onClick={() => setActiveTab('code')}
/>
</Tabs>
</Box>
<ImportOptions
project={project}
environment={environment}
onChange={setEnvironment}
/>
<ConditionallyRender
condition={activeTab === 'file'}
show={
<StyledFileDropZone
onSuccess={data => {
setImportPayload(data);
setActiveTab('code');
setToastData({
type: 'success',
title: 'File uploaded',
});
}}
onError={error => {
setToastData({
type: 'error',
title: error,
});
}}
onDragStatusChange={setDragActive}
>
<PulsingAvatar active={dragActive}>
<ArrowUpward fontSize="large" />
</PulsingAvatar>
<DropMessage>
{dragActive
? 'Drop your file to upload'
: 'Drop your file here'}
</DropMessage>
<SelectFileMessage>
or select a file from your device
</SelectFileMessage>
<Button variant="outlined">Select file</Button>
<MaxSizeMessage>
JSON format: max 500 kB
</MaxSizeMessage>
</StyledFileDropZone>
}
elseShow={
<StyledTextField
label="Exported toggles"
variant="outlined"
onChange={event =>
setImportPayload(event.target.value)
}
value={importPayload}
multiline
minRows={13}
maxRows={13}
/>
}
/>
<ImportExplanation />
<ActionsContainer>
<Button
sx={{ position: 'static' }}
variant="contained"
color="primary"
type="submit"
onClick={onSubmit}
>
Import
</Button>
</ActionsContainer>
</ImportLayoutContainer>
</ModalContentContainer>
</SidebarModal>
);
};

View File

@ -0,0 +1,117 @@
import TimelineSeparator from '@mui/lab/TimelineSeparator';
import TimelineItem, { timelineItemClasses } from '@mui/lab/TimelineItem';
import React, { FC } from 'react';
import { Box, styled } from '@mui/material';
import TimelineConnector from '@mui/lab/TimelineConnector';
import TimelineDot from '@mui/lab/TimelineDot';
import TimelineContent from '@mui/lab/TimelineContent';
import Timeline from '@mui/lab/Timeline';
const StyledTimeline = styled(Timeline)(() => ({
[`& .${timelineItemClasses.root}:before`]: {
flex: 0,
padding: 0,
},
}));
const StyledTimelineConnector = styled(TimelineConnector)(({ theme }) => ({
width: '1px',
backgroundColor: theme.palette.neutral.border,
}));
const StyledTimelineDot = styled(TimelineDot, {
shouldForwardProp: prop => prop !== 'active',
})<{ active: boolean }>(({ theme, active }) => ({
color: active ? theme.palette.primary.main : theme.palette.neutral.border,
backgroundColor: active ? theme.palette.text.tertiaryContrast : 'initial',
fontWeight: active ? theme.fontWeight.bold : theme.fontWeight.medium,
borderColor: theme.palette.neutral.border,
width: '40px',
height: '40px',
borderWidth: '1px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}));
const StyledTimelineContent = styled(TimelineContent, {
shouldForwardProp: prop => prop !== 'active',
})<{ active: boolean }>(({ theme, active }) => ({
marginBottom: theme.spacing(6),
color: active
? theme.palette.text.tertiaryContrast
: theme.palette.neutral.border,
marginTop: theme.spacing(2),
}));
const TimelineItemTitle = styled(Box)(({ theme }) => ({
fontWeight: theme.fontWeight.bold,
fontSize: theme.fontSizes.bodySize,
}));
const TimelineItemDescription = styled(Box)(({ theme }) => ({
fontSize: theme.fontSizes.smallerBody,
}));
export const ImportTimeline: FC<{
stage: 'configure' | 'validate' | 'import';
}> = ({ stage }) => {
return (
<StyledTimeline>
<TimelineItem>
<TimelineSeparator>
<StyledTimelineDot
variant="outlined"
active={stage === 'configure'}
>
1
</StyledTimelineDot>
<StyledTimelineConnector />
</TimelineSeparator>
<StyledTimelineContent active={stage === 'configure'}>
<TimelineItemTitle>Import file</TimelineItemTitle>
<TimelineItemDescription>
Import previously exported toggle configuration from
another Unleash instance as a JSON file
</TimelineItemDescription>
</StyledTimelineContent>
</TimelineItem>
<TimelineItem>
<TimelineSeparator>
<StyledTimelineDot
variant="outlined"
active={stage === 'validate'}
>
2
</StyledTimelineDot>
<StyledTimelineConnector />
</TimelineSeparator>
<StyledTimelineContent active={stage === 'validate'}>
<TimelineItemTitle>
Validate configuration
</TimelineItemTitle>
<TimelineItemDescription>
Check the errors and warnings from the import process
</TimelineItemDescription>
</StyledTimelineContent>
</TimelineItem>
<TimelineItem>
<TimelineSeparator>
<StyledTimelineDot
variant="outlined"
active={stage === 'import'}
>
3
</StyledTimelineDot>
</TimelineSeparator>
<StyledTimelineContent active={stage === 'import'}>
<TimelineItemTitle>Finish import</TimelineItemTitle>
<TimelineItemDescription>
Feature toggle configuration will be imported to your
new Unleash instance
</TimelineItemDescription>
</StyledTimelineContent>
</TimelineItem>
</StyledTimeline>
);
};