Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement demo guide steps logic (#3528)
https://linear.app/unleash/issue/2-915/implement-guide-steps-logic https://user-images.githubusercontent.com/14320932/232099388-a8138b29-8256-4ed2-b8f4-f7607cf3ab9c.mp4 See discussion for context: https://unleash-internal.slack.com/archives/C046LV85N3C/p1681723816687779?thread_ts=1681488537.345059&cid=C046LV85N3C Relates to [roadmap](https://github.com/orgs/Unleash/projects/10) item: #3537
- Loading branch information
Showing
7 changed files
with
773 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
import { Typography } from '@mui/material'; | ||
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; | ||
import { Badge } from 'component/common/Badge/Badge'; | ||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||
import { useEffect, useState } from 'react'; | ||
import { Step } from 'react-joyride'; | ||
import { DemoTopics } from './DemoTopics/DemoTopics'; | ||
import { DemoSteps } from './DemoSteps/DemoSteps'; | ||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; | ||
import { createLocalStorage } from 'utils/createLocalStorage'; | ||
|
||
export interface ITutorialTopic { | ||
title: string; | ||
steps: Step[]; | ||
} | ||
|
||
const defaultProgress = { | ||
expanded: true, | ||
run: false, | ||
topic: 0, | ||
steps: [0], | ||
}; | ||
|
||
const { value: storedProgress, setValue: setStoredProgress } = | ||
createLocalStorage('Tutorial:v1', defaultProgress); | ||
|
||
const TOPICS: ITutorialTopic[] = [ | ||
{ | ||
title: 'Import', | ||
steps: [ | ||
{ | ||
target: 'button[data-testid="IMPORT_BUTTON"]', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Import toggle configuration | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
This is a cool feature that enables you to import | ||
your toggle configuration. This is just an example | ||
and not part of the final guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'New feature toggle', | ||
steps: [ | ||
{ | ||
target: 'button[data-testid="NAVIGATE_TO_CREATE_FEATURE"]', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Add a new feature toggle | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
You can use this button to add a new feature toggle. | ||
This is just an example and not part of the final | ||
guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'Enable/disable a feature toggle', | ||
steps: [ | ||
{ | ||
target: '.MuiSwitch-sizeMedium', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Enable/disable a feature toggle | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
The simplest way to use a feature toggle is to | ||
enable or disable it for everyone (on/off). | ||
</Typography> | ||
<Badge | ||
sx={{ marginTop: 2 }} | ||
icon={<InfoOutlinedIcon />} | ||
> | ||
Look at the demo page when toggling! | ||
</Badge> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: 'Community', | ||
steps: [ | ||
{ | ||
target: 'a[href="https://twitter.com/getunleash"]', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Follow us on Twitter! | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
Following us on Twitter is one of the easiest ways | ||
of keeping up with us. This is just an example and | ||
not part of the final guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
{ | ||
target: 'a[href="https://www.linkedin.com/company/getunleash"]', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Follow us on LinkedIn! | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
You can also follow us LinkedIn. This is just an | ||
example and not part of the final guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
{ | ||
target: 'a[href="https://github.com/Unleash/unleash"]', | ||
title: ( | ||
<Typography fontWeight="bold"> | ||
Check out Unleash on GitHub! | ||
</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
Unleash is open-source, check out the project on | ||
GitHub. This is just an example and not part of the | ||
final guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
{ | ||
target: 'a[href="https://slack.unleash.run"]', | ||
title: ( | ||
<Typography fontWeight="bold">Join us on Slack!</Typography> | ||
), | ||
content: ( | ||
<> | ||
<Typography variant="body2" color="text.secondary"> | ||
Join our community in Slack. This is just an example | ||
and not part of the final guide. | ||
</Typography> | ||
</> | ||
), | ||
disableBeacon: true, | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
export const Demo = () => { | ||
const { uiConfig } = useUiConfig(); | ||
const [loaded, setLoaded] = useState(false); | ||
const [expanded, setExpanded] = useState(storedProgress.expanded ?? true); | ||
const [run, setRun] = useState(storedProgress.run ?? false); | ||
const [topic, setTopic] = useState(storedProgress.topic ?? 0); | ||
const [steps, setSteps] = useState(storedProgress.steps ?? [0]); | ||
|
||
useEffect(() => { | ||
setTimeout(() => { | ||
setLoaded(true); | ||
}, 1000); | ||
}, []); | ||
|
||
useEffect(() => { | ||
setStoredProgress({ | ||
expanded, | ||
run, | ||
topic, | ||
steps, | ||
}); | ||
}, [expanded, run, topic, steps]); | ||
|
||
if (!uiConfig.flags.demo) return null; | ||
|
||
return ( | ||
<> | ||
<DemoTopics | ||
expanded={expanded} | ||
setExpanded={setExpanded} | ||
steps={steps} | ||
currentTopic={topic} | ||
setCurrentTopic={(topic: number) => { | ||
setTopic(topic); | ||
setSteps(steps => { | ||
const newSteps = [...steps]; | ||
newSteps[topic] = 0; | ||
return newSteps; | ||
}); | ||
}} | ||
topics={TOPICS} | ||
/> | ||
<ConditionallyRender | ||
condition={loaded} | ||
show={ | ||
<DemoSteps | ||
run={run} | ||
setRun={setRun} | ||
setExpanded={setExpanded} | ||
steps={steps} | ||
setSteps={setSteps} | ||
topic={topic} | ||
setTopic={setTopic} | ||
topics={TOPICS} | ||
/> | ||
} | ||
/> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.