diff --git a/frontend/src/component/project/Project/Import/ImportModal.tsx b/frontend/src/component/project/Project/Import/ImportModal.tsx
index 615a9bc8f9..63cfd50612 100644
--- a/frontend/src/component/project/Project/Import/ImportModal.tsx
+++ b/frontend/src/component/project/Project/Import/ImportModal.tsx
@@ -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"
>
-
-
-
- setActiveTab('file')}
- />
- setActiveTab('code')}
- />
-
-
-
- {
- setImportPayload(data);
- setActiveTab('code');
- setToastData({
- type: 'success',
- title: 'File uploaded',
- });
- }}
- onError={error => {
- setToastData({
- type: 'error',
- title: error,
- });
- }}
- onDragStatusChange={setDragActive}
- >
-
-
-
-
- {dragActive
- ? 'Drop your file to upload'
- : 'Drop your file here'}
-
-
- or select a file from your device
-
-
-
- JSON format: max 500 kB
-
-
- }
- elseShow={
-
- setImportPayload(event.target.value)
- }
- value={importPayload}
- multiline
- minRows={13}
- maxRows={13}
- />
- }
- />
-
-
-
-
-
+
+ setActiveTab('file')}
+ />
+ setActiveTab('code')}
+ />
+
+
+
+ {
+ setImportPayload(data);
+ setActiveTab('code');
+ setToastData({
+ type: 'success',
+ title: 'File uploaded',
+ });
+ }}
+ onError={error => {
+ setToastData({
+ type: 'error',
+ title: error,
+ });
+ }}
+ onDragStatusChange={setDragActive}
+ >
+
+
+
+
+ {dragActive
+ ? 'Drop your file to upload'
+ : 'Drop your file here'}
+
+
+ or select a file from your device
+
+
+
+ JSON format: max 500 kB
+
+
+ }
+ elseShow={
+
+ setImportPayload(event.target.value)
+ }
+ value={importPayload}
+ multiline
+ minRows={13}
+ maxRows={13}
+ />
+ }
+ />
+
+
+
+
+
+
);
};
diff --git a/frontend/src/component/project/Project/Import/ImportTimeline.tsx b/frontend/src/component/project/Project/Import/ImportTimeline.tsx
new file mode 100644
index 0000000000..ca95a7907a
--- /dev/null
+++ b/frontend/src/component/project/Project/Import/ImportTimeline.tsx
@@ -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 (
+
+
+
+
+ 1
+
+
+
+
+ Import file
+
+ Import previously exported toggle configuration from
+ another Unleash instance as a JSON file
+
+
+
+
+
+
+ 2
+
+
+
+
+
+ Validate configuration
+
+
+ Check the errors and warnings from the import process
+
+
+
+
+
+
+ 3
+
+
+
+ Finish import
+
+ Feature toggle configuration will be imported to your
+ new Unleash instance
+
+
+
+
+ );
+};