Skip to content
Merged
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
65 changes: 34 additions & 31 deletions web/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
import js from '@eslint/js'
import eslintReact from "@eslint-react/eslint-plugin";
import eslintJs from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
import globals from 'globals'
import reactPlugin from 'eslint-plugin-react'
import reactHooksPlugin from 'eslint-plugin-react-hooks'
import tseslint from 'typescript-eslint'
import eslintConfigPrettier from 'eslint-config-prettier'

export default tseslint.config(
export default defineConfig(
{
ignores: ['dist/**', 'vite-env.d.ts', 'vite.config.ts']
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
files: ["**/*.ts", "**/*.tsx"],
ignores: ['dist/**', 'vite-env.d.ts', 'vite.config.ts'],

// Extend recommended rule sets from:
// 1. ESLint JS's recommended rules
// 2. TypeScript ESLint recommended rules
// 3. ESLint React's recommended-typescript rules
// 4. Prettier (Must be last to disable conflicting rules)
extends: [
eslintJs.configs.recommended,
tseslint.configs.recommended,
eslintReact.configs["recommended-typescript"],
eslintConfigPrettier,
],

// Configure language/parsing options
languageOptions: {
ecmaVersion: 'latest',
ecmaVersion: 'latest', // Allow modern JS syntax
globals: {
...globals.browser
...globals.browser, // Allow browser globals like `window`
},
parser: tseslint.parser, // Your existing parser
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname
}
},
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin
},
settings: {
react: {
version: 'detect'
}
tsconfigRootDir: import.meta.dirname,
},
},

// TODO: See if some of these could be fixed
rules: {
...reactPlugin.configs.recommended.rules,
...reactPlugin.configs['jsx-runtime'].rules,
...reactHooksPlugin.configs.recommended.rules
}
"@eslint-react/dom-no-dangerously-set-innerhtml": "off",
"@eslint-react/exhaustive-deps": "off",
"@eslint-react/set-state-in-effect": "off",
},
},
eslintConfigPrettier
)
);
7 changes: 3 additions & 4 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,12 @@
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"jsdom": "^28.1.0",
"eslint": "^9.17.0",
"eslint": "^10.2.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-react": "^7.37.3",
"eslint-plugin-react-hooks": "^7.0.1",
"@eslint-react/eslint-plugin": "^4.2.3",
"globals": "^17.4.0",
"prettier": "^3.8.1",
"typescript-eslint": "^8.57.0",
"typescript-eslint": "^8.58.1",
"vitest": "^4.0.18"
}
}
10 changes: 6 additions & 4 deletions web/src/components/DocumentControlButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ export default function DocumentControlButtons(props: Props): React.JSX.Element
<div className={styles['share-modal-copy-container']}>
<button
className={styles['share-modal-copy']}
onClick={() => {
void (async () => {
await navigator.clipboard.writeText(props.getShareUrl({ useLatest: shareModalUseLatest, hideUi: shareModalHideUi }))
})()
onClick={async () => {
const url = props.getShareUrl({
useLatest: shareModalUseLatest,
hideUi: shareModalHideUi
});
await navigator.clipboard.writeText(url);
}}
>
Copy
Expand Down
1 change: 0 additions & 1 deletion web/src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export default function SearchBar(props: Props): React.JSX.Element {
updateSearch(q)
}
setShowFavourites(props.showFavourites)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.showFavourites]);

const onFavourites = (show: boolean): void => {
Expand Down
6 changes: 3 additions & 3 deletions web/src/data-providers/ConfigDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We need any, because we don't know the type of the children
*/

import { createContext, useContext, useEffect, useState, JSX } from 'react'
import { createContext, use, useEffect, useState, JSX } from 'react'

export interface Config {
headerHTML?: string
Expand Down Expand Up @@ -31,7 +31,7 @@ export const ConfigDataProvider = ({ children }: any): JSX.Element => {
})()
}, [])

return <Context.Provider value={config}>{children}</Context.Provider>
return <Context value={config}>{children}</Context>
}

export const useConfig = (): Config => useContext(Context)
export const useConfig = (): Config => use(Context)
10 changes: 4 additions & 6 deletions web/src/data-providers/MessageBannerProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We need any, because we don't know the type of the children
*/

import React, { useState, useCallback, useContext, JSX } from 'react'
import React, { useState, useCallback, use, JSX } from 'react'
import Banner from '../components/InfoBanner'

export interface Message {
Expand Down Expand Up @@ -57,7 +57,6 @@ export function MessageBannerProvider({ children }: any): JSX.Element {
}, message.showMs)

setLastTimeout(newTimeout)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

const clearMessages = useCallback(() => {
Expand All @@ -70,15 +69,14 @@ export function MessageBannerProvider({ children }: any): JSX.Element {
type: 'success',
showMs: 6000
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return (
<Context.Provider value={{ showMessage, clearMessages }}>
<Context value={{ showMessage, clearMessages }}>
<Banner message={message} />
{children}
</Context.Provider>
</Context>
)
}

export const useMessageBanner = (): MessageBannerState => useContext(Context)
export const useMessageBanner = (): MessageBannerState => use(Context)
7 changes: 3 additions & 4 deletions web/src/data-providers/ProjectDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We need any, because we don't know the type of the children
*/

import React, { createContext, useContext, useEffect, useState, JSX } from 'react'
import React, { createContext, use, useEffect, useState, JSX } from 'react'
import { type Project } from '../models/ProjectsResponse'
import type ProjectsResponse from '../models/ProjectsResponse'
import { useMessageBanner } from './MessageBannerProvider'
Expand Down Expand Up @@ -75,10 +75,9 @@ export function ProjectDataProvider({ children }: any): JSX.Element {

useEffect(() => {
loadData()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return <Context.Provider value={state}>{children}</Context.Provider>
return <Context value={state}>{children}</Context>
}

export const useProjects = (): ProjectState => useContext(Context)
export const useProjects = (): ProjectState => use(Context)
7 changes: 3 additions & 4 deletions web/src/data-providers/SearchProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We need any, because we don't know the type of the children
*/

import React, { createContext, useContext, useEffect, useState, JSX } from 'react'
import React, { createContext, use, useEffect, useState, JSX } from 'react'
import { type Project } from '../models/ProjectsResponse'
import { useProjects } from './ProjectDataProvider'
import Fuse from 'fuse.js'
Expand Down Expand Up @@ -66,10 +66,9 @@ export function SearchProvider({ children }: any): JSX.Element {
filteredProjects: filterProjects(''),
setQuery
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [projects])

return <Context.Provider value={state}>{children}</Context.Provider>
return <Context value={state}>{children}</Context>
}

export const useSearch = (): SearchState => useContext(Context)
export const useSearch = (): SearchState => use(Context)
7 changes: 3 additions & 4 deletions web/src/data-providers/StatsDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We need any, because we don't know the type of the children
*/

import { createContext, useContext, useEffect, useState, JSX } from 'react'
import { createContext, use, useEffect, useState, JSX } from 'react'
import { useMessageBanner } from './MessageBannerProvider'


Expand Down Expand Up @@ -77,10 +77,9 @@ export function StatsDataProvider({ children }: any): JSX.Element {

useEffect(() => {
loadData()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

return <Context.Provider value={state}>{children}</Context.Provider>
return <Context value={state}>{children}</Context>
}

export const useStats = (): StatsState => useContext(Context)
export const useStats = (): StatsState => use(Context)
12 changes: 6 additions & 6 deletions web/src/pages/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ export default function Claim(): JSX.Element {
<button
type="submit"
disabled={token !== ''}
onClick={() => {
;(async () => {
await claim()
})().catch((e) => {
console.error(e)
})
onClick={async () => {
try {
await claim();
} catch (e) {
console.error(e);
}
}}
>
Claim
Expand Down
1 change: 0 additions & 1 deletion web/src/pages/Delete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export default function Delete(): JSX.Element {
}

setVersions(projects?.find((p) => p.name === project)?.versions ?? [])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [project])

const validate = (
Expand Down
32 changes: 15 additions & 17 deletions web/src/pages/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export default function Docs(): JSX.Element {
const [projectLoading, setProjectLoading] = useState<boolean>(true)
const [notFound, setNotFound] = useState<boolean>(false)

const page = useRef(params['*'] ?? '')
const hash = useRef(location.hash)
const pageRef = useRef(params['*'] ?? '')
const hashRef = useRef(location.hash)

const [project, setProject] = useState<string>(params.project ?? '')
const [version, setVersion] = useState<string>(params.version ?? 'latest')
Expand All @@ -39,10 +39,9 @@ export default function Docs(): JSX.Element {
return ProjectRepository.getProjectDocsURL(
project,
displayVersion.name,
page.current,
hash.current
pageRef.current,
hashRef.current
)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [project, displayVersion, iframeUpdateTrigger])

useEffect(() => {
Expand All @@ -68,11 +67,11 @@ export default function Docs(): JSX.Element {
}

const getShareUrl = (options: { useLatest: boolean, hideUi: boolean }): string => {
return buildBrowserUrl(project, options.useLatest ? 'latest' : displayVersion?.name ?? 'latest', page.current, hash.current, options.hideUi)
return buildBrowserUrl(project, options.useLatest ? 'latest' : displayVersion?.name ?? 'latest', pageRef.current, hashRef.current, options.hideUi)
}

const updateUrl = (newProject: string, newVersion: string, hideUi: boolean): void => {
window.history.pushState(null, '', buildBrowserUrl(newProject, newVersion, page.current, hash.current, hideUi))
window.history.pushState(null, '', buildBrowserUrl(newProject, newVersion, pageRef.current, hashRef.current, hideUi))
}

useEffect(() => {
Expand Down Expand Up @@ -115,19 +114,19 @@ export default function Docs(): JSX.Element {
if (title != null && title !== document.title) {
updateTitle(title)
}
if (urlPage === page.current) {
if (urlPage === pageRef.current) {
return
}
page.current = urlPage
hash.current = urlHash
pageRef.current = urlPage
hashRef.current = urlHash
updateUrl(project, version, hideUi)
}

const iFrameHashChanged = (newHash: string): void => {
if (newHash === hash.current) {
if (newHash === hashRef.current) {
return
}
hash.current = newHash
hashRef.current = newHash
updateUrl(project, version, hideUi)
}

Expand Down Expand Up @@ -156,15 +155,14 @@ export default function Docs(): JSX.Element {
setVersion(urlVersion)
setHideUi(urlHideUi)

if (urlPage !== page.current) {
page.current = urlPage
if (urlPage !== pageRef.current) {
pageRef.current = urlPage
setIframeUpdateTrigger((v) => v + 1)
}
if (urlHash !== hash.current) {
hash.current = urlHash
if (urlHash !== hashRef.current) {
hashRef.current = urlHash
setIframeUpdateTrigger((v) => v + 1)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location])

if (projectLoading) {
Expand Down
1 change: 0 additions & 1 deletion web/src/pages/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export default function Home(): JSX.Element {

useEffect(() => {
updateFavorites()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [projects])

if (loadingFailed || statsLoadingFailed) {
Expand Down
Loading
Loading