Timeline component
parent
853cc9c9ad
commit
99b4929b2a
|
@ -64,7 +64,8 @@
|
|||
"About": {
|
||||
"Navigation": {
|
||||
"System": "System",
|
||||
"ReleaseNotes": "Release notes"
|
||||
"ReleaseNotes": "Release notes",
|
||||
"Timeline": "Timeline"
|
||||
},
|
||||
"ReleaseNotes": {
|
||||
"Version": "Version",
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
"About": {
|
||||
"Navigation": {
|
||||
"System": "Sistem",
|
||||
"ReleaseNotes": "Note de lansare"
|
||||
"ReleaseNotes": "Note de lansare",
|
||||
"Timeline": "Cronologie"
|
||||
},
|
||||
"ReleaseNotes": {
|
||||
"Version": "Versiune",
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useState, useMemo } from "react";
|
|||
import PageTitle from "../../components/common/PageTitle";
|
||||
import BubbleChartIcon from "@material-ui/icons/BubbleChart";
|
||||
import NotesIcon from "@material-ui/icons/Notes";
|
||||
import TimelineIcon from "@material-ui/icons/Timeline";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AboutSystemContainer from "./system/AboutSystemContainer";
|
||||
import ReleaseNotesContainer from "./releaseNotes/ReleaseNotesContainer";
|
||||
|
@ -9,7 +10,8 @@ import NavigationButtons from "../../components/common/NavigationButtons";
|
|||
|
||||
const NavigationTabs = {
|
||||
SYSTEM: "About.Navigation.System",
|
||||
RELEASE_NOTES: "About.Navigation.ReleaseNotes"
|
||||
RELEASE_NOTES: "About.Navigation.ReleaseNotes",
|
||||
TIMELINE: "About.Navigation.Timeline"
|
||||
};
|
||||
|
||||
const tabs = [
|
||||
|
@ -20,6 +22,10 @@ const tabs = [
|
|||
{
|
||||
code: NavigationTabs.RELEASE_NOTES,
|
||||
icon: NotesIcon
|
||||
},
|
||||
{
|
||||
code: NavigationTabs.TIMELINE,
|
||||
icon: TimelineIcon
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -42,6 +48,9 @@ const AboutContainer = () => {
|
|||
/>
|
||||
{tab === NavigationTabs.SYSTEM && <AboutSystemContainer />}
|
||||
{tab === NavigationTabs.RELEASE_NOTES && <ReleaseNotesContainer />}
|
||||
{tab === NavigationTabs.TIMELINE && (
|
||||
<ReleaseNotesContainer view="timeline" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import useApi from "../../../api";
|
||||
import ReleaseNotesList from "./ReleaseNotesList";
|
||||
import TimelineComponent from "../timeline/TimelineComponent";
|
||||
|
||||
const ReleaseNotesContainer = () => {
|
||||
const sort = releases =>
|
||||
releases.sort((a, b) => new Date(b.date) - new Date(a.date));
|
||||
|
||||
const ReleaseNotesContainer = ({ view }) => {
|
||||
const [state, setState] = useState({ data: [], loaded: false });
|
||||
|
||||
const api = useApi();
|
||||
|
@ -16,7 +21,20 @@ const ReleaseNotesContainer = () => {
|
|||
});
|
||||
}, [api, state.loaded]);
|
||||
|
||||
return <>{state.loaded && <ReleaseNotesList releaseNotes={state.data} />}</>;
|
||||
return (
|
||||
<>
|
||||
{state.loaded &&
|
||||
(view === "timeline" ? (
|
||||
<TimelineComponent releases={sort(state.data)} />
|
||||
) : (
|
||||
<ReleaseNotesList releases={sort(state.data)} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
ReleaseNotesContainer.propTypes = {
|
||||
view: PropTypes.string
|
||||
};
|
||||
|
||||
export default ReleaseNotesContainer;
|
||||
|
|
|
@ -9,7 +9,7 @@ import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
|
|||
import ReleaseNoteSummary from "./ReleaseNoteSummary";
|
||||
import ReleaseNote from "./ReleaseNote";
|
||||
|
||||
const ReleaseNotesList = ({ releaseNotes }) => {
|
||||
const ReleaseNotesList = ({ releases }) => {
|
||||
const [flags, setFlags] = useState({});
|
||||
|
||||
const handleToggle = key => (_, expanded) => {
|
||||
|
@ -25,22 +25,30 @@ const ReleaseNotesList = ({ releaseNotes }) => {
|
|||
return collapsed;
|
||||
};
|
||||
|
||||
console.log(
|
||||
"sortedReleases",
|
||||
JSON.stringify(releases.map(z => ({ version: z.version, date: z.date })))
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{releaseNotes.map(note => {
|
||||
{releases.map(release => {
|
||||
return (
|
||||
<Accordion key={note.version} onChange={handleToggle(note.version)}>
|
||||
<Accordion
|
||||
key={release.version}
|
||||
onChange={handleToggle(release.version)}
|
||||
>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
id={`panel-${note.version}-header`}
|
||||
id={`panel-${release.version}-header`}
|
||||
>
|
||||
<ReleaseNoteSummary
|
||||
releaseNote={note}
|
||||
collapsed={isCollapsed(note.version)}
|
||||
releaseNote={release}
|
||||
collapsed={isCollapsed(release.version)}
|
||||
/>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<ReleaseNote releaseNote={note} />
|
||||
<ReleaseNote releaseNote={release} />
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
|
@ -50,7 +58,7 @@ const ReleaseNotesList = ({ releaseNotes }) => {
|
|||
};
|
||||
|
||||
ReleaseNotesList.propTypes = {
|
||||
releaseNotes: PropTypes.array.isRequired
|
||||
releases: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
export default ReleaseNotesList;
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Timeline from "@material-ui/lab/Timeline";
|
||||
import TimelineItem from "@material-ui/lab/TimelineItem";
|
||||
import TimelineSeparator from "@material-ui/lab/TimelineSeparator";
|
||||
import TimelineConnector from "@material-ui/lab/TimelineConnector";
|
||||
import TimelineContent from "@material-ui/lab/TimelineContent";
|
||||
import TimelineOppositeContent from "@material-ui/lab/TimelineOppositeContent";
|
||||
import TimelineDot from "@material-ui/lab/TimelineDot";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { getRandomElement } from "../../../utils";
|
||||
import {
|
||||
Announcement,
|
||||
AmpStories,
|
||||
Apps,
|
||||
BugReport,
|
||||
DeviceHub,
|
||||
Equalizer,
|
||||
FilterTiltShift,
|
||||
Grain,
|
||||
Layers,
|
||||
LocalOffer,
|
||||
Memory,
|
||||
NetworkCheck,
|
||||
OfflineBolt,
|
||||
Star,
|
||||
Whatshot,
|
||||
Widgets
|
||||
} from "@material-ui/icons";
|
||||
|
||||
const timelineIcons = [
|
||||
Announcement,
|
||||
AmpStories,
|
||||
Apps,
|
||||
BugReport,
|
||||
DeviceHub,
|
||||
Equalizer,
|
||||
FilterTiltShift,
|
||||
Grain,
|
||||
Layers,
|
||||
LocalOffer,
|
||||
Memory,
|
||||
NetworkCheck,
|
||||
OfflineBolt,
|
||||
Star,
|
||||
Whatshot,
|
||||
Widgets
|
||||
];
|
||||
|
||||
const timelineDotVariants = [
|
||||
{ color: "primary", variant: "outlined" },
|
||||
{ color: "secondary", variant: "outlined" }
|
||||
];
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
paper: {
|
||||
padding: "6px 16px"
|
||||
}
|
||||
}));
|
||||
|
||||
const TimelineComponent = ({ releases }) => {
|
||||
const classes = useStyles();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const _releases = releases.map((release, index) => {
|
||||
const isLast = index === releases.length - 1;
|
||||
const icon = getRandomElement(timelineIcons);
|
||||
const dot = getRandomElement(timelineDotVariants);
|
||||
return { ...release, isLast, icon, dot };
|
||||
});
|
||||
|
||||
return (
|
||||
<Timeline align="alternate">
|
||||
{_releases.map(release => (
|
||||
<TimelineItem key={release.version}>
|
||||
<TimelineOppositeContent>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
{t("DATE_FORMAT", {
|
||||
date: { value: release.date, format: "DD-MM-YYYY HH:mm" }
|
||||
})}
|
||||
</Typography>
|
||||
</TimelineOppositeContent>
|
||||
<TimelineSeparator>
|
||||
<TimelineDot
|
||||
color={release.dot.color}
|
||||
variant={release.dot.variant}
|
||||
>
|
||||
<release.icon />
|
||||
</TimelineDot>
|
||||
{!release.isLast && <TimelineConnector />}
|
||||
</TimelineSeparator>
|
||||
<TimelineContent>
|
||||
<Paper elevation={3} className={classes.paper}>
|
||||
<Typography variant="h6" component="h1">
|
||||
{release.notes[0]}
|
||||
</Typography>
|
||||
{release.notes.slice(1).map((note, index) => (
|
||||
<Typography key={index} variant="body2">
|
||||
{note}
|
||||
</Typography>
|
||||
))}
|
||||
</Paper>
|
||||
</TimelineContent>
|
||||
</TimelineItem>
|
||||
))}
|
||||
</Timeline>
|
||||
);
|
||||
};
|
||||
|
||||
TimelineComponent.propTypes = {
|
||||
releases: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
export default TimelineComponent;
|
|
@ -1,5 +1,5 @@
|
|||
const primary = "#00695C";
|
||||
const secondary = "#FF5C93";
|
||||
const secondary = "#F9A825";
|
||||
const warning = "#ff9800";
|
||||
const success = "#4caf50";
|
||||
const info = "#2196f3";
|
||||
|
@ -10,8 +10,8 @@ const defaultTheme = {
|
|||
main: primary
|
||||
},
|
||||
secondary: {
|
||||
main: secondary,
|
||||
contrastText: "#ffcc00"
|
||||
main: secondary
|
||||
// contrastText: "#ffcc00"
|
||||
},
|
||||
warning: {
|
||||
main: warning
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import { getRandomElement } from "./random";
|
||||
|
||||
export { getRandomElement };
|
|
@ -0,0 +1,7 @@
|
|||
const getRandomElement = array => {
|
||||
const randomIndex = Math.floor(Math.random() * array.length);
|
||||
const element = array[randomIndex];
|
||||
return element;
|
||||
};
|
||||
|
||||
export { getRandomElement };
|
Loading…
Reference in New Issue