Skip to content

Commit 4a9c206

Browse files
committed
Backport azure-ad optimizations
1 parent e3c8232 commit 4a9c206

File tree

3 files changed

+87
-21
lines changed

3 files changed

+87
-21
lines changed

package-lock.json

+33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@types/lodash.memoize": "^4.1.9",
1818
"class-variance-authority": "^0.7.1",
1919
"clsx": "^2.1.1",
20+
"localforage": "^1.10.0",
2021
"lodash": "^4.17.21",
2122
"lodash.memoize": "^4.1.2",
2223
"lucide-react": "^0.471.1",
@@ -32,6 +33,7 @@
3233
},
3334
"devDependencies": {
3435
"@eslint/js": "^9.18.0",
36+
"@types/localforage": "^0.0.33",
3537
"@types/lodash": "^4.17.14",
3638
"@types/node": "^22.10.5",
3739
"@types/papaparse": "^5.3.15",

src/hooks/useLicenseData.ts

+52-21
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { useState, useCallback } from 'react';
1+
import { useState, useCallback, useEffect } from 'react';
22
import { GroupedData, ParsedUser } from '@/types';
33
import Papa from 'papaparse';
44
import { mapLicensesData } from '@/helpers/filter-helpers';
55
import _ from 'lodash';
6-
import { ErrorCodes, LicenseError } from '@/types/errors';
6+
import { LicenseError } from '@/types/errors';
7+
import localforage from 'localforage';
78

89
export interface UseLicenseDataReturn {
910
groupedData: GroupedData;
@@ -15,50 +16,80 @@ export interface UseLicenseDataReturn {
1516
handleFileDrop: (event: React.DragEvent<HTMLDivElement>) => Promise<void>;
1617
}
1718

19+
const CACHE_KEY = 'licenseDataCache';
20+
1821
export function useLicenseData(): UseLicenseDataReturn {
1922
const [groupedData, setGroupedData] = useState<GroupedData>({});
2023
const [loading, setLoading] = useState(false);
2124
const [fileName, setFileName] = useState('');
2225
const [error, setError] = useState<LicenseError | null>(null);
2326

27+
useEffect(() => {
28+
const loadCachedData = async () => {
29+
const cachedData = await localforage.getItem<{ groupedData: GroupedData; fileName: string }>(CACHE_KEY);
30+
if (cachedData) {
31+
setGroupedData(cachedData.groupedData);
32+
setFileName(cachedData.fileName);
33+
}
34+
};
35+
loadCachedData();
36+
}, []);
37+
2438
const processFile = async (file: File) => {
2539
if (!file) {
2640
setFileName('');
2741
setGroupedData({});
2842
return;
2943
}
30-
44+
45+
setError(null); // Reset error state before processing
46+
47+
const fileExtension = file.name.split('.').pop()?.toLowerCase();
48+
if (file.type !== 'text/csv' && fileExtension !== 'csv') {
49+
const licenseError = new LicenseError(
50+
'Invalid file type',
51+
'INVALID_FILE_TYPE',
52+
new Error('Only CSV files are allowed')
53+
);
54+
setError(licenseError);
55+
console.error(licenseError);
56+
return;
57+
}
58+
3159
setLoading(true);
3260
try {
3361
const text = await file.text();
34-
const result = Papa.parse<ParsedUser>(text, {
62+
Papa.parse<ParsedUser>(text, {
3563
header: true,
3664
skipEmptyLines: true,
3765
transformHeader: header => header.trim(),
38-
transform: value => value.trim()
39-
});
40-
41-
if (result.errors.length > 0) {
42-
throw new Error('Error parsing CSV: ' + result.errors[0].message);
43-
}
66+
transform: value => value.trim(),
67+
complete: (results) => {
68+
if (results.errors.length > 0) {
69+
throw new Error('Error parsing CSV: ' + results.errors.map(e => e.message).join(', '));
70+
}
4471

45-
const licenses = result.data;
46-
const mappedData = mapLicensesData(licenses);
47-
const grouped = _.groupBy(mappedData, 'department');
48-
const sortedGrouped = _.mapValues(grouped, users =>
49-
_.sortBy(users, ['displayName'])
50-
);
51-
52-
setGroupedData(sortedGrouped);
53-
setFileName(file.name);
72+
const licenses = results.data;
73+
const mappedData = mapLicensesData(licenses);
74+
const grouped = _.groupBy(mappedData, 'department');
75+
const sortedGrouped = _.mapValues(grouped, users =>
76+
_.sortBy(users, ['displayName'])
77+
);
78+
79+
setGroupedData(sortedGrouped);
80+
setFileName(file.name);
81+
82+
localforage.setItem(CACHE_KEY, { groupedData: sortedGrouped, fileName: file.name });
83+
}
84+
});
5485
} catch (error) {
5586
const licenseError = new LicenseError(
5687
'Error loading file',
57-
ErrorCodes.FILE_PARSE_ERROR,
88+
'FILE_PARSE_ERROR',
5889
error
5990
);
6091
setError(licenseError);
61-
console.error(licenseError);
92+
console.error('Error details:', error);
6293
} finally {
6394
setLoading(false);
6495
}

0 commit comments

Comments
 (0)