Skip to content

Commit e276cdc

Browse files
sherryhlijennchennChinemeremChigbossreekar
authored
[Release] Version 0.3.7 (#406)
* Add support to go back to prev page (#397) * Upgrade to ubuntu 22.04 (#395) * Upgrade to ubuntu 22.04 * Update ci.yml * Observe ts version for ubuntu 20.04 * Pin typescript version * Update yarn.lock * Revert "Update yarn.lock" This reverts commit dadfe1d. * Revert "Pin typescript version" This reverts commit 42c6eb3. * Pin packageManager * Update ci.yml * Update ci.yml * Update yarn.lock * Pin exact versions * Update yarn.lock * Update package.json * Generate prisma client * Update tsconfig.json * Update ci.yml * Prisma binary targets * Update ci.yml * Try linux-musl * Linux musl * Update ci.yml * Specify musl * Remove generated client * Update schema.prisma * Update ci.yml * Update schema.prisma * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update schema.prisma * Upgrade prisma * Try upgrading to Node 16 * Update ci.yml * Update yarn.lock * Upgrade prisma * Update ci.yml * Update tsconfig.json * Update schema.prisma * Update schema.prisma * Update schema.prisma * Add Seeding and Add Primsa3 Naming Migration * Prisma standardize * Update yarn.lock * Update yarn and add return type * Revert package.json * Revert "Revert package.json" This reverts commit 8db818e. * Update index.tsx --------- Co-authored-by: Sharujan Sreekaran <ohnose123@gmail.com> * Add Albert Lai to employee seed data (#401) Added a new employee entry for Albert Lai in the seed data to support development and testing with updated employee records. * Upgrade to ubuntu 24.04 (#402) * Upgrade to ubuntu 22.04 * Update ci.yml * Observe ts version for ubuntu 20.04 * Pin typescript version * Update yarn.lock * Revert "Update yarn.lock" This reverts commit dadfe1d. * Revert "Pin typescript version" This reverts commit 42c6eb3. * Pin packageManager * Update ci.yml * Update ci.yml * Update yarn.lock * Pin exact versions * Update yarn.lock * Update package.json * Generate prisma client * Update tsconfig.json * Update ci.yml * Prisma binary targets * Update ci.yml * Try linux-musl * Linux musl * Update ci.yml * Specify musl * Remove generated client * Update schema.prisma * Update ci.yml * Update schema.prisma * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update ci.yml * Update schema.prisma * Upgrade prisma * Try upgrading to Node 16 * Update ci.yml * Update yarn.lock * Upgrade prisma * Update ci.yml * Update tsconfig.json * Update schema.prisma * Update schema.prisma * Update schema.prisma * Add Seeding and Add Primsa3 Naming Migration * Prisma standardize * Update yarn.lock * Update yarn and add return type * Revert package.json * Revert "Revert package.json" This reverts commit 8db818e. * Update index.tsx * Add IF EXISTS to index rename statements in migration Updated index renaming statements in the migration SQL to use ALTER INDEX IF EXISTS for safer execution. This prevents errors if the specified indexes do not exist during migration. * Update migration.sql --------- Co-authored-by: Sharujan Sreekaran <ohnose123@gmail.com> --------- Co-authored-by: Jennifer Chen <32009013+jennchenn@users.noreply.github.com> Co-authored-by: Chinemerem <chinemeremchigbo@Outlook.com> Co-authored-by: Sharujan Sreekaran <ohnose123@gmail.com>
1 parent 7911114 commit e276cdc

File tree

10 files changed

+491
-578
lines changed

10 files changed

+491
-578
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
os: [ubuntu-20.04]
20-
node: [14.17.0]
19+
os: [ubuntu-22.04]
20+
node: [16.20.2]
2121

2222
steps:
2323
- name: Checkout

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ yarn dev
7272
npx prisma migrate deploy
7373
```
7474

75-
4. Reset and seed database (ensure node is v14.17.0 or else it will stall)
75+
4. Reset and seed database (ensure node is v16.20.2 or else it will stall)
7676

7777
```bash
7878
npx prisma migrate reset

components/Pagination.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { HStack, Text, IconButton, Input } from '@chakra-ui/react'; // Chakra UI
22
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'; // Chakra UI Icons
3-
import { useState } from 'react';
3+
import { useEffect, useState } from 'react';
44

55
type Props = {
66
readonly pageSize: number; // Number of items per page
@@ -25,6 +25,10 @@ export default function Pagination(props: Props) {
2525

2626
const [inputValue, setInputValue] = useState<string | number>(pageNumber + 1); // Display page number as 1-based index
2727

28+
useEffect(() => {
29+
setInputValue(pageNumber + 1);
30+
}, [pageNumber]);
31+
2832
/**
2933
* Go to the next page if possible, and invoke callback if defined
3034
* `pageNumber + 1` moves to the next page (zero-based index)

components/admin/requests/Header.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,10 @@ export default function RequestHeader({
9393

9494
const [backLink, setBackLink] = useState('/admin');
9595
const generateBackLink = () => {
96-
let status;
9796
const routerQuery = router.query;
98-
if (routerQuery === undefined || routerQuery.origin === undefined) {
99-
status = applicationStatus;
100-
} else {
101-
status = routerQuery.origin;
102-
}
103-
setBackLink(`/admin?tab=${status}`);
97+
const status = typeof routerQuery.tab === 'string' ? routerQuery.tab : applicationStatus;
98+
const page = typeof routerQuery.page === 'string' ? routerQuery.page : '0';
99+
setBackLink(`/admin?tab=${status}&page=${page}`);
104100
};
105101

106102
useEffect(() => {

lib/utils/s3-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export const refreshS3SignedUrl = (
143143
objectKey: string | null,
144144
s3SignedUrl: string | null,
145145
lastUpdatedTime: number
146-
) => {
146+
): string | null => {
147147
// Get the valid duration period from env.
148148
const linkDuration = parseInt(process.env.INVOICE_LINK_TTL_DAYS);
149149
const DAY = 24 * 60 * 60 * 1000;

package.json

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "with-typescript",
33
"version": "1.0.0",
44
"engines": {
5-
"node": "14.17.0"
5+
"node": "16.20.2"
66
},
77
"scripts": {
88
"dev": "next",
@@ -22,69 +22,70 @@
2222
"ts-node": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\""
2323
},
2424
"dependencies": {
25-
"@apollo/client": "^3.6.8",
26-
"@chakra-ui/icons": "^1.0.14",
27-
"@chakra-ui/react": "^1.6.2",
28-
"@emotion/react": "11",
29-
"@emotion/styled": "11",
30-
"@fontsource/noto-sans": "^4.4.5",
31-
"@prisma/client": "^2.28.0",
32-
"@types/mime-types": "^2.1.1",
33-
"@types/node": "^16.7.4",
34-
"@types/nodemailer": "^6.4.4",
35-
"@types/react-bootstrap-typeahead": "^5.1.7",
36-
"@types/react-helmet": "^6.1.2",
37-
"@types/react-table": "^7.7.2",
38-
"apollo-server-micro": "^2.24.1",
25+
"@apollo/client": "3.6.8",
26+
"@chakra-ui/icons": "1.0.14",
27+
"@chakra-ui/react": "1.6.2",
28+
"@emotion/react": "11.4.0",
29+
"@emotion/styled": "11.3.0",
30+
"@fontsource/noto-sans": "4.4.5",
31+
"@prisma/client": "3.15.2",
32+
"@types/mime-types": "2.1.1",
33+
"@types/node": "16.7.4",
34+
"@types/nodemailer": "6.4.4",
35+
"@types/react-bootstrap-typeahead": "5.1.7",
36+
"@types/react-helmet": "6.1.2",
37+
"@types/react-table": "7.7.2",
38+
"apollo-server-micro": "2.24.1",
3939
"bootstrap": "5.1.1",
40-
"chakra-ui-steps": "^1.1.1",
41-
"csv-writer": "^1.6.0",
42-
"formik": "^2.2.9",
43-
"framer-motion": "4",
44-
"graphql": "^15.5.0",
45-
"graphql-middleware": "^6.1.31",
40+
"chakra-ui-steps": "1.1.1",
41+
"csv-writer": "1.6.0",
42+
"formik": "2.2.9",
43+
"framer-motion": "4.1.17",
44+
"graphql": "15.5.0",
45+
"graphql-middleware": "6.1.31",
4646
"graphql-request": "3.6.0",
47-
"mime-types": "^2.1.35",
48-
"moment": "^2.29.3",
49-
"next": "12",
50-
"next-auth": "^3.26.1",
51-
"next-i18next": "^8.3.0",
52-
"next-s3-upload": "^0.1.8",
53-
"nodemailer": "^6.6.1",
54-
"pdfmake": "^0.2.4",
55-
"pino": "^8.3.0",
56-
"react": "^17.0.2",
57-
"react-bootstrap": "^2.0.0-rc.0",
58-
"react-bootstrap-typeahead": "^5.2.1",
59-
"react-day-picker": "^7.4.10",
60-
"react-dom": "^17.0.2",
61-
"react-helmet": "^6.1.0",
62-
"react-intersection-observer": "^8.32.0",
63-
"react-table": "^7.7.0",
64-
"typescript": "^4.4.2",
65-
"unstated-next": "^1.1.0",
66-
"yup": "^0.32.11"
47+
"mime-types": "2.1.35",
48+
"moment": "2.29.1",
49+
"next": "12.0.3",
50+
"next-auth": "3.26.1",
51+
"next-i18next": "8.3.0",
52+
"next-s3-upload": "0.1.8",
53+
"nodemailer": "6.6.1",
54+
"pdfmake": "0.2.4",
55+
"pino": "8.3.0",
56+
"react": "17.0.2",
57+
"react-bootstrap": "2.0.0-rc.0",
58+
"react-bootstrap-typeahead": "5.2.1",
59+
"react-day-picker": "7.4.10",
60+
"react-dom": "17.0.2",
61+
"react-helmet": "6.1.0",
62+
"react-intersection-observer": "8.32.0",
63+
"react-table": "7.7.0",
64+
"typescript": "4.4.2",
65+
"unstated-next": "1.1.0",
66+
"yarn-lockfile": "1.1.1",
67+
"yup": "0.32.11"
6768
},
6869
"devDependencies": {
69-
"@graphql-codegen/add": "^2.0.2",
70+
"@graphql-codegen/add": "2.0.2",
7071
"@graphql-codegen/cli": "1.21.4",
71-
"@graphql-codegen/typescript": "^1.22.0",
72-
"@types/pdfmake": "^0.1.21",
73-
"@types/react": "^17.0.2",
74-
"@types/react-dom": "^17.0.1",
75-
"@typescript-eslint/eslint-plugin": "^4.24.0",
76-
"@typescript-eslint/parser": "^4.24.0",
77-
"apollo": "^2.33.2",
78-
"csv-parser": "^3.0.0",
79-
"eslint": "^7.26.0",
80-
"eslint-config-next": "^11.0.0",
81-
"eslint-plugin-react": "^7.23.2",
82-
"husky": "4",
83-
"lint-staged": "^11.0.0",
84-
"pino-pretty": "^8.1.0",
85-
"prettier": "^2.3.0",
86-
"prisma": "^2.28.0",
87-
"ts-node": "^10.0.0"
72+
"@graphql-codegen/typescript": "1.22.0",
73+
"@types/pdfmake": "0.1.21",
74+
"@types/react": "17.0.30",
75+
"@types/react-dom": "17.0.5",
76+
"@typescript-eslint/eslint-plugin": "4.33.0",
77+
"@typescript-eslint/parser": "4.33.0",
78+
"apollo": "2.33.2",
79+
"csv-parser": "3.0.0",
80+
"eslint": "7.32.0",
81+
"eslint-config-next": "11.0.0",
82+
"eslint-plugin-react": "7.24.0",
83+
"husky": "4.3.8",
84+
"lint-staged": "11.0.0",
85+
"pino-pretty": "8.1.0",
86+
"prettier": "2.3.0",
87+
"prisma": "3.15.2",
88+
"ts-node": "10.0.0"
8889
},
8990
"husky": {
9091
"hooks": {
@@ -95,5 +96,8 @@
9596
"*.{ts,tsx}": "eslint --cache --fix",
9697
"*.{ts,tsx,md}": "prettier --write"
9798
},
99+
"prisma": {
100+
"seed": "yarn ts-node prisma/seed.ts"
101+
},
98102
"license": "MIT"
99103
}

pages/admin/index.tsx

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import Table from '@components/Table'; // Table component
2929
import Pagination from '@components/Pagination'; // Pagination component
3030
import RequestStatusBadge from '@components/admin/RequestStatusBadge'; //Status badge component
3131
import { useQuery } from '@tools/hooks/graphql'; //Apollo client
32-
import { useEffect, useState } from 'react'; // React
32+
import { useEffect, useRef, useState, useMemo } from 'react'; // React
3333
import {
3434
ApplicationRow,
3535
GetApplicationsRequest,
@@ -46,27 +46,42 @@ import EmptyMessage from '@components/EmptyMessage';
4646

4747
interface RouterQuery {
4848
tab?: string;
49+
page?: number;
4950
}
5051

51-
export const getTabIndex = (routerQuery: RouterQuery): number => {
52-
if (routerQuery === undefined || routerQuery.tab === undefined) {
53-
return 1;
52+
export const getTabPageIndex = (routerQuery: RouterQuery): [number, number] => {
53+
if (
54+
routerQuery === undefined ||
55+
routerQuery.tab === undefined ||
56+
routerQuery.page === undefined
57+
) {
58+
return [1, 0];
5459
}
60+
5561
const tabName = routerQuery.tab;
62+
let tabIndex = 1;
63+
5664
switch (tabName) {
5765
case 'ALL':
58-
return 0;
66+
tabIndex = 0;
67+
break;
5968
case 'PENDING':
60-
return 1;
69+
tabIndex = 1;
70+
break;
6171
case 'IN_PROGRESS':
62-
return 2;
72+
tabIndex = 2;
73+
break;
6374
case 'COMPLETED':
64-
return 3;
75+
tabIndex = 3;
76+
break;
6577
case 'REJECTED':
66-
return 4;
78+
tabIndex = 4;
79+
break;
6780
default:
68-
return 1;
81+
tabIndex = 1;
6982
}
83+
84+
return [tabIndex, Number(routerQuery.page)];
7085
};
7186

7287
const tabIndexToStatus: { [key: number]: ApplicationStatus | 'ALL' } = {
@@ -174,23 +189,37 @@ const Requests: NextPage = () => {
174189
// This will avoid firing a query for each key the user presses
175190
const debouncedSearchFilter = useDebounce<string>(searchFilter, 500);
176191

192+
const filters = useMemo(
193+
() => ({
194+
statusFilter,
195+
permitTypeFilter,
196+
requestTypeFilter,
197+
searchFilter,
198+
sortOrder,
199+
}),
200+
[statusFilter, permitTypeFilter, requestTypeFilter, searchFilter, sortOrder]
201+
);
202+
203+
const debouncedFilters = useDebounce(filters, 500);
204+
177205
// Data & pagination
178206
const [requestsData, setRequestsData] = useState<Array<ApplicationRow>>([]);
179207
const [pageNumber, setPageNumber] = useState(0);
180208
const [recordsCount, setRecordsCount] = useState(0);
181209

182210
// Tabs
183211
const [tabIndex, setTabIndex] = useState(0);
184-
const getTabFromRoute = (): number => {
185-
const index = getTabIndex(routerQuery);
212+
const getTabPageFromRoute = () => {
213+
const [index, page] = getTabPageIndex(routerQuery);
186214
setTabIndex(index);
215+
setPageNumber(page);
187216
return index;
188217
};
189218

190219
const handleTabChange = () => {
191220
const status = tabIndexToStatus[tabIndex];
192221
setStatusFilter(status === 'ALL' ? null : status);
193-
router.push({ query: { tab: status } });
222+
router.push({ query: { tab: status, page: pageNumber } });
194223
};
195224

196225
// Make query to applications resolver
@@ -239,9 +268,11 @@ const Requests: NextPage = () => {
239268
}
240269
);
241270

271+
const firstRender = useRef(true);
272+
242273
// Determine the active tab on page load based on the route
243274
useEffect(() => {
244-
getTabFromRoute();
275+
getTabPageFromRoute();
245276
}, []);
246277

247278
useEffect(() => {
@@ -251,9 +282,13 @@ const Requests: NextPage = () => {
251282

252283
// Set page number to 0 after every filter or sort change
253284
useEffect(() => {
285+
if (firstRender.current) {
286+
firstRender.current = false;
287+
return; // Skip resetting on first mount to allow resetting state
288+
}
254289
setPageNumber(0);
255290
refetch();
256-
}, [statusFilter, permitTypeFilter, requestTypeFilter, debouncedSearchFilter, sortOrder]);
291+
}, [debouncedFilters]);
257292

258293
return (
259294
<Layout>
@@ -291,6 +326,7 @@ const Requests: NextPage = () => {
291326
index={tabIndex}
292327
onChange={index => {
293328
setTabIndex(index);
329+
setPageNumber(0);
294330
}}
295331
>
296332
<TabList paddingX="24px" defaultIndex={1}>
@@ -423,7 +459,9 @@ const Requests: NextPage = () => {
423459
initialSort={sortOrder}
424460
onChangeSortOrder={setSortOrder}
425461
onRowClick={({ id }) =>
426-
router.push(`/admin/request/${id}?origin=${tabIndexToStatus[tabIndex]}`)
462+
router.push(
463+
`/admin/request/${id}?tab=${tabIndexToStatus[tabIndex]}&page=${pageNumber}`
464+
)
427465
}
428466
/>
429467
<Flex justifyContent="flex-end">

prisma/dev-seed-utils/employees.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ const employees = [
124124
lastName: 'Lu',
125125
email: 'davidlu+employee@uwblueprint.org',
126126
},
127+
{
128+
firstName: 'Albert',
129+
lastName: 'Lai',
130+
email: 'albertlai631+employee@gmail.com',
131+
},
127132
];
128133

129134
/**

0 commit comments

Comments
 (0)