diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 62ee6ff0..db3b6ec3 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,9 @@ jobs: - name: Lint run: npm run lint + - name: TypeScript Type Check + run: npm run type-check + - name: Run Vitest Tests run: npm run test:vi diff --git a/package.json b/package.json index 3974d37a..594d9ca2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "test:cy": "cypress run --component --browser chrome", "test:cy:open": "cypress open --component --browser chrome", "generate-graphql-types": "graphql-codegen --config graphql.config.yaml", - "generate-graphql-types:watch": "graphql-codegen --config graphql.config.yaml --watch" + "generate-graphql-types:watch": "graphql-codegen --config graphql.config.yaml --watch", + "type-check": "tsc --noEmit" }, "dependencies": { "@apollo/client": "3.14.0", diff --git a/src/components/ControlPlane/GitRepositories.tsx b/src/components/ControlPlane/GitRepositories.tsx index e12ec596..d33865b5 100644 --- a/src/components/ControlPlane/GitRepositories.tsx +++ b/src/components/ControlPlane/GitRepositories.tsx @@ -23,10 +23,6 @@ export type GitRepoItem = GitReposResponse['items'][0] & { metadata: GitReposResponse['items'][0]['metadata'] & { namespace?: string }; }; -interface CellRow { - original: T; -} - export function GitRepositories() { const { data, error, isLoading } = useApiResource(FluxRequest); //404 if component not enabled const { t } = useTranslation(); @@ -83,7 +79,7 @@ export function GitRepositories() { width: 125, hAlign: 'Center', Filter: ({ column }) => , - Cell: ({ row }: { row: CellRow }) => + Cell: ({ row }) => row.original?.isReady != null ? ( }) => ( - - ), + Cell: ({ row }) => , }, { Header: t('ManagedResources.actionColumnHeader'), @@ -110,7 +104,7 @@ export function GitRepositories() { width: 60, disableFilters: true, accessor: 'actions', - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const item = row.original?.item; if (!item) return undefined; const actions: ActionItem[] = [ diff --git a/src/components/ControlPlane/Kustomizations.tsx b/src/components/ControlPlane/Kustomizations.tsx index 0cc69768..aeb9fec1 100644 --- a/src/components/ControlPlane/Kustomizations.tsx +++ b/src/components/ControlPlane/Kustomizations.tsx @@ -30,10 +30,6 @@ export function Kustomizations() { const errorDialogRef = useRef(null); const handlePatch = useHandleResourcePatch(errorDialogRef); - interface CellRow { - original: T; - } - type FluxRow = { name: string; created: string; @@ -78,7 +74,7 @@ export function Kustomizations() { width: 125, hAlign: 'Center', Filter: ({ column }) => , - Cell: ({ row }: { row: CellRow }) => + Cell: ({ row }) => row.original?.isReady != null ? ( }) => ( - - ), + Cell: ({ row }) => , }, { Header: t('ManagedResources.actionColumnHeader'), @@ -105,7 +99,7 @@ export function Kustomizations() { width: 60, disableFilters: true, accessor: 'actions', - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const item = row.original?.item; if (!item) return undefined; const actions: ActionItem[] = [ diff --git a/src/components/ControlPlane/MCPHealthPopoverButton.tsx b/src/components/ControlPlane/MCPHealthPopoverButton.tsx index 8ed4d7e7..389c7623 100644 --- a/src/components/ControlPlane/MCPHealthPopoverButton.tsx +++ b/src/components/ControlPlane/MCPHealthPopoverButton.tsx @@ -11,7 +11,7 @@ import { import { AnalyticalTableColumnDefinition } from '@ui5/webcomponents-react/wrappers'; import PopoverPlacement from '@ui5/webcomponents/dist/types/PopoverPlacement.js'; import '@ui5/webcomponents-icons/dist/copy'; -import { JSX, useRef, useState, ReactNode } from 'react'; +import { JSX, useRef, useState } from 'react'; import type { ButtonClickEventDetail } from '@ui5/webcomponents/dist/Button.js'; import { ControlPlaneStatusType, @@ -25,17 +25,6 @@ import { useLink } from '../../lib/shared/useLink.ts'; import TooltipCell from '../Shared/TooltipCell.tsx'; import type { Ui5CustomEvent } from '@ui5/webcomponents-react-base'; -interface CellData { - cell: { - value: ReactNode; - }; - row: { - original: T; - [key: string]: unknown; - }; - [key: string]: unknown; -} - type MCPHealthPopoverButtonProps = { mcpStatus: ControlPlaneStatusType | undefined; projectName: string; @@ -99,7 +88,7 @@ const MCPHealthPopoverButton = ({ mcpStatus, projectName, workspaceName, mcpName Header: t('MCPHealthPopoverButton.statusHeader'), accessor: 'status', width: 50, - Cell: (instance: CellData) => { + Cell: (instance) => { const isReady = instance.cell.value === 'True'; return ( ) => { + Cell: (instance) => { return {instance.cell.value}; }, }, @@ -121,7 +110,7 @@ const MCPHealthPopoverButton = ({ mcpStatus, projectName, workspaceName, mcpName Header: t('MCPHealthPopoverButton.messageHeader'), accessor: 'message', width: 350, - Cell: (instance: CellData) => { + Cell: (instance) => { return {instance.cell.value}; }, }, @@ -129,7 +118,7 @@ const MCPHealthPopoverButton = ({ mcpStatus, projectName, workspaceName, mcpName Header: t('MCPHealthPopoverButton.reasonHeader'), accessor: 'reason', width: 100, - Cell: (instance: CellData) => { + Cell: (instance) => { return {instance.cell.value}; }, }, @@ -137,7 +126,7 @@ const MCPHealthPopoverButton = ({ mcpStatus, projectName, workspaceName, mcpName Header: t('MCPHealthPopoverButton.transitionHeader'), accessor: 'lastTransitionTime', width: 125, - Cell: (instance: CellData) => { + Cell: (instance) => { const rawDate = instance.cell.value; const date = new Date(rawDate as string); return ( diff --git a/src/components/ControlPlane/ManagedResources.tsx b/src/components/ControlPlane/ManagedResources.tsx index 80a26ddc..bebc8c54 100644 --- a/src/components/ControlPlane/ManagedResources.tsx +++ b/src/components/ControlPlane/ManagedResources.tsx @@ -40,9 +40,6 @@ interface StatusFilterColumn { filterValue?: string; setFilter?: (value?: string) => void; } -interface CellRow { - original: T; -} type ResourceRow = { kind: string; @@ -130,7 +127,7 @@ export function ManagedResources() { hAlign: 'Center', width: 125, Filter: ({ column }: { column: StatusFilterColumn }) => , - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const { original } = row; return original?.synced != null ? ( , - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const { original } = row; return original?.ready != null ? ( }) => { + Cell: ({ row }) => { const { original } = row; return original?.item ? ( @@ -180,7 +177,7 @@ export function ManagedResources() { hAlign: 'Center', width: 60, disableFilters: true, - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const { original } = row; const item = original?.item; if (!item) return undefined; diff --git a/src/components/ControlPlane/Providers.tsx b/src/components/ControlPlane/Providers.tsx index 977a9537..0ed0fd6b 100644 --- a/src/components/ControlPlane/Providers.tsx +++ b/src/components/ControlPlane/Providers.tsx @@ -24,15 +24,6 @@ import StatusFilter from '../Shared/StatusFilter/StatusFilter.tsx'; import { ResourceStatusCell } from '../Shared/ResourceStatusCell.tsx'; import { Resource } from '../../utils/removeManagedFieldsAndFilterData.ts'; -interface CellData { - cell: { - value: T | null; - row: { - original?: ProvidersRow; - }; - }; -} - type ProvidersRow = { name: string; version: string; @@ -78,14 +69,14 @@ export function Providers() { width: 125, Filter: ({ column }) => , filter: 'equals', - Cell: (cellData: CellData) => + Cell: (cellData) => cellData.cell.row.original?.installed != null ? ( ) : null, }, @@ -96,14 +87,14 @@ export function Providers() { width: 125, Filter: ({ column }) => , filter: 'equals', - Cell: (cellData: CellData) => + Cell: (cellData) => cellData.cell.row.original?.installed != null ? ( ) : null, }, @@ -113,7 +104,7 @@ export function Providers() { width: 75, accessor: 'yaml', disableFilters: true, - Cell: (cellData: CellData) => ( + Cell: (cellData) => ( ), }, diff --git a/src/components/ControlPlane/ProvidersConfig.tsx b/src/components/ControlPlane/ProvidersConfig.tsx index 524eaaba..68d3705f 100644 --- a/src/components/ControlPlane/ProvidersConfig.tsx +++ b/src/components/ControlPlane/ProvidersConfig.tsx @@ -32,10 +32,6 @@ type Rows = { resource: ProviderConfigItem; }; -interface CellRow { - original: T; -} - export function ProvidersConfig() { const { t } = useTranslation(); const { openInAside } = useSplitter(); @@ -104,7 +100,7 @@ export function ProvidersConfig() { width: 75, accessor: 'yaml', disableFilters: true, - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const item = row.original?.resource; return item ? : undefined; }, @@ -115,7 +111,7 @@ export function ProvidersConfig() { width: 60, disableFilters: true, accessor: 'actions', - Cell: ({ row }: { row: CellRow }) => { + Cell: ({ row }) => { const item = row.original?.resource; if (!item) return undefined; const actions: ActionItem[] = [ diff --git a/src/components/ControlPlanes/List/ControlPlaneListWorkspaceGridTile.tsx b/src/components/ControlPlanes/List/ControlPlaneListWorkspaceGridTile.tsx index b3ecef31..cf97ef31 100644 --- a/src/components/ControlPlanes/List/ControlPlaneListWorkspaceGridTile.tsx +++ b/src/components/ControlPlanes/List/ControlPlaneListWorkspaceGridTile.tsx @@ -52,7 +52,7 @@ export function ControlPlaneListWorkspaceGridTile({ projectName, workspace }: Pr const errorView = createErrorView(cpsError); const shouldCollapsePanel = !!errorView; - function createErrorView(error: APIError) { + function createErrorView(error: APIError | undefined) { if (error) { if (error.status === 403) { return ( diff --git a/src/components/Core/FeedbackButton.tsx b/src/components/Core/FeedbackButton.tsx index 1fc3d8aa..d623e129 100644 --- a/src/components/Core/FeedbackButton.tsx +++ b/src/components/Core/FeedbackButton.tsx @@ -17,6 +17,7 @@ import { Dispatch, RefObject, SetStateAction, useRef, useState } from 'react'; import { useAuthOnboarding } from '../../spaces/onboarding/auth/AuthContextOnboarding'; import { useTranslation } from 'react-i18next'; import { ButtonClickEventDetail } from '@ui5/webcomponents/dist/Button.js'; +import { TextAreaInputEventDetail } from '@ui5/webcomponents/dist/TextArea.js'; import PopoverPlacement from '@ui5/webcomponents/dist/types/PopoverPlacement.js'; import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js'; @@ -35,7 +36,7 @@ export function FeedbackButton() { setFeedbackPopoverOpen(!feedbackPopoverOpen); }; - const onFeedbackMessageChange = (event: Ui5CustomEvent) => { + const onFeedbackMessageChange = (event: Ui5CustomEvent) => { const newValue = event.target.value; setFeedbackMessage(newValue); }; @@ -98,15 +99,7 @@ const FeedbackPopover = ({ rating: number; onFeedbackSent: () => void; feedbackMessage: string; - onFeedbackMessageChange: ( - event: Ui5CustomEvent< - TextAreaDomRef, - { - value: string; - previousValue: string; - } - >, - ) => void; + onFeedbackMessageChange: (event: Ui5CustomEvent) => void; feedbackSent: boolean; }) => { const { t } = useTranslation(); diff --git a/src/components/Members/ImportMembersDialog.tsx b/src/components/Members/ImportMembersDialog.tsx index 0128976c..5d751d25 100644 --- a/src/components/Members/ImportMembersDialog.tsx +++ b/src/components/Members/ImportMembersDialog.tsx @@ -91,8 +91,9 @@ export const ImportMembersDialog: FC = ({ Header: t('MemberTable.columnTypeHeader'), accessor: 'kind', width: 145, - Cell: (instance: { cell: { row: { original: TableRow } } }) => { - const kind = ACCOUNT_TYPES.find(({ value }) => value === instance.cell.row.original.kind); + Cell: (instance) => { + const original = instance.cell.row.original as TableRow; + const kind = ACCOUNT_TYPES.find(({ value }) => value === original.kind); return ( diff --git a/src/components/Members/MemberTable.tsx b/src/components/Members/MemberTable.tsx index d77131f6..1a62131f 100644 --- a/src/components/Members/MemberTable.tsx +++ b/src/components/Members/MemberTable.tsx @@ -22,14 +22,6 @@ type MemberTableProps = { requireAtLeastOneMember: boolean; }; -type CellInstance = { - cell: { - row: { - original: MemberTableRow; - }; - }; -}; - export const MemberTable: FC = ({ members, onDeleteMember, @@ -49,7 +41,7 @@ export const MemberTable: FC = ({ Header: t('MemberTable.columnTypeHeader'), accessor: 'kind', width: 145, - Cell: (instance: CellInstance) => { + Cell: (instance) => { const kind = ACCOUNT_TYPES.find(({ value }) => value === instance.cell.row.original.kind); return ( @@ -75,13 +67,13 @@ export const MemberTable: FC = ({ Header: '', id: 'edit', width: 100, - Cell: (instance: CellInstance) => ( + Cell: (instance) => (