Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
project2-it2810
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Mikkel Marstein
project2-it2810
Commits
dcc20acf
Verified
Commit
dcc20acf
authored
3 years ago
by
Ulrik Røsby
Browse files
Options
Downloads
Patches
Plain Diff
feat: Make selected chart params persist within sessions.
parent
add84dfd
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/helpers/hooks.ts
+3
-10
3 additions, 10 deletions
src/helpers/hooks.ts
src/pages/FeatsVsFixesPage/index.tsx
+17
-9
17 additions, 9 deletions
src/pages/FeatsVsFixesPage/index.tsx
src/pages/TimePerIssueLabelPage/index.tsx
+18
-12
18 additions, 12 deletions
src/pages/TimePerIssueLabelPage/index.tsx
with
38 additions
and
31 deletions
src/helpers/hooks.ts
+
3
−
10
View file @
dcc20acf
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
);
}
This diff is collapsed.
Click to expand it.
src/pages/FeatsVsFixesPage/index.tsx
+
17
−
9
View file @
dcc20acf
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
{
use
Effect
,
useState
}
from
'
react
'
;
import
{
use
SessionStorage
}
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
>
...
...
This diff is collapsed.
Click to expand it.
src/pages/TimePerIssueLabelPage/index.tsx
+
18
−
12
View file @
dcc20acf
...
...
@@ -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
=
{
difficultyLabels
String
}
value
=
{
difficultyLabels
String
}
>
<
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
=
{
otherLabels
String
}
value
=
{
otherLabels
String
}
>
<
div
>
Other
</
div
>
</
MenuItem
>
</
Select
>
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment