Skip to content

Commit 7e3f8ca

Browse files
authored
Upgrade AG Grid to v34 and rewrite leaderboard routing (source-academy#3319)
* Upgrade ag-grid to latest * Fix removed deprecated option * Create AG Grid bootstrapper * Move Sentry bootstrap to separate file * Register various modules needed for AG Grid * Migrate tables to new theming API * Remove hardcoded global AG Grid styling * Restore leaderboard styles with scoped CSS * Fix leaderboard not loading * Fix deprecation * Simplify leaderboard routing logic * Commit utils file * Remove useless items * Simplify leaderboard dropdown code * Remove unused styles * Fix overflow and memoization bugs * Move constant out of component * Use camelCase for variable * Remove useless comment * Fix table bugs * Fix redirect not working * Migrate changes * Fix bugs * Fix more bugs
1 parent 0e3fab4 commit 7e3f8ca

28 files changed

+394
-555
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
"@tremor/react": "^1.8.2",
4949
"ace-builds": "^1.42.1",
5050
"acorn": "^8.9.0",
51-
"ag-grid-community": "^32.3.1",
52-
"ag-grid-react": "^32.3.1",
51+
"ag-grid-community": "^34.1.1",
52+
"ag-grid-react": "^34.1.1",
5353
"array-move": "^4.0.0",
5454
"browserfs": "^1.4.3",
5555
"classnames": "^2.3.2",

src/bootstrap/agGrid.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {
2+
CellStyleModule,
3+
ClientSideRowModelModule,
4+
ColumnApiModule,
5+
ColumnAutoSizeModule,
6+
CsvExportModule,
7+
DateFilterModule,
8+
InfiniteRowModelModule,
9+
type Module,
10+
ModuleRegistry,
11+
PaginationModule,
12+
RowDragModule,
13+
TextEditorModule,
14+
TextFilterModule,
15+
ValidationModule
16+
} from 'ag-grid-community';
17+
18+
const productionModules: readonly Module[] = [
19+
CellStyleModule,
20+
ClientSideRowModelModule,
21+
ColumnApiModule,
22+
ColumnAutoSizeModule,
23+
CsvExportModule,
24+
DateFilterModule,
25+
InfiniteRowModelModule,
26+
PaginationModule,
27+
RowDragModule,
28+
TextEditorModule,
29+
TextFilterModule,
30+
ValidationModule
31+
];
32+
33+
export const initializeAgGridModules = () => {
34+
const modulesToLoad = [...productionModules];
35+
36+
// Load helpful warnings in development mode
37+
if (process.env.NODE_ENV === 'development') {
38+
modulesToLoad.push(ValidationModule);
39+
}
40+
ModuleRegistry.registerModules(modulesToLoad);
41+
};

src/bootstrap/sentry.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as Sentry from '@sentry/react';
2+
import { useEffect } from 'react';
3+
import {
4+
createRoutesFromChildren,
5+
matchRoutes,
6+
useLocation,
7+
useNavigationType
8+
} from 'react-router';
9+
import Constants from 'src/commons/utils/Constants';
10+
import { store } from 'src/pages/createStore';
11+
12+
export const initializeSentryLogging = () => {
13+
if (!Constants.sentryDsn) {
14+
return;
15+
}
16+
Sentry.init({
17+
dsn: Constants.sentryDsn,
18+
environment: Constants.sourceAcademyEnvironment,
19+
release: `cadet-frontend@${Constants.sourceAcademyVersion}`,
20+
integrations: [
21+
Sentry.reactRouterV7BrowserTracingIntegration({
22+
useEffect,
23+
useLocation,
24+
useNavigationType,
25+
createRoutesFromChildren,
26+
matchRoutes
27+
}),
28+
Sentry.replayIntegration()
29+
]
30+
});
31+
const userId = store.getState().session.userId;
32+
Sentry.setUser(typeof userId !== 'undefined' ? { id: userId.toString() } : null);
33+
};

src/commons/sourceRecorder/SourceRecorderTable.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import 'ag-grid-community/styles/ag-grid.css';
2-
31
import {
42
Divider,
53
FormGroup,
@@ -9,6 +7,7 @@ import {
97
SpinnerSize
108
} from '@blueprintjs/core';
119
import { ColDef, GridApi, GridReadyEvent } from 'ag-grid-community';
10+
import { themeBalham } from 'ag-grid-community';
1211
import { AgGridReact } from 'ag-grid-react';
1312
import { sortBy } from 'lodash';
1413
import React from 'react';
@@ -62,7 +61,7 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
6261
},
6362
minWidth: 200,
6463
suppressMovable: true,
65-
suppressMenu: true,
64+
suppressHeaderMenuButton: true,
6665
cellStyle: {
6766
'text-align': 'left'
6867
},
@@ -73,15 +72,15 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
7372
field: 'title',
7473
minWidth: 100,
7574
suppressMovable: true,
76-
suppressMenu: true,
75+
suppressHeaderMenuButton: true,
7776
hide: !!this.props.handleSetSourcecastData
7877
},
7978
{
8079
headerName: 'Uploader',
8180
field: 'uploader.name',
8281
minWidth: 150,
8382
suppressMovable: true,
84-
suppressMenu: true,
83+
suppressHeaderMenuButton: true,
8584
cellStyle: {
8685
'text-align': 'center'
8786
}
@@ -91,7 +90,7 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
9190
valueGetter: params => getStandardDate(params.data.inserted_at),
9291
minWidth: 150,
9392
suppressMovable: true,
94-
suppressMenu: true
93+
suppressHeaderMenuButton: true
9594
},
9695
{
9796
headerName: 'Share',
@@ -102,7 +101,7 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
102101
},
103102
minWidth: 80,
104103
suppressMovable: true,
105-
suppressMenu: true
104+
suppressHeaderMenuButton: true
106105
},
107106
{
108107
headerName: 'Delete',
@@ -115,7 +114,7 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
115114
maxWidth: 100,
116115
sortable: false,
117116
suppressMovable: true,
118-
suppressMenu: true,
117+
suppressHeaderMenuButton: true,
119118
cellStyle: {
120119
'text-align': 'center'
121120
},
@@ -169,6 +168,7 @@ class SourcecastTable extends React.Component<SourceRecorderTableProps, State> {
169168
<div className="SourcecastTable">
170169
<div className="ag-grid-parent">
171170
<AgGridReact
171+
theme={themeBalham}
172172
domLayout="autoHeight"
173173
columnDefs={this.state.columnDefs}
174174
defaultColDef={this.defaultColumnDefs}

src/index.tsx

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,22 @@ import 'src/i18n/i18n';
22
import 'src/styles/index.scss';
33

44
import { Button, OverlaysProvider } from '@blueprintjs/core';
5-
import * as Sentry from '@sentry/react';
65
import { setModulesStaticURL } from 'js-slang/dist/modules/loader';
7-
import { useEffect } from 'react';
86
import { createRoot } from 'react-dom/client';
97
import { Provider } from 'react-redux';
10-
import {
11-
createRoutesFromChildren,
12-
matchRoutes,
13-
useLocation,
14-
useNavigationType
15-
} from 'react-router';
168
import Constants, { Links } from 'src/commons/utils/Constants';
179
import { showWarningMessage } from 'src/commons/utils/notifications/NotificationsHelper';
1810
import { register as registerServiceWorker } from 'src/commons/utils/RegisterServiceWorker';
1911
import { triggerSyncLogs } from 'src/features/eventLogging/client';
2012
import { store } from 'src/pages/createStore';
2113

14+
import { initializeAgGridModules } from './bootstrap/agGrid';
15+
import { initializeSentryLogging } from './bootstrap/sentry';
2216
import ApplicationWrapper from './commons/application/ApplicationWrapper';
2317
import { createInBrowserFileSystem } from './pages/fileSystem/createInBrowserFileSystem';
2418

25-
if (Constants.sentryDsn) {
26-
Sentry.init({
27-
dsn: Constants.sentryDsn,
28-
environment: Constants.sourceAcademyEnvironment,
29-
release: `cadet-frontend@${Constants.sourceAcademyVersion}`,
30-
integrations: [
31-
Sentry.reactRouterV7BrowserTracingIntegration({
32-
useEffect,
33-
useLocation,
34-
useNavigationType,
35-
createRoutesFromChildren,
36-
matchRoutes
37-
}),
38-
Sentry.replayIntegration()
39-
]
40-
});
41-
const userId = store.getState().session.userId;
42-
Sentry.setUser(typeof userId !== 'undefined' ? { id: userId.toString() } : null);
43-
}
19+
initializeSentryLogging();
20+
initializeAgGridModules();
4421

4522
const rootContainer = document.getElementById('root') as HTMLElement;
4623
const root = createRoot(rootContainer);

src/pages/academy/academyRoutes.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ import { assessmentRegExp, gradingRegExp, teamRegExp } from 'src/features/academ
77
import { GuardedRoute } from 'src/routes/routeGuard';
88

99
import { store } from '../createStore';
10+
import {
11+
contestLeaderboardLoader,
12+
leaderboardLoader
13+
} from '../leaderboard/subcomponents/leaderboardUtils';
1014

1115
const notFoundPath = 'not_found';
1216

1317
const Assessment = () => import('../../commons/assessment/Assessment');
1418
const Game = () => import('./game/Game');
1519
const Sourcecast = () => import('../sourcecast/Sourcecast');
1620
const Achievement = () => import('../achievement/Achievement');
17-
const Leaderboard = () => import('../leaderboard/Leaderboard');
18-
const OverallLeaderboardWrapper = () =>
19-
import('../leaderboard/subcomponents/OverallLeaderboardWrapper');
21+
const OverallLeaderboard = () => import('../leaderboard/subcomponents/OverallLeaderboard');
2022
const ContestLeaderboardWrapper = () =>
2123
import('../leaderboard/subcomponents/ContestLeaderboardWrapper');
2224
const NotFound = () => import('../notFound/NotFound');
@@ -78,9 +80,18 @@ const getCommonAcademyRoutes = (): RouteObject[] => {
7880
},
7981
{ path: 'sourcecast/:sourcecastId?', lazy: Sourcecast },
8082
{ path: 'achievements/*', lazy: Achievement },
81-
{ path: 'leaderboard/overall', lazy: OverallLeaderboardWrapper },
82-
{ path: 'leaderboard/contests/*', lazy: ContestLeaderboardWrapper },
83-
{ path: 'leaderboard/*', lazy: Leaderboard },
83+
{
84+
path: 'leaderboard',
85+
loader: leaderboardLoader,
86+
children: [
87+
{ path: 'overall', lazy: OverallLeaderboard },
88+
{
89+
path: 'contests/:contestId?/:leaderboardType',
90+
loader: contestLeaderboardLoader,
91+
lazy: ContestLeaderboardWrapper
92+
}
93+
]
94+
},
8495
{ path: '*', lazy: NotFound }
8596
];
8697
};

src/pages/academy/adminPanel/AdminPanel.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import 'ag-grid-community/styles/ag-grid.css';
2-
import 'ag-grid-community/styles/ag-theme-balham.css';
3-
41
import { Button, Divider, H1, Intent, Tab, Tabs } from '@blueprintjs/core';
52
import React, { useCallback, useEffect, useRef, useState } from 'react';
63
import { useDispatch } from 'react-redux';

src/pages/academy/adminPanel/subcomponents/AddStoriesUserPanel.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Position
1313
} from '@blueprintjs/core';
1414
import { IconNames } from '@blueprintjs/icons';
15-
import { ColDef } from 'ag-grid-community';
15+
import { type ColDef, themeBalham } from 'ag-grid-community';
1616
import { AgGridReact } from 'ag-grid-react';
1717
import { uniqBy } from 'lodash';
1818
import React from 'react';
@@ -50,8 +50,9 @@ const AddStoriesUserPanel: React.FC<Props> = props => {
5050
const { CSVReader } = useCSVReader();
5151

5252
const grid = (
53-
<div className="Grid ag-grid-parent ag-theme-balham">
53+
<div className="Grid">
5454
<AgGridReact
55+
theme={themeBalham}
5556
domLayout="autoHeight"
5657
columnDefs={columnDefs}
5758
defaultColDef={defaultColumnDefs}

src/pages/academy/adminPanel/subcomponents/AddUserPanel.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Position
1313
} from '@blueprintjs/core';
1414
import { IconNames } from '@blueprintjs/icons';
15-
import { ColDef } from 'ag-grid-community';
15+
import { type ColDef, themeBalham } from 'ag-grid-community';
1616
import { AgGridReact } from 'ag-grid-react';
1717
import { uniqBy } from 'lodash';
1818
import React from 'react';
@@ -50,8 +50,9 @@ const AddUserPanel: React.FC<Props> = props => {
5050
const { CSVReader } = useCSVReader();
5151

5252
const grid = (
53-
<div className="Grid ag-grid-parent ag-theme-balham">
53+
<div className="Grid">
5454
<AgGridReact
55+
theme={themeBalham}
5556
domLayout="autoHeight"
5657
columnDefs={columnDefs}
5758
defaultColDef={defaultColumnDefs}

src/pages/academy/adminPanel/subcomponents/assessmentConfigPanel/AssessmentConfigPanel.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Button, H2 } from '@blueprintjs/core';
22
import {
3-
CellValueChangedEvent,
4-
ColDef,
5-
GridApi,
6-
GridReadyEvent,
7-
RowDragEvent
3+
type CellValueChangedEvent,
4+
type ColDef,
5+
type GridApi,
6+
type GridReadyEvent,
7+
type RowDragEvent,
8+
themeBalham
89
} from 'ag-grid-community';
910
import { AgGridReact } from 'ag-grid-react';
1011
import { cloneDeep, isEqual } from 'lodash';
@@ -316,8 +317,9 @@ const AssessmentConfigPanel: WithImperativeApi<
316317
};
317318

318319
const grid = (
319-
<div className="Grid ag-grid-parent ag-theme-balham">
320+
<div className="Grid">
320321
<AgGridReact
322+
theme={themeBalham}
321323
domLayout="autoHeight"
322324
columnDefs={columnDefs}
323325
defaultColDef={defaultColumnDefs}

0 commit comments

Comments
 (0)