Marking progress on roadmap
This commit is contained in:
@ -70,12 +70,12 @@ const H6 = styled(H1).attrs({ as: 'h6' })`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Headings = {
|
const Headings = {
|
||||||
h1: linkify(H1),
|
h1: H1,
|
||||||
h2: linkify(H2),
|
h2: H2,
|
||||||
h3: linkify(H3),
|
h3: H3,
|
||||||
h4: linkify(H4),
|
h4: H4,
|
||||||
h5: linkify(H5),
|
h5: H5,
|
||||||
h6: linkify(H6)
|
h6: H6
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Headings;
|
export default Headings;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { Box, CloseButton } from '@chakra-ui/react';
|
import { Box, Button, Flex, Text } from '@chakra-ui/react';
|
||||||
import { RemoveScroll } from 'react-remove-scroll';
|
import { RemoveScroll } from 'react-remove-scroll';
|
||||||
import { RoadmapType } from '../../lib/roadmap';
|
import { RoadmapType } from '../../lib/roadmap';
|
||||||
import RoadmapGroup from '../../pages/[roadmap]/[group]';
|
import RoadmapGroup from '../../pages/[roadmap]/[group]';
|
||||||
|
import { CheckIcon, CloseIcon, RepeatIcon } from '@chakra-ui/icons';
|
||||||
|
|
||||||
type ContentDrawerProps = {
|
type ContentDrawerProps = {
|
||||||
roadmap: RoadmapType;
|
roadmap: RoadmapType;
|
||||||
@ -15,6 +16,8 @@ export function ContentDrawer(props: ContentDrawerProps) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDone = localStorage.getItem(groupId) === 'done';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box zIndex={99999} pos="relative">
|
<Box zIndex={99999} pos="relative">
|
||||||
<Box
|
<Box
|
||||||
@ -39,13 +42,63 @@ export function ContentDrawer(props: ContentDrawerProps) {
|
|||||||
borderLeftWidth={'1px'}
|
borderLeftWidth={'1px'}
|
||||||
overflowY="scroll"
|
overflowY="scroll"
|
||||||
>
|
>
|
||||||
<CloseButton
|
<Flex
|
||||||
onClick={onClose}
|
mt="20px"
|
||||||
pos="absolute"
|
justifyContent="space-between"
|
||||||
top={'20px'}
|
alignItems="center"
|
||||||
right={'20px'}
|
|
||||||
zIndex={1}
|
zIndex={1}
|
||||||
/>
|
>
|
||||||
|
{!isDone && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.setItem(groupId, 'done');
|
||||||
|
document
|
||||||
|
.querySelector(`[data-group-id*="-${groupId}"]`)
|
||||||
|
?.classList?.add('done');
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
colorScheme="green"
|
||||||
|
leftIcon={<CheckIcon />}
|
||||||
|
size="xs"
|
||||||
|
iconSpacing={0}
|
||||||
|
>
|
||||||
|
<Text as="span" d={['block', 'none', 'none', 'block']} ml="10px">
|
||||||
|
Mark as Done
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{isDone && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
localStorage.removeItem(groupId);
|
||||||
|
document
|
||||||
|
.querySelector(`[data-group-id*="-${groupId}"]`)
|
||||||
|
?.classList?.remove('done');
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
colorScheme="purple"
|
||||||
|
leftIcon={<RepeatIcon />}
|
||||||
|
size="xs"
|
||||||
|
iconSpacing={0}
|
||||||
|
>
|
||||||
|
<Text as="span" d={['block', 'none', 'none', 'block']} ml="10px">
|
||||||
|
Mark as Pending
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
onClick={onClose}
|
||||||
|
colorScheme="yellow"
|
||||||
|
ml="5px"
|
||||||
|
leftIcon={<CloseIcon width="8px" />}
|
||||||
|
iconSpacing={0}
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<Text as="span" d={['none', 'none', 'none', 'block']} ml="10px">
|
||||||
|
Close
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
<RoadmapGroup isOutlet roadmap={roadmap} group={groupId} />
|
<RoadmapGroup isOutlet roadmap={roadmap} group={groupId} />
|
||||||
</Box>
|
</Box>
|
||||||
</RemoveScroll>
|
</RemoveScroll>
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import { getRGBFromDecimalColor, makeSVGElement } from './utils';
|
import {
|
||||||
|
getRGBFromDecimalColor,
|
||||||
|
makeSVGElement,
|
||||||
|
removeSortingInfo,
|
||||||
|
} from './utils';
|
||||||
import {
|
import {
|
||||||
ARROW_WIDTH,
|
ARROW_WIDTH,
|
||||||
BORDER_WIDTH,
|
BORDER_WIDTH,
|
||||||
@ -257,12 +261,17 @@ export class Renderer {
|
|||||||
|
|
||||||
__group__(control: any, container: any) {
|
__group__(control: any, container: any) {
|
||||||
const controlName = control?.properties?.controlName;
|
const controlName = control?.properties?.controlName;
|
||||||
|
const groupId = removeSortingInfo(controlName);
|
||||||
|
const isDone = localStorage.getItem(groupId) === 'done';
|
||||||
|
|
||||||
let group = makeSVGElement(
|
let group = makeSVGElement(
|
||||||
'g',
|
'g',
|
||||||
{
|
{
|
||||||
...(controlName
|
...(controlName
|
||||||
? { class: 'clickable-group', 'data-group-id': controlName }
|
? {
|
||||||
|
class: `clickable-group ${isDone ? 'done' : ''}`,
|
||||||
|
'data-group-id': controlName,
|
||||||
|
}
|
||||||
: {}),
|
: {}),
|
||||||
},
|
},
|
||||||
container
|
container
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
export function removeSortingInfo(groupId: string) {
|
||||||
|
return (groupId || '').replace(/^\d+-/, '');
|
||||||
|
}
|
||||||
|
|
||||||
export function getRGBFromDecimalColor(color: number) {
|
export function getRGBFromDecimalColor(color: number) {
|
||||||
let red = (color >> 16) & 0xff;
|
let red = (color >> 16) & 0xff;
|
||||||
let green = (color >> 8) & 0xff;
|
let green = (color >> 8) & 0xff;
|
||||||
|
@ -12,6 +12,7 @@ import { RoadmapPageHeader } from '../../components/roadmap/roadmap-page-header'
|
|||||||
import { ContentDrawer } from '../../components/roadmap/content-drawer';
|
import { ContentDrawer } from '../../components/roadmap/content-drawer';
|
||||||
import { RoadmapError } from '../../components/roadmap/roadmap-error';
|
import { RoadmapError } from '../../components/roadmap/roadmap-error';
|
||||||
import { RoadmapLoader } from '../../components/roadmap/roadmap-loader';
|
import { RoadmapLoader } from '../../components/roadmap/roadmap-loader';
|
||||||
|
import { removeSortingInfo } from '../../lib/renderer/utils';
|
||||||
|
|
||||||
type RoadmapProps = {
|
type RoadmapProps = {
|
||||||
roadmap: RoadmapType;
|
roadmap: RoadmapType;
|
||||||
@ -19,10 +20,6 @@ type RoadmapProps = {
|
|||||||
|
|
||||||
export function InteractiveRoadmapRenderer(props: RoadmapProps) {
|
export function InteractiveRoadmapRenderer(props: RoadmapProps) {
|
||||||
const { roadmap } = props;
|
const { roadmap } = props;
|
||||||
if (!roadmap.jsonUrl) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { loading: isLoading, error: hasErrorLoading, get } = useFetch();
|
const { loading: isLoading, error: hasErrorLoading, get } = useFetch();
|
||||||
|
|
||||||
const roadmapRef = useRef(null);
|
const roadmapRef = useRef(null);
|
||||||
@ -33,6 +30,10 @@ export function InteractiveRoadmapRenderer(props: RoadmapProps) {
|
|||||||
const [hasErrorRendering, setHasErrorRendering] = useState(false);
|
const [hasErrorRendering, setHasErrorRendering] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!roadmap.jsonUrl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
get(roadmap.jsonUrl)
|
get(roadmap.jsonUrl)
|
||||||
.then((roadmapJson) => {
|
.then((roadmapJson) => {
|
||||||
setRoadmapJson(roadmapJson);
|
setRoadmapJson(roadmapJson);
|
||||||
@ -65,7 +66,7 @@ export function InteractiveRoadmapRenderer(props: RoadmapProps) {
|
|||||||
|
|
||||||
// e.g. 100-internet:how-does-the-internet-work
|
// e.g. 100-internet:how-does-the-internet-work
|
||||||
// will be translated to `internet:how-does-the-internet-work`
|
// will be translated to `internet:how-does-the-internet-work`
|
||||||
setGroupId(groupId.replace(/^\d+-/, ''));
|
setGroupId(removeSortingInfo(groupId));
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('keydown', keydownListener);
|
window.addEventListener('keydown', keydownListener);
|
||||||
@ -104,8 +105,12 @@ export function InteractiveRoadmapRenderer(props: RoadmapProps) {
|
|||||||
});
|
});
|
||||||
}, [roadmapJson]);
|
}, [roadmapJson]);
|
||||||
|
|
||||||
|
if (!roadmap.jsonUrl) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasErrorLoading || hasErrorRendering) {
|
if (hasErrorLoading || hasErrorRendering) {
|
||||||
return <RoadmapError roadmap={roadmap} />
|
return <RoadmapError roadmap={roadmap} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -43,6 +43,11 @@ const GlobalStyles = css`
|
|||||||
&:hover > [fill="rgb(153,153,153)"] { fill: #646464; }
|
&:hover > [fill="rgb(153,153,153)"] { fill: #646464; }
|
||||||
&:hover > [fill="rgb(255,255,255)"] { fill: #d7d7d7; }
|
&:hover > [fill="rgb(255,255,255)"] { fill: #d7d7d7; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg .done {
|
||||||
|
& rect { fill: #cbcbcb; }
|
||||||
|
& text { text-decoration: line-through; }
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user