Skip to content

Commit b58ce55

Browse files
Addressing Continuous Refreshing in Development Environment (#1466)
* Update documentation * used custom hook for localstorage * Revert "Update documentation" This reverts commit 521d8b5. * fixing documentation conflicts * removed documentation.zip * Add pre-commit hook to check localStorage usage * added check for file in check-localstorage-usage.js script * Update OrgList.test.tsx * Update getRefreshToken.test.ts * updated script and workflow to check for flag * Update documentation --------- Co-authored-by: chandel-aman <dishatalreja1202@gmail.com>
1 parent df259fc commit b58ce55

File tree

194 files changed

+884
-411
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

194 files changed

+884
-411
lines changed

.github/workflows/pull-request.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ jobs:
4949

5050
- name: Run linting check
5151
if: steps.changed-files.outputs.only_changed != 'true'
52-
run: npm run lint:check
52+
run: npm run lint:check
53+
54+
- name: Check for localStorage Usage
55+
run: |
56+
chmod +x scripts/githooks/check-localstorage-usage.js
57+
node scripts/githooks/check-localstorage-usage.js --scan-entire-repo
5358
5459
- name: Compare translation files
5560
run: |

.lintstagedrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"**/*.{ts,tsx,yml}": "eslint --fix",
3-
"**/*.{ts,tsx,json,scss,css,yml}": "prettier --write"
3+
"**/*.{ts,tsx,json,scss,css,yml}": "prettier --write",
4+
"**/*.{ts,tsx}": "node scripts/githooks/check-localstorage-usage.js"
45
}

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
"jest-preview": "jest-preview",
6767
"update:toc": "node scripts/githooks/update-toc.js",
6868
"lint-staged": "lint-staged --concurrent false",
69-
"setup": "tsx setup.ts"
69+
"setup": "tsx setup.ts",
70+
"check-localstorage": "node scripts/githooks/check-localstorage-usage.js"
7071
},
7172
"eslintConfig": {
7273
"extends": [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env node
2+
3+
import { readFileSync, existsSync } from 'fs';
4+
import path from 'path';
5+
import { execSync } from 'child_process';
6+
7+
const args = process.argv.slice(2);
8+
const scanEntireRepo = args.includes('--scan-entire-repo');
9+
10+
const containsSkipComment = (file) => {
11+
try {
12+
const content = readFileSync(file, 'utf-8');
13+
return content.includes('// SKIP_LOCALSTORAGE_CHECK');
14+
} catch (error) {
15+
console.error(`Error reading file ${file}:`, error.message);
16+
return false;
17+
}
18+
};
19+
20+
const getModifiedFiles = () => {
21+
try {
22+
if (scanEntireRepo) {
23+
const result = execSync('git ls-files | grep ".tsx\\?$"', {
24+
encoding: 'utf-8',
25+
});
26+
return result.trim().split('\n');
27+
}
28+
29+
const result = execSync('git diff --cached --name-only', {
30+
encoding: 'utf-8',
31+
});
32+
return result.trim().split('\n');
33+
} catch (error) {
34+
console.error('Error fetching modified files:', error.message);
35+
process.exit(1);
36+
}
37+
};
38+
39+
const files = getModifiedFiles();
40+
41+
const filesWithLocalStorage = [];
42+
43+
const checkLocalStorageUsage = (file) => {
44+
if (!file) {
45+
return;
46+
}
47+
48+
const fileName = path.basename(file);
49+
50+
// Skip files with specific names or containing a skip comment
51+
if (
52+
fileName === 'check-localstorage-usage.js' ||
53+
fileName === 'useLocalstorage.test.ts' ||
54+
fileName === 'useLocalstorage.ts' ||
55+
containsSkipComment(file)
56+
) {
57+
console.log(`Skipping file: ${file}`);
58+
return;
59+
}
60+
61+
try {
62+
if (existsSync(file)) {
63+
const content = readFileSync(file, 'utf-8');
64+
65+
if (
66+
content.includes('localStorage.getItem') ||
67+
content.includes('localStorage.setItem') ||
68+
content.includes('localStorage.removeItem')
69+
) {
70+
filesWithLocalStorage.push(file);
71+
}
72+
} else {
73+
console.log(`File ${file} does not exist.`);
74+
}
75+
} catch (error) {
76+
console.error(`Error reading file ${file}:`, error.message);
77+
}
78+
};
79+
80+
files.forEach(checkLocalStorageUsage);
81+
82+
if (filesWithLocalStorage.length > 0) {
83+
console.error('\x1b[31m%s\x1b[0m', '\nError: Found usage of localStorage');
84+
console.error('\nFiles with localStorage usage:');
85+
filesWithLocalStorage.forEach((file) => console.error(file));
86+
87+
console.info(
88+
'\x1b[34m%s\x1b[0m',
89+
'\nInfo: Consider using custom hook functions.'
90+
);
91+
console.info(
92+
'Please use the getItem, setItem, and removeItem functions provided by the custom hook useLocalStorage.\n'
93+
);
94+
95+
process.exit(1);
96+
}

src/App.tsx

+12-12
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ import Donate from 'screens/UserPortal/Donate/Donate';
3232
import Events from 'screens/UserPortal/Events/Events';
3333
// import Chat from 'screens/UserPortal/Chat/Chat';
3434
import Advertisements from 'components/Advertisements/Advertisements';
35+
import useLocalStorage from 'utils/useLocalstorage';
36+
37+
const { setItem } = useLocalStorage();
3538

3639
function app(): JSX.Element {
3740
/*const { updatePluginLinks, updateInstalled } = bindActionCreators(
@@ -63,18 +66,15 @@ function app(): JSX.Element {
6366

6467
useEffect(() => {
6568
if (data) {
66-
localStorage.setItem(
67-
'name',
68-
`${data.checkAuth.firstName} ${data.checkAuth.lastName}`
69-
);
70-
localStorage.setItem('id', data.checkAuth._id);
71-
localStorage.setItem('email', data.checkAuth.email);
72-
localStorage.setItem('IsLoggedIn', 'TRUE');
73-
localStorage.setItem('UserType', data.checkAuth.userType);
74-
localStorage.setItem('FirstName', data.checkAuth.firstName);
75-
localStorage.setItem('LastName', data.checkAuth.lastName);
76-
localStorage.setItem('UserImage', data.checkAuth.image);
77-
localStorage.setItem('Email', data.checkAuth.email);
69+
setItem('name', `${data.checkAuth.firstName} ${data.checkAuth.lastName}`);
70+
setItem('id', data.checkAuth._id);
71+
setItem('email', data.checkAuth.email);
72+
setItem('IsLoggedIn', 'TRUE');
73+
setItem('UserType', data.checkAuth.userType);
74+
setItem('FirstName', data.checkAuth.firstName);
75+
setItem('LastName', data.checkAuth.lastName);
76+
setItem('UserImage', data.checkAuth.image);
77+
setItem('Email', data.checkAuth.email);
7878
}
7979
}, [data, loading]);
8080

src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ import { MockedProvider, wait } from '@apollo/react-testing';
2121
import { StaticMockLink } from 'utils/StaticMockLink';
2222
import { ADD_ON_ENTRY_MOCK } from './AddOnEntryMocks';
2323
import { ToastContainer } from 'react-toastify';
24+
import useLocalStorage from 'utils/useLocalstorage';
25+
26+
const { getItem } = useLocalStorage();
2427

2528
const link = new StaticMockLink(ADD_ON_ENTRY_MOCK, true);
2629

2730
const httpLink = new HttpLink({
2831
uri: BACKEND_URL,
2932
headers: {
30-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
33+
authorization: 'Bearer ' + getItem('token') || '',
3134
},
3235
});
3336
console.error = jest.fn();

src/components/AddOn/core/AddOnRegister/AddOnRegister.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ import { BACKEND_URL } from 'Constant/constant';
1919
import i18nForTest from 'utils/i18nForTest';
2020
import { I18nextProvider } from 'react-i18next';
2121
import { toast } from 'react-toastify';
22+
import useLocalStorage from 'utils/useLocalstorage';
23+
24+
const { getItem } = useLocalStorage();
2225

2326
const httpLink = new HttpLink({
2427
uri: BACKEND_URL,
2528
headers: {
26-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
29+
authorization: 'Bearer ' + getItem('token') || '',
2730
},
2831
});
2932

src/components/AddOn/core/AddOnStore/AddOnStore.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ import { store } from 'state/store';
2222
import { BACKEND_URL } from 'Constant/constant';
2323
import i18nForTest from 'utils/i18nForTest';
2424
import { I18nextProvider } from 'react-i18next';
25+
import useLocalStorage from 'utils/useLocalstorage';
26+
27+
const { getItem } = useLocalStorage();
2528

2629
const httpLink = new HttpLink({
2730
uri: BACKEND_URL,
2831
headers: {
29-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
32+
authorization: 'Bearer ' + getItem('token') || '',
3033
},
3134
});
3235

src/components/Advertisements/Advertisements.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@ import {
2626
import userEvent from '@testing-library/user-event';
2727
import { ADD_ADVERTISEMENT_MUTATION } from 'GraphQl/Mutations/mutations';
2828
import { ToastContainer } from 'react-toastify';
29+
import useLocalStorage from 'utils/useLocalstorage';
30+
31+
const { getItem } = useLocalStorage();
2932

3033
const httpLink = new HttpLink({
3134
uri: BACKEND_URL,
3235
headers: {
33-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
36+
authorization: 'Bearer ' + getItem('token') || '',
3437
},
3538
});
3639

src/components/Advertisements/core/AdvertisementEntry/AdvertisementEntry.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ import { BACKEND_URL } from 'Constant/constant';
1717
import i18nForTest from 'utils/i18nForTest';
1818
import { I18nextProvider } from 'react-i18next';
1919
import dayjs from 'dayjs';
20+
import useLocalStorage from 'utils/useLocalstorage';
21+
22+
const { getItem } = useLocalStorage();
2023

2124
const httpLink = new HttpLink({
2225
uri: BACKEND_URL,
2326
headers: {
24-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
27+
authorization: 'Bearer ' + getItem('token') || '',
2528
},
2629
});
2730
const translations = JSON.parse(

src/components/Advertisements/core/AdvertisementRegister/AdvertisementRegister.test.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ import { toast } from 'react-toastify';
2323
import { ADD_ADVERTISEMENT_MUTATION } from 'GraphQl/Mutations/mutations';
2424
import dayjs from 'dayjs';
2525
import { StaticMockLink } from 'utils/StaticMockLink';
26+
import useLocalStorage from 'utils/useLocalstorage';
27+
28+
const { getItem } = useLocalStorage();
2629

2730
jest.mock('react-toastify', () => ({
2831
toast: {
@@ -60,7 +63,7 @@ const link = new StaticMockLink(MOCKS, true);
6063
const httpLink = new HttpLink({
6164
uri: BACKEND_URL,
6265
headers: {
63-
authorization: 'Bearer ' + localStorage.getItem('token') || '',
66+
authorization: 'Bearer ' + getItem('token') || '',
6467
},
6568
});
6669

src/components/DeleteOrg/DeleteOrg.test.tsx

+9-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import i18nForTest from 'utils/i18nForTest';
1717
import DeleteOrg from './DeleteOrg';
1818
import { ToastContainer, toast } from 'react-toastify';
1919
import { IS_SAMPLE_ORGANIZATION_QUERY } from 'GraphQl/Queries/Queries';
20+
import useLocalStorage from 'utils/useLocalstorage';
21+
22+
const { setItem } = useLocalStorage();
2023

2124
async function wait(ms = 1000): Promise<void> {
2225
await act(async () => {
@@ -106,7 +109,7 @@ afterEach(() => {
106109
describe('Delete Organization Component', () => {
107110
test('should be able to Toggle Delete Organization Modal', async () => {
108111
window.location.assign('/orgsetting/id=456');
109-
localStorage.setItem('UserType', 'SUPERADMIN');
112+
setItem('UserType', 'SUPERADMIN');
110113
render(
111114
<MockedProvider addTypename={false} link={link}>
112115
<BrowserRouter>
@@ -131,7 +134,7 @@ describe('Delete Organization Component', () => {
131134

132135
test('should be able to Toggle Delete Organization Modal When Organization is Sample Organization', async () => {
133136
window.location.assign('/orgsetting/id=123');
134-
localStorage.setItem('UserType', 'SUPERADMIN');
137+
setItem('UserType', 'SUPERADMIN');
135138
render(
136139
<MockedProvider addTypename={false} link={link}>
137140
<BrowserRouter>
@@ -156,7 +159,7 @@ describe('Delete Organization Component', () => {
156159

157160
test('Delete organization functionality should work properly', async () => {
158161
window.location.assign('/orgsetting/id=456');
159-
localStorage.setItem('UserType', 'SUPERADMIN');
162+
setItem('UserType', 'SUPERADMIN');
160163
render(
161164
<MockedProvider addTypename={false} link={link}>
162165
<BrowserRouter>
@@ -177,7 +180,7 @@ describe('Delete Organization Component', () => {
177180

178181
test('Delete organization functionality should work properly for sample org', async () => {
179182
window.location.assign('/orgsetting/id=123');
180-
localStorage.setItem('UserType', 'SUPERADMIN');
183+
setItem('UserType', 'SUPERADMIN');
181184
render(
182185
<MockedProvider addTypename={false} link={link}>
183186
<BrowserRouter>
@@ -198,7 +201,7 @@ describe('Delete Organization Component', () => {
198201

199202
test('Error handling for IS_SAMPLE_ORGANIZATION_QUERY mock', async () => {
200203
window.location.assign('/orgsetting/id=123');
201-
localStorage.setItem('UserType', 'SUPERADMIN');
204+
setItem('UserType', 'SUPERADMIN');
202205
jest.spyOn(toast, 'error');
203206
render(
204207
<MockedProvider addTypename={false} link={link2}>
@@ -222,7 +225,7 @@ describe('Delete Organization Component', () => {
222225

223226
test('Error handling for DELETE_ORGANIZATION_MUTATION mock', async () => {
224227
window.location.assign('/orgsetting/id=456');
225-
localStorage.setItem('UserType', 'SUPERADMIN');
228+
setItem('UserType', 'SUPERADMIN');
226229
render(
227230
<MockedProvider addTypename={false} link={link2}>
228231
<BrowserRouter>

src/components/DeleteOrg/DeleteOrg.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@ import {
1010
} from 'GraphQl/Mutations/mutations';
1111
import { IS_SAMPLE_ORGANIZATION_QUERY } from 'GraphQl/Queries/Queries';
1212
import styles from './DeleteOrg.module.css';
13+
import useLocalStorage from 'utils/useLocalstorage';
1314

1415
function deleteOrg(): JSX.Element {
1516
const { t } = useTranslation('translation', {
1617
keyPrefix: 'deleteOrg',
1718
});
1819
const [showDeleteModal, setShowDeleteModal] = useState(false);
20+
const { getItem } = useLocalStorage();
1921
const currentUrl = window.location.href.split('=')[1];
20-
const canDelete = localStorage.getItem('UserType') === 'SUPERADMIN';
22+
const canDelete = getItem('UserType') === 'SUPERADMIN';
2123
const toggleDeleteModal = (): void => setShowDeleteModal(!showDeleteModal);
2224

2325
const [del] = useMutation(DELETE_ORGANIZATION_MUTATION);

0 commit comments

Comments
 (0)