Skip to content
Snippets Groups Projects
Verified Commit dcc20acf authored by Ulrik Røsby's avatar Ulrik Røsby
Browse files

feat: Make selected chart params persist within sessions.

parent add84dfd
Branches
No related tags found
No related merge requests found
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react';
type StorageObject = typeof window.localStorage | typeof window.sessionStorage;
type PossibleValues = string | number | boolean;
// useStorage, useLocalStorage and useSessionStorage is taken from:
// https://github.com/WebDevSimplified/useful-custom-react-hooks/blob/main/src/8-useStorage/useStorage.js
/**
......@@ -11,7 +10,7 @@ type PossibleValues = string | number | boolean;
* @param storageObject Either localStorage or sessionStorage
* @returns An array of [value, setValue, remove]
*/
function useStorage<ValueType extends PossibleValues>(
function useStorage<ValueType>(
key: string,
defaultValue: ValueType,
storageObject: StorageObject,
......@@ -40,10 +39,7 @@ function useStorage<ValueType extends PossibleValues>(
* @param defaultValue The default value of the item in localStorage.
* @returns An array of [value, setValue, remove]
*/
export function useLocalStorage<ValueType extends PossibleValues>(
key: string,
defaultValue: ValueType,
) {
export function useLocalStorage<ValueType>(key: string, defaultValue: ValueType) {
return useStorage(key, defaultValue, window.localStorage);
}
......@@ -53,9 +49,6 @@ export function useLocalStorage<ValueType extends PossibleValues>(
* @param defaultValue The default value of the item in sessionStorage.
* @returns An array of [value, setValue, remove]
*/
export function useSessionStorage<ValueType extends PossibleValues>(
key: string,
defaultValue: ValueType,
) {
export function useSessionStorage<ValueType>(key: string, defaultValue: ValueType) {
return useStorage(key, defaultValue, window.sessionStorage);
}
import PageContainer from '../../components/PageContainer/index';
import { Checkbox } from '@material-ui/core';
import { useEffect, useState } from 'react';
import ChartPie from '../../components/ChartPie';
import PageContainer from '../../components/PageContainer/index';
import { getAllCommitsFromAPI } from '../../helpers/api-calls';
import { useEffect, useState } from 'react';
import { useSessionStorage } from '../../helpers/hooks';
import { CommitAuthor } from '../../helpers/types';
import { Checkbox } from '@material-ui/core';
import { parseCommitData } from './utils';
export default function FeatsVsFixesPage() {
// The retrieved athor data form the api.
const [authorData, setAuthorData] = useState<CommitAuthor[]>([]);
// The selected showing authors (default all selected), settings are saved in sessions.
const [selectedAuthors, setSelectedAuthors] = useSessionStorage<boolean[]>(
'selectedAuthorsFeatsVsFixes',
new Array(authorData.length).fill(true),
);
const featsFixesGraphData: Array<{ commitType: string; val: number }> = [
{ commitType: 'feat', val: 0 },
......@@ -20,7 +27,7 @@ export default function FeatsVsFixesPage() {
];
for (let i = 0; i < authorData.length; i++) {
if (authorData[i].active) {
if (selectedAuthors?.[i]) {
featsFixesGraphData[0].val += authorData[i].feats;
featsFixesGraphData[1].val += authorData[i].fixes;
additionsDeletionsGraphData[0].val += authorData[i].additions;
......@@ -44,14 +51,15 @@ export default function FeatsVsFixesPage() {
{authorData.map((m, i) => {
if (m.feats || m.fixes) {
return (
<div key={i}>
<div key={JSON.stringify(m)}>
Person {i + 1}
<Checkbox
checked={m.active}
checked={selectedAuthors?.[i]}
onChange={() => {
const temp_list = [...authorData];
temp_list[i].active = !temp_list[i].active;
setAuthorData(temp_list);
if (!selectedAuthors) return; // selectedAuthors will never be undefined
const tempList = [...selectedAuthors];
tempList[i] = !tempList[i];
setSelectedAuthors(tempList);
}}
/>
</div>
......
......@@ -3,25 +3,30 @@ import { useEffect, useState } from 'react';
import ChartBar from '../../components/ChartBar/index';
import PageContainer from '../../components/PageContainer';
import { getIssuesFromAPI } from '../../helpers/api-calls';
import {
difficultyLabels,
Label,
otherLabels,
techDescriptionLabels,
} from '../../helpers/constants';
import { difficultyLabels, otherLabels, techDescriptionLabels } from '../../helpers/constants';
import { useSessionStorage } from '../../helpers/hooks';
import { BarDataItem, Issue } from '../../helpers/types';
import useStyles from './styles';
import { avgTimePerIssueLabel } from './utils';
const difficultyLabelsString = JSON.stringify(difficultyLabels);
const techLabelsString = JSON.stringify(techDescriptionLabels);
const otherLabelsString = JSON.stringify(otherLabels);
export default function TimePerIssueLabelPage() {
const [allIssueData, setAllIssueData] = useState<Issue[] | null>(null);
const [data, setData] = useState<BarDataItem[] | null>(null);
const [selected, setSelected] = useState<Label[]>(difficultyLabels);
// The selected issueLabel groups are saved in each session.
const [selected, setSelected] = useSessionStorage<string>(
'issueLabelsSelected',
difficultyLabelsString,
);
const classes = useStyles();
// On page load, get the issues from the API and load it into a state.
useEffect(() => {
getIssuesFromAPI().then((res) => {
// Since console.error makes sense here.
// eslint-disable-next-line
if (!res.ok) return console.error(res.status, res.data);
setAllIssueData(res.data);
......@@ -35,7 +40,8 @@ export default function TimePerIssueLabelPage() {
if (selected == null) return;
// Find the average time used to close an issue with one of the selected labels
const dataForRelevantIssues = avgTimePerIssueLabel(allIssueData, selected);
const selectedArray = JSON.parse(selected);
const dataForRelevantIssues = avgTimePerIssueLabel(allIssueData, selectedArray);
setData(dataForRelevantIssues);
}, [selected, allIssueData]);
......@@ -53,17 +59,17 @@ export default function TimePerIssueLabelPage() {
id="demo-simple-select"
value={selected}
onChange={(e) => {
const newValue = e.target.value as Label[];
const newValue = e.target.value as string;
setSelected(newValue);
}}
>
<MenuItem key={JSON.stringify(difficultyLabels)} value={difficultyLabels}>
<MenuItem key={difficultyLabelsString} value={difficultyLabelsString}>
<div>Difficulty</div>
</MenuItem>
<MenuItem key={JSON.stringify(techDescriptionLabels)} value={techDescriptionLabels}>
<MenuItem key={techLabelsString} value={techLabelsString}>
<div>Tech Description</div>
</MenuItem>
<MenuItem key={JSON.stringify(otherLabels)} value={otherLabels}>
<MenuItem key={otherLabelsString} value={otherLabelsString}>
<div>Other</div>
</MenuItem>
</Select>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment