Skip to content

Utils migration #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@isamrish/gatsby-plugin-google-adsense": "^1.2.0",
"@reduxjs/toolkit": "^1.9.5",
"@types/node": "^22.13.10",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"chart.js": "^4.3.0",
"debounce": "^1.2.1",
"fuse.js": "^6.6.2",
Expand Down Expand Up @@ -38,7 +41,8 @@
"devDependencies": {
"husky": "^8.0.0",
"lint-staged": "^13.2.3",
"prettier": "^2.8.8"
"prettier": "^2.8.8",
"typescript": "^5.8.2"
},
"scripts": {
"build": "gatsby build",
Expand Down
27 changes: 0 additions & 27 deletions src/utils/chartData.js

This file was deleted.

46 changes: 46 additions & 0 deletions src/utils/chartData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
interface OrgYearData {
[year: string]: {
num_projects: number
}
}
interface OrgChartData {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline above

years: number[]
numProjects: number[]
}
/**
* Creates organization chart data based on the provided years and organization data.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can skip this jsdoc. This doesn't say anything extra that isn't already clear by the types and naming of the function arguments.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, there is no downsides of having these comments but just want to say that it's not worth spending time writing these unless they add some value.

* @param allYears - An array of all years to consider.
* @param orgYearData - An object containing organization data for specific years.
* @returns An object containing the years to plot and the number of projects for each year.
*/

export const createOrgChartData = (
allYears: number[],
orgYearData: OrgYearData
): OrgChartData => {
// Filter and sort years, excluding 2025
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ditto, this comment doesn't seem to add any value.

same below.

const years = allYears
.sort()
.filter(item => item != 2025)
.reduce((yearsToPlot: number[], year: number) => {
if (yearsToPlot.length != 0) {
yearsToPlot.push(year)
return yearsToPlot
} else {
return Object.keys(orgYearData).includes(year.toString()) ? [year] : []
}
}, [])
// Calculate the number of projects for each year
const numProjects = []
for (const year of years) {
if (Object.keys(orgYearData).includes(year.toString())) {
numProjects.push(orgYearData[year].num_projects)
} else {
numProjects.push(0)
}
}
return {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline above.

years,
numProjects,
}
}
13 changes: 0 additions & 13 deletions src/utils/events.js

This file was deleted.

28 changes: 28 additions & 0 deletions src/utils/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
type EventCallBack<T = any> = (payload: T) => void

export class EventBus {
// Define a static map to store event subscribers
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto: these comments don't seem to add any value. I'd prefer skipping these.

private static _subscriberMap: Record<string, EventCallBack[]> = {}

/**
* Emit an event with a payload to all subscribers.
* @param eventName - The name of the event to emit.
* @param payload - The data to pass to the subscribers.
*/
static emit<T = any>(eventName: string, payload: T): void {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, can you think of ideas to avoid any here? We'd want the caller of this function to know what type should the payload be based on the eventName.

I was thinking something we can maintain a registry of all event types in this file.

type EventTypes = {
  updateSearch: string;
}

type EventCallback<T> = (payload: T) => void

export class EventBus {

  type SubscriberMap = {
    [EventName in keyof EventTypes]: EventCallback<EventTypes[EventName]>[];
  }
 
  private static _subscriberMap: SubscriberMap = {}

  static emit<T extends keyof EventTypes>(eventName: T, payload: EventTypes[T]): void {
    if (!this._subscriberMap[eventName]) return
    this._subscriberMap[eventName].forEach(callback => callback(payload))
  }

  static subscribe<T extends keyof EventTypes>(eventName: T, callback: EventCallback<EventTypes[T]>): void {
    if (!this._subscriberMap[eventName]) this._subscriberMap[eventName] = []
    this._subscriberMap[eventName].push(callback)
  }
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you have better ideas.

if (!this._subscriberMap[eventName]) return
this._subscriberMap[eventName].forEach(callback => callback(payload))
}
/**
* Subscribe to an event.
* @param eventName - The name of the event to subscribe to.
* @param callback - The function to call when the event is emitted.
*/
static subscribe<T = any>(
eventName: string,
callback: EventCallBack<T>
): void {
if (!this._subscriberMap[eventName]) this._subscriberMap[eventName] = []
this._subscriberMap[eventName].push(callback)
}
}
14 changes: 7 additions & 7 deletions src/utils/searchParams.js → src/utils/searchParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
* This will not re-render the complete application. Using this API
* may cause the react-router to go out of sync and give false values if
* accessed elsewhere.
* @param {{ [param: string]: string }} params
* @param {Record<string, string>} params - Key-value pairs of search params to set.
*/
export const setSearchParams = params => {
export const setSearchParams = (params: Record<string, string>): void => {
if (typeof window !== "undefined" && window) {
const url = new URL(window.location)
const url = new URL(window.location.href)
for (const [param, value] of Object.entries(params)) {
url.searchParams.set(param, value)
}
Expand All @@ -22,9 +22,9 @@ export const setSearchParams = params => {
* @param {string} param
* @returns {string | null}
*/
export const getSearchParam = param => {
export const getSearchParam = (param: string): string | null => {
if (typeof window !== "undefined" && window) {
return new URL(window.location).searchParams.get(param)
return new URL(window.location.href).searchParams.get(param)
} else {
console.error("error getting search params. window is not defined.")
return null
Expand All @@ -35,9 +35,9 @@ export const getSearchParam = param => {
* Removes a search param from the url.
* @param {string} param
*/
export const removeSearchParam = param => {
export const removeSearchParam = (param: string): void => {
if (typeof window !== "undefined" && window) {
const url = new URL(window.location)
const url = new URL(window.location.href)
url.searchParams.delete(param)
window.history.pushState({}, "", url)
} else {
Expand Down
16 changes: 16 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"outDir": "./dist",
"rootDir": "./",
"module": "commonjs",
"strict": true,
"noImplicitAny": true,
"moduleResolution": "node",
"esModuleInterop": true,
"target": "es5",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
29 changes: 29 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2534,6 +2534,13 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==

"@types/node@^22.13.10":
version "22.13.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.10.tgz#df9ea358c5ed991266becc3109dc2dc9125d77e4"
integrity sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==
dependencies:
undici-types "~6.20.0"

"@types/node@^8.5.7":
version "8.10.66"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
Expand Down Expand Up @@ -2561,6 +2568,11 @@
dependencies:
"@types/react" "*"

"@types/react-dom@^19.0.4":
version "19.0.4"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.0.4.tgz#bedba97f9346bd4c0fe5d39e689713804ec9ac89"
integrity sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==

"@types/react@*":
version "17.0.2"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.2.tgz#3de24c4efef902dd9795a49c75f760cbe4f7a5a8"
Expand All @@ -2569,6 +2581,13 @@
"@types/prop-types" "*"
csstype "^3.0.2"

"@types/react@^19.0.10":
version "19.0.10"
resolved "https://registry.yarnpkg.com/@types/react/-/react-19.0.10.tgz#d0c66dafd862474190fe95ce11a68de69ed2b0eb"
integrity sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==
dependencies:
csstype "^3.0.2"

"@types/responselike@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
Expand Down Expand Up @@ -11645,6 +11664,11 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=

typescript@^5.8.2:
version "5.8.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.2.tgz#8170b3702f74b79db2e5a96207c15e65807999e4"
integrity sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==

ua-parser-js@^1.0.35:
version "1.0.35"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz#c4ef44343bc3db0a3cbefdf21822f1b1fc1ab011"
Expand Down Expand Up @@ -11680,6 +11704,11 @@ unc-path-regex@^0.1.2:
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=

undici-types@~6.20.0:
version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==

unicode-canonical-property-names-ecmascript@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
Expand Down