diff --git a/.storybook/main.js b/.storybook/main.js index 4b0260b35..c645ef0cd 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -52,4 +52,7 @@ module.exports = { builder: 'webpack5', }, staticDirs: ['./public'], + typescript: { + reactDocgen: 'react-docgen-typescript-plugin', + }, }; diff --git a/app/portainer/helpers/promise-utils.ts b/app/portainer/helpers/promise-utils.ts index 5ef54ba68..b71899f77 100644 --- a/app/portainer/helpers/promise-utils.ts +++ b/app/portainer/helpers/promise-utils.ts @@ -3,10 +3,10 @@ * * @param promises a list of functions that return promises */ -export function promiseSequence(promises: (() => Promise)[]) { +export function promiseSequence(promises: (() => Promise)[]) { return promises.reduce( - (promise, nextPromise) => promise.then(() => nextPromise()), - Promise.resolve(undefined as unknown as T) + (promise, nextPromise) => promise.then(nextPromise), + Promise.resolve(undefined as unknown) ); } diff --git a/app/react-tools/react-query.ts b/app/react-tools/react-query.ts index 26db442ed..5da82bfff 100644 --- a/app/react-tools/react-query.ts +++ b/app/react-tools/react-query.ts @@ -64,7 +64,7 @@ function mergeOptions(options: T[]) { ...acc, ...option, }), - {} + {} as T ); } diff --git a/app/react-tools/react2angular.tsx b/app/react-tools/react2angular.tsx index 76e7b3355..ae1814803 100644 --- a/app/react-tools/react2angular.tsx +++ b/app/react-tools/react2angular.tsx @@ -35,7 +35,7 @@ type PropNames = Exclude; * if the second parameter has any ts errors check that the component has the correct props */ export function react2angular[]>( - Component: React.ComponentType, + Component: React.ComponentType, propNames: U & ([PropNames] extends [U[number]] ? unknown : PropNames) ): IComponentOptions & { name: string } { const bindings = Object.fromEntries(propNames.map((key) => [key, '<'])); @@ -61,7 +61,7 @@ export function react2angular[]>( ReactDOM.render( {/* eslint-disable-next-line react/jsx-props-no-spreading */} - + , el diff --git a/app/react-tools/withCurrentUser.tsx b/app/react-tools/withCurrentUser.tsx index bd0daf42f..41a48f1a7 100644 --- a/app/react-tools/withCurrentUser.tsx +++ b/app/react-tools/withCurrentUser.tsx @@ -5,13 +5,13 @@ import { UserProvider } from '@/react/hooks/useUser'; import { withReactQuery } from './withReactQuery'; export function withCurrentUser( - WrappedComponent: ComponentType -): ComponentType { + WrappedComponent: ComponentType +): ComponentType { // Try to create a nice displayName for React Dev Tools. const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { return ( diff --git a/app/react-tools/withI18nSuspense.tsx b/app/react-tools/withI18nSuspense.tsx index b0e12304e..c704149bc 100644 --- a/app/react-tools/withI18nSuspense.tsx +++ b/app/react-tools/withI18nSuspense.tsx @@ -7,7 +7,7 @@ export function withI18nSuspense( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { return ( diff --git a/app/react-tools/withReactQuery.tsx b/app/react-tools/withReactQuery.tsx index 1cc326c4a..b73091ff7 100644 --- a/app/react-tools/withReactQuery.tsx +++ b/app/react-tools/withReactQuery.tsx @@ -4,14 +4,14 @@ import { QueryClientProvider } from 'react-query'; import { queryClient as defaultQueryClient } from './react-query'; export function withReactQuery( - WrappedComponent: ComponentType, + WrappedComponent: ComponentType, queryClient = defaultQueryClient -): ComponentType { +): ComponentType { // Try to create a nice displayName for React Dev Tools. const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { return ( diff --git a/app/react-tools/withUIRouter.tsx b/app/react-tools/withUIRouter.tsx index b85b0c3a3..3046d9847 100644 --- a/app/react-tools/withUIRouter.tsx +++ b/app/react-tools/withUIRouter.tsx @@ -8,7 +8,7 @@ export function withUIRouter( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { return ( diff --git a/app/react/components/datatables/types.ts b/app/react/components/datatables/types.ts index 0c396f1b1..f2e107b7a 100644 --- a/app/react/components/datatables/types.ts +++ b/app/react/components/datatables/types.ts @@ -13,12 +13,12 @@ export type ZustandSetFunc = ( replace?: boolean | undefined ) => void; -export function paginationSettings( - set: ZustandSetFunc +export function paginationSettings( + set: ZustandSetFunc ): PaginationTableSettings { return { pageSize: 10, - setPageSize: (pageSize: number) => set({ pageSize }), + setPageSize: (pageSize: number) => set((s) => ({ ...s, pageSize })), }; } @@ -27,8 +27,8 @@ export interface SortableTableSettings { setSortBy: (id: string, desc: boolean) => void; } -export function sortableSettings( - set: ZustandSetFunc, +export function sortableSettings( + set: ZustandSetFunc, initialSortBy: string | { id: string; desc: boolean } ): SortableTableSettings { return { @@ -36,7 +36,8 @@ export function sortableSettings( typeof initialSortBy === 'string' ? { id: initialSortBy, desc: false } : initialSortBy, - setSortBy: (id: string, desc: boolean) => set({ sortBy: { id, desc } }), + setSortBy: (id: string, desc: boolean) => + set((s) => ({ ...s, sortBy: { id, desc } })), }; } @@ -45,12 +46,13 @@ export interface SettableColumnsTableSettings { setHiddenColumns: (hiddenColumns: string[]) => void; } -export function hiddenColumnsSettings( - set: ZustandSetFunc +export function hiddenColumnsSettings( + set: ZustandSetFunc ): SettableColumnsTableSettings { return { hiddenColumns: [], - setHiddenColumns: (hiddenColumns: string[]) => set({ hiddenColumns }), + setHiddenColumns: (hiddenColumns: string[]) => + set((s) => ({ ...s, hiddenColumns })), }; } @@ -59,12 +61,13 @@ export interface RefreshableTableSettings { setAutoRefreshRate: (autoRefreshRate: number) => void; } -export function refreshableSettings( - set: ZustandSetFunc +export function refreshableSettings( + set: ZustandSetFunc ): RefreshableTableSettings { return { autoRefreshRate: 0, - setAutoRefreshRate: (autoRefreshRate: number) => set({ autoRefreshRate }), + setAutoRefreshRate: (autoRefreshRate: number) => + set((s) => ({ ...s, autoRefreshRate })), }; } diff --git a/app/react/hooks/useLimitToBE.tsx b/app/react/hooks/useLimitToBE.tsx index c5f70a646..8478eb3df 100644 --- a/app/react/hooks/useLimitToBE.tsx +++ b/app/react/hooks/useLimitToBE.tsx @@ -21,7 +21,7 @@ export function withLimitToBE( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { const isLimitedToBE = useLimitToBE(defaultPath); if (isLimitedToBE) { diff --git a/app/react/hooks/withHideOnExtension.tsx b/app/react/hooks/withHideOnExtension.tsx index 7adad5bdc..7618870d1 100644 --- a/app/react/hooks/withHideOnExtension.tsx +++ b/app/react/hooks/withHideOnExtension.tsx @@ -10,7 +10,7 @@ export function withHideOnExtension( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { if (window.ddExtension) { return null; } diff --git a/app/react/kubernetes/datatables/DefaultDatatableSettings.tsx b/app/react/kubernetes/datatables/DefaultDatatableSettings.tsx index 260379178..775f0d38c 100644 --- a/app/react/kubernetes/datatables/DefaultDatatableSettings.tsx +++ b/app/react/kubernetes/datatables/DefaultDatatableSettings.tsx @@ -16,15 +16,16 @@ export interface TableSettings RefreshableTableSettings, SystemResourcesTableSettings {} -export function systemResourcesSettings( - set: ZustandSetFunc +export function systemResourcesSettings( + set: ZustandSetFunc ): SystemResourcesTableSettings { return { showSystemResources: false, setShowSystemResources(showSystemResources: boolean) { - set({ + set((s) => ({ + ...s, showSystemResources, - }); + })); }, }; } diff --git a/app/react/portainer/feature-flags/withEdition.tsx b/app/react/portainer/feature-flags/withEdition.tsx index 45e05dfc2..3572ca35e 100644 --- a/app/react/portainer/feature-flags/withEdition.tsx +++ b/app/react/portainer/feature-flags/withEdition.tsx @@ -8,7 +8,7 @@ export function withEdition( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { if (process.env.PORTAINER_EDITION !== edition) { return null; } diff --git a/app/react/portainer/feature-flags/withFeatureFlag.tsx b/app/react/portainer/feature-flags/withFeatureFlag.tsx index a3c0e0c7f..a41b21b4a 100644 --- a/app/react/portainer/feature-flags/withFeatureFlag.tsx +++ b/app/react/portainer/feature-flags/withFeatureFlag.tsx @@ -10,7 +10,7 @@ export function withFeatureFlag( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { const featureFlagQuery = useFeatureFlag(flag); if (!featureFlagQuery.data) { diff --git a/app/react/test-utils/withUserProvider.tsx b/app/react/test-utils/withUserProvider.tsx index 9b42e0b99..e425419a7 100644 --- a/app/react/test-utils/withUserProvider.tsx +++ b/app/react/test-utils/withUserProvider.tsx @@ -21,7 +21,7 @@ export function withUserProvider( const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; - function WrapperComponent(props: T) { + function WrapperComponent(props: T & JSX.IntrinsicAttributes) { const state = useMemo(() => ({ user }), []); return ( diff --git a/package.json b/package.json index f5921e0ea..c60b13a3a 100644 --- a/package.json +++ b/package.json @@ -199,6 +199,7 @@ "postcss-loader": "^6.2.1", "prettier": "^2.8.1", "prettier-plugin-tailwindcss": "^0.2.1", + "react-docgen-typescript-plugin": "^1.0.5", "react-test-renderer": "^17.0.2", "source-map-loader": "^3.0.0", "speed-measure-webpack-plugin": "^1.5.0", @@ -207,7 +208,7 @@ "swagger2openapi": "^7.0.8", "tailwindcss": "^3.1.4", "tsconfig-paths-webpack-plugin": "^3.5.2", - "typescript": "^4.5.2", + "typescript": "^5.0.4", "webpack": "^5.65.0", "webpack-build-notifier": "^2.3.0", "webpack-bundle-analyzer": "^4.5.0", diff --git a/yarn.lock b/yarn.lock index efe293cbc..a80fdda8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15016,7 +15016,20 @@ react-datetime-picker@^4.2.0: react-fit "^1.4.0" react-time-picker "^5.2.0" -react-docgen-typescript@^2.1.1: +react-docgen-typescript-plugin@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.5.tgz#015d8350b06a450d98000080d8ae5eac475e9f79" + integrity sha512-Ds6s2ioyIlH45XSfEVMNwRcDkzuff3xQCPxDFOzTc8GEshy+hksas8RYlmV4JEQREI+OGEGybhMCJk3vFbQZNQ== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + find-cache-dir "^3.3.1" + flat-cache "^3.0.4" + micromatch "^4.0.2" + react-docgen-typescript "^2.2.2" + tslib "^2.0.0" + +react-docgen-typescript@^2.1.1, react-docgen-typescript@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== @@ -17381,10 +17394,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^4.5.2: - version "4.5.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3" - integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA== +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== uglify-js@3.4.x: version "3.4.10"