Skip to content

Commit 901b82b

Browse files
Merge pull request #4394 from OneCommunityGlobal/chirag-pr-team-analytics-dashboard-data-view-toggle-addition
Chirag - PR Team Analytics dashboard data view toggle addition
2 parents a185074 + 482b449 commit 901b82b

4 files changed

Lines changed: 256 additions & 191 deletions

File tree

src/components/PRAnalyticsDashboard/ReviewsInsight/ActionDoneGraph.jsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { Bar } from 'react-chartjs-2';
22
import styles from './ReviewsInsight.module.css';
33
import { useSelector } from 'react-redux';
4+
import { Chart } from 'chart.js';
5+
import ChartDataLabels from 'chartjs-plugin-datalabels';
46

57
function ActionDoneGraph({ selectedTeams, teamData }) {
68
const darkMode = useSelector(state => state.theme.darkMode);
79

810
if (!selectedTeams || selectedTeams.length === 0) {
9-
return <div> </div>;
11+
return <div></div>;
1012
}
1113

1214
if (!teamData || Object.keys(teamData).length === 0) {
13-
return <div className={styles['no-data-ri']}>No data available for Action Done Graph.</div>;
15+
return <div className={styles.noData}>No data available for Action Graph.</div>;
1416
}
1517

1618
const isAllTeams = selectedTeams.some(team => team.value === 'All');
@@ -54,6 +56,14 @@ function ActionDoneGraph({ selectedTeams, teamData }) {
5456
tooltip: {
5557
enabled: true,
5658
},
59+
datalabels: {
60+
color: darkMode ? '#fff' : '#000',
61+
font: { weight: 'bold', size: 11 },
62+
formatter: value => {
63+
if (!value) return 0;
64+
return value;
65+
},
66+
},
5767
},
5868
scales: {
5969
x: {
@@ -81,9 +91,11 @@ function ActionDoneGraph({ selectedTeams, teamData }) {
8191
};
8292

8393
return (
84-
<div className={styles['ri-action-done-graph']}>
85-
<h2>PR: Action Done</h2>
86-
<div className={styles['ri-graph']}>
94+
<div className={styles.riActionDoneGraph}>
95+
<h2 className={`${styles.heading} ${darkMode ? styles.darkModeForeground : ''}`}>
96+
PR: Action Done
97+
</h2>
98+
<div className={`${styles.riGraph} ${darkMode ? styles.riGraphDarkMode : ''}`}>
8799
<Bar data={data} options={options} />
88100
</div>
89101
</div>

src/components/PRAnalyticsDashboard/ReviewsInsight/PRQualityGraph.jsx

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import { Pie } from 'react-chartjs-2';
22
import styles from './ReviewsInsight.module.css';
33
import { useSelector } from 'react-redux';
4+
import { Chart } from 'chart.js';
5+
import ChartDataLabels from 'chartjs-plugin-datalabels';
46

5-
function PRQualityGraph({ selectedTeams, qualityData }) {
7+
Chart.register(ChartDataLabels);
8+
9+
function PRQualityGraph({ selectedTeams, qualityData, isDataViewActive }) {
610
const darkMode = useSelector(state => state.theme.darkMode);
711

812
if (!selectedTeams || selectedTeams.length === 0) {
913
return <div> </div>;
1014
}
1115

1216
if (!qualityData || Object.keys(qualityData).length === 0) {
13-
return <div className={styles['no-data-ri']}>No data available for Quality Graph.</div>;
17+
return <div className={styles.noData}>No data available for Quality Graph.</div>;
1418
}
1519

1620
const isAllTeams = selectedTeams.some(team => team.value === 'All');
@@ -20,17 +24,23 @@ function PRQualityGraph({ selectedTeams, qualityData }) {
2024

2125
const generateChartData = team => {
2226
const teamQualityData = qualityData[team] || {};
27+
28+
const counts = [
29+
teamQualityData.NotApproved || 0,
30+
teamQualityData.LowQuality || 0,
31+
teamQualityData.Sufficient || 0,
32+
teamQualityData.Exceptional || 0,
33+
];
34+
35+
const total = counts.reduce((sum, v) => sum + v, 0);
36+
const values = isDataViewActive ? counts.map(v => (total ? (v / total) * 100 : 0)) : counts;
37+
2338
return {
2439
labels: ['Not Approved', 'Low Quality', 'Sufficient', 'Exceptional'],
2540
datasets: [
2641
{
2742
label: `PR Quality Distribution for ${team}`,
28-
data: [
29-
teamQualityData.NotApproved || 0,
30-
teamQualityData.LowQuality || 0,
31-
teamQualityData.Sufficient || 0,
32-
teamQualityData.Exceptional || 0,
33-
],
43+
data: values,
3444
backgroundColor: ['#DC3545', '#FFC107', '#28A745', '#5940CB'],
3545
hoverOffset: 4,
3646
},
@@ -47,38 +57,39 @@ function PRQualityGraph({ selectedTeams, qualityData }) {
4757
legend: {
4858
position: 'bottom',
4959
labels: {
50-
font: {
51-
size: 12,
52-
},
53-
color: !darkMode ? '#333' : '#fff',
60+
font: { size: 12 },
61+
color: darkMode ? '#fff' : '#333',
5462
},
5563
},
5664
tooltip: {
5765
enabled: true,
5866
callbacks: {
59-
title: () => '',
60-
label: tooltipItem => {
61-
const label = tooltipItem.label || '';
62-
const value = tooltipItem.raw || 0;
63-
return `${label}: ${value}`;
64-
},
67+
label: ctx => (isDataViewActive ? `${ctx.raw.toFixed(1)}%` : ctx.raw),
68+
},
69+
},
70+
datalabels: {
71+
color: darkMode ? '#fff' : '#000',
72+
font: { weight: 'bold', size: 11 },
73+
formatter: value => {
74+
if (!value) return '';
75+
return isDataViewActive ? `${value}%` : value;
6576
},
6677
},
6778
},
6879
};
6980

7081
return (
71-
<div className={styles['ri-quality-graph']}>
72-
<h2>PR Quality Distribution</h2>
73-
<div className={styles['ri-charts']}>
82+
<div className={styles.riQualityGraph}>
83+
<h2 className={`${styles.heading} ${darkMode ? styles.darkModeForeground : ''}`}>
84+
PR Quality Distribution
85+
</h2>
86+
87+
<div className={`${styles.riCharts}`}>
7488
{teamsToDisplay.map(team => (
75-
<div key={team} className={styles['ri-chart']}>
76-
<div className={styles['ri-chart-header']}>
77-
<h3>{team}</h3>
78-
<span className={styles['ri-team-member-count']}>
79-
{qualityData[team]?.memberCount ?? 0}
80-
</span>
81-
</div>
89+
<div key={team} className={`${styles.riChart} ${darkMode ? styles.riChartDarkMode : ''}`}>
90+
<h3 className={`${styles.heading} ${darkMode ? styles.darkModeForeground : ''}`}>
91+
{team}
92+
</h3>
8293
<Pie data={generateChartData(team)} options={options} />
8394
</div>
8495
))}

src/components/PRAnalyticsDashboard/ReviewsInsight/ReviewsInsight.jsx

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import { getAllTeamCode } from '../../../actions/allTeamsAction';
99

1010
function ReviewsInsight() {
1111
const [duration, setDuration] = useState('Last Week');
12-
const [selectedTeams, setSelectedTeams] = useState([]);
12+
const [selectedTeams, setSelectedTeams] = useState([{ value: 'All', label: 'All Teams' }]);
1313
const [teamData, setTeamData] = useState({});
1414
const [qualityData, setQualityData] = useState({});
15+
const [dataViewActive, setDataViewActive] = useState(false);
1516
const dispatch = useDispatch();
1617

1718
const { loading, data, error } = useSelector(state => state.reviewsInsights);
@@ -95,23 +96,42 @@ function ReviewsInsight() {
9596

9697
return (
9798
<div
98-
className={`${styles['reviews-insight-container']} ${darkMode ? styles['dark-mode'] : ''}`}
99+
className={`${styles.reviewsInsightContainer} ${darkMode ? styles.darkModeForeground : ''} ${
100+
darkMode ? styles.darkModeBackground : ''
101+
}`}
99102
>
100-
<h1>PR Reviews Insights</h1>
103+
<h1 className={darkMode ? styles.darkModeForeground : styles.heading}>PR Reviews Insights</h1>
101104

102-
<div className={styles['ri-filters']}>
103-
<div className={styles['ri-filter-item']}>
104-
<label htmlFor="ri-duration-filter">Duration:</label>
105-
<select id="ri-duration-filter" value={duration} onChange={handleDurationChange}>
105+
<div className={`${styles.riFilters} ${darkMode ? styles.darkModeForeground : ''}`}>
106+
<div className={`${styles.riFilterItem} ${darkMode ? styles.darkModeForeground : ''}`}>
107+
<label
108+
htmlFor="ri-duration-filter"
109+
className={`${styles.riFilterItemLabel} ${darkMode ? styles.darkModeForeground : ''}`}
110+
>
111+
Duration:
112+
</label>
113+
<select
114+
id="ri-duration-filter"
115+
value={duration}
116+
onChange={handleDurationChange}
117+
className={`${styles.riDurationFilter} ${
118+
darkMode ? styles.riDurationFilterDarkMode : ''
119+
}`}
120+
>
106121
<option value="Last Week">Last Week</option>
107122
<option value="Last 2 weeks">Last 2 weeks</option>
108123
<option value="Last Month">Last Month</option>
109124
<option value="All Time">All Time</option>
110125
</select>
111126
</div>
112127

113-
<div className={styles['ri-filter-item']}>
114-
<label htmlFor="team-filter">Team Code:</label>
128+
<div className={`${styles.riFilterItem} ${darkMode ? styles.darkModeForeground : ''}`}>
129+
<label
130+
htmlFor="team-filter"
131+
className={`${styles.riFilterItemLabel} ${darkMode ? styles.darkModeForeground : ''}`}
132+
>
133+
Team Code:
134+
</label>
115135
<Select
116136
id="team-filter"
117137
isMulti
@@ -176,24 +196,58 @@ function ReviewsInsight() {
176196
}}
177197
/>
178198
</div>
199+
200+
<div className={`${styles.riFilterItem} ${darkMode ? styles.darkModeForeground : ''}`}>
201+
<span className={styles.riDataviewTitle}>Data View</span>
202+
<div className={styles.riToggleWrap}>
203+
<label className={styles.riSwitch}>
204+
<input
205+
type="checkbox"
206+
checked={dataViewActive}
207+
onChange={() => setDataViewActive(v => !v)}
208+
aria-label="Toggle data view: Percent vs Number"
209+
className={styles.riSwitchInput}
210+
/>
211+
<span className={`${styles.riSlider} ${darkMode ? styles.riSliderDarkMode : ''}`} />
212+
</label>
213+
214+
<span className={`${styles.modeLabel} ${darkMode ? styles.darkModeForeground : ''}`}>
215+
{dataViewActive ? 'PERCENT' : 'NUMBER'}
216+
</span>
217+
</div>
218+
</div>
179219
</div>
180220

181-
<div className={styles['ri-selected-teams']}>
221+
<div>
182222
{selectedTeams.length === 0 ? (
183-
<p>No teams selected</p>
223+
<p className={`${styles.riSelectedTeams} ${darkMode ? styles.darkModeForeground : ''}`}>
224+
No teams selected
225+
</p>
184226
) : selectedTeams.some(team => team.value === 'All') ? (
185-
<p>Selected Teams: All Teams</p>
227+
<p className={`${styles.riSelectedTeams} ${darkMode ? styles.darkModeForeground : ''}`}>
228+
Selected Teams: All Teams
229+
</p>
186230
) : (
187-
<p>Selected Teams: {selectedTeams.map(team => team.label).join(', ')}</p>
231+
<p className={`${styles.riSelectedTeams} ${darkMode ? styles.darkModeForeground : ''}`}>
232+
Selected Teams: {selectedTeams.map(team => team.label).join(', ')}
233+
</p>
188234
)}
189235
</div>
190236

191-
{loading && <div className={styles['ri-loading']}>Loading...</div>}
192-
{error && <div className={styles['ri-error']}>{error}</div>}
237+
{loading && (
238+
<div className={`${styles.riLoading} ${darkMode ? styles.darkModeForeground : ''}`}>
239+
Loading...
240+
</div>
241+
)}
242+
{error && <div className={`${styles.riError}`}>{error}</div>}
193243
{!loading && !error && (
194-
<div className={styles['ri-graphs']}>
244+
<div className={`${styles.riGraphs} ${darkMode ? styles.darkModeForeground : ''}`}>
195245
<ActionDoneGraph selectedTeams={selectedTeams} teamData={teamData} />
196-
<PRQualityGraph selectedTeams={selectedTeams} qualityData={qualityData} />
246+
<PRQualityGraph
247+
selectedTeams={selectedTeams}
248+
qualityData={qualityData}
249+
isDataViewActive={dataViewActive}
250+
/>
197251
</div>
198252
)}
199253
</div>

0 commit comments

Comments
 (0)