chore: pass CI (#42635)

* chore: eslint on icons

* chore: eslint spacer element

* chore: remove more eslint

* fix: existing lint issues

* fix: misnamed import

* fix: client now builds!

* fix: tsc errors

* fix: more linting issues
This commit is contained in:
Nicholas Carrigan (he/him)
2021-06-25 14:24:33 -07:00
committed by Mrugesh Mohapatra
parent d87b472ee7
commit 592a2846d3
39 changed files with 75 additions and 75 deletions

View File

@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from 'react';
import { useTranslation } from 'react-i18next';

View File

@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from 'react';
function CertificationIcon(): JSX.Element {

View File

@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React, { Fragment } from 'react';
import { useTranslation } from 'react-i18next';

View File

@ -1,17 +1,21 @@
import React, { Fragment } from 'react';
import { useTranslation } from 'react-i18next';
// eslint-disable-next-line
function Spacer(props: any): JSX.Element {
interface SpacerPropTypes {
style: Record<string, unknown>;
}
function Spacer(props: SpacerPropTypes): JSX.Element {
const { t } = useTranslation();
props.style = { paddingTop: '5', ...props.style };
return (
<Fragment>
<span className='sr-only'>{t('icons.spacer')}</span>
<svg
className='tick'
height='50'
paddingTop='5'
viewBox='-10 -45 200 200'
width='50'
xmlns='http://www.w3.org/2000/svg'

View File

@ -1,4 +1,3 @@
/* eslint-disable react/jsx-sort-props */
import React, { useEffect, useState } from 'react';
import { bindActionCreators, Dispatch } from 'redux';
import { connect } from 'react-redux';
@ -7,7 +6,6 @@ import { Grid, Row, Col, Image, Button } from '@freecodecamp/react-bootstrap';
import ShowProjectLinks from './show-project-links';
import FreeCodeCampLogo from '../assets/icons/FreeCodeCamp-logo';
// eslint-disable-next-line max-len
import DonateForm from '../components/Donation/DonateForm';
import { Trans, useTranslation } from 'react-i18next';
@ -27,8 +25,6 @@ import { createFlashMessage } from '../components/Flash/redux';
import standardErrorMessage from '../utils/standardErrorMessage';
import reallyWeirdErrorMessage from '../utils/reallyWeirdErrorMessage';
import { langCodes } from '../../../config/i18n/all-langs';
// eslint-disable-next-line
// @ts-ignore
import envData from '../../../config/env.json';
import RedirectHome from '../components/RedirectHome';
@ -145,7 +141,6 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
} = props;
if (!signedInUserName || signedInUserName !== username) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (isEmpty(user) && username) {
fetchProfileForUser(username);
}
@ -272,8 +267,8 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
<Row>
<Col md={8} mdOffset={2} xs={12}>
<DonateForm
handleProcessing={handleProcessing}
defaultTheme='default'
handleProcessing={handleProcessing}
isMinimalForm={true}
/>
</Col>
@ -294,10 +289,10 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
block={true}
bsSize='lg'
bsStyle='primary'
target='_blank'
href={`https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&name=${certTitle}&organizationId=4831032&issueYear=${certYear}&issueMonth=${
certMonth + 1
}&certUrl=${certURL}`}
target='_blank'
>
{t('profile.add-linkedin')}
</Button>
@ -306,11 +301,11 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
block={true}
bsSize='lg'
bsStyle='primary'
target='_blank'
href={`https://twitter.com/intent/tweet?text=${t('profile.tweet', {
certTitle: certTitle,
certURL: certURL
})}`}
target='_blank'
>
{t('profile.add-twitter')}
</Button>
@ -331,7 +326,7 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
</div>
</Col>
<Col md={7} sm={12}>
<div data-cy='issue-date' className='issue-date'>
<div className='issue-date' data-cy='issue-date'>
{t('certification.issued')}&nbsp;
<strong>
{certDate.toLocaleString([localeCode, 'en-US'], {
@ -346,7 +341,7 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
<main className='information'>
<div className='information-container'>
<Trans title={certTitle} i18nKey='certification.fulltext'>
<Trans i18nKey='certification.fulltext' title={certTitle}>
<h3>placeholder</h3>
<h1>
<strong>{{ user: displayName }}</strong>
@ -383,7 +378,7 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
<Spacer size={2} />
{signedInUserName === username ? shareCertBtns : ''}
<Spacer size={2} />
<ShowProjectLinks user={user} name={displayName} certName={certTitle} />
<ShowProjectLinks certName={certTitle} name={displayName} user={user} />
<Spacer size={2} />
</Grid>
);
@ -391,4 +386,8 @@ const ShowCertification = (props: IShowCertificationProps): JSX.Element => {
ShowCertification.displayName = 'ShowCertification';
export default connect(mapStateToProps, mapDispatchToProps)(ShowCertification);
export default connect(
mapStateToProps,
mapDispatchToProps
// eslint-disable-next-line @typescript-eslint/no-explicit-any
)(ShowCertification as any);

View File

@ -63,7 +63,6 @@ const mapDispatchToProps: {
class ShowProfileOrFourOhFour extends Component<IShowProfileOrFourOhFourProps> {
componentDidMount() {
const { requestedUser, maybeUser, fetchProfileForUser } = this.props;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (isEmpty(requestedUser)) {
fetchProfileForUser(maybeUser);
}
@ -75,7 +74,6 @@ class ShowProfileOrFourOhFour extends Component<IShowProfileOrFourOhFourProps> {
}
const { isSessionUser, requestedUser, showLoading } = this.props;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (isEmpty(requestedUser)) {
if (showLoading) {
// We don't know if /:maybeUser is a user or not, we will show
@ -100,7 +98,6 @@ class ShowProfileOrFourOhFour extends Component<IShowProfileOrFourOhFourProps> {
// @ts-ignore
ShowProfileOrFourOhFour.displayName = 'ShowProfileOrFourOhFour';
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
export default connect(
makeMapStateToProps,
mapDispatchToProps

View File

@ -1,4 +1,3 @@
/* eslint-disable react/jsx-sort-props */
import React, { useState } from 'react';
import '../components/layouts/project-links.css';
import { maybeUrlRE } from '../utils';
@ -44,7 +43,6 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
const {
user: { completedChallenges }
} = props;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const completedProject = find(
completedChallenges,
({ id }) => projectId === id
@ -66,8 +64,8 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
if (challengeFiles) {
return (
<button
onClick={onClickHandler}
className='project-link-button-override'
onClick={onClickHandler}
>
{t('certification.project.solution')}
</button>
@ -127,8 +125,8 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
return (
<li key={ind}>
<a
href={certLocation}
className='btn-invert project-link'
href={certLocation}
rel='noopener noreferrer'
target='_blank'
>
@ -143,8 +141,7 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
// @ts-expect-error Error expected until projectMap is typed
({ link, title, id }) => (
<li key={id}>
{/* @ts-expect-error Link needs to be typed */}
<Link to={link} className='project-link'>
<Link className='project-link' to={link}>
{t(`certification.project.title.${title as string}`, title)}
</Link>
: {getProjectSolution(id, title)}
@ -187,16 +184,16 @@ const ShowProjectLinks = (props: IShowProjectLinksProps): JSX.Element => {
If you suspect that any of these projects violate the{' '}
<a
href='https://www.freecodecamp.org/news/academic-honesty-policy/'
target='_blank'
rel='noreferrer'
target='_blank'
>
academic honesty policy
</a>
, please{' '}
<a
href={`/user/${username}/report-user`}
target='_blank'
rel='noreferrer'
target='_blank'
>
report this to our team
</a>

View File

@ -55,4 +55,3 @@ const loggedInProps = {
};
const loggedOutProps = { ...loggedInProps };
loggedOutProps.isSignedIn = false;
/* eslint-disable */

View File

@ -26,7 +26,7 @@ import Certification from '../components/settings/Certification';
import { UserType } from '../redux/prop-types';
import DangerZone from '../components/settings/danger-zone';
const { apiLocation } = envData as Record<string, string>;
const { apiLocation } = envData;
// TODO: update types for actions
interface IShowSettingsProps {
@ -42,6 +42,7 @@ interface IShowSettingsProps {
updateQuincyEmail: (isSendQuincyEmail: boolean) => void;
user: UserType;
verifyCert: () => void;
path?: string;
}
const mapStateToProps = createSelector(
@ -165,6 +166,7 @@ export function ShowSettings(props: IShowSettingsProps): JSX.Element {
website={website}
/>
<Spacer />
{/* @ts-expect-error Portfolio types mismatch */}
<Portfolio portfolio={portfolio} updatePortfolio={updatePortfolio} />
<Spacer />
<Honesty isHonest={isHonest} updateIsHonest={updateIsHonest} />
@ -200,5 +202,5 @@ export function ShowSettings(props: IShowSettingsProps): JSX.Element {
}
ShowSettings.displayName = 'ShowSettings';
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
export default connect(mapStateToProps, mapDispatchToProps)(ShowSettings);

View File

@ -7,7 +7,7 @@ import envData from '../../../config/env.json';
import FullWidthRow from '../components/helpers/full-width-row';
import { Spacer } from '../components/helpers';
const { apiLocation } = envData as Record<string, string>;
const { apiLocation } = envData;
function ShowUnsubscribed({
unsubscribeId

View File

@ -166,6 +166,5 @@ class ShowUser extends Component<IShowUserProps> {
ShowUser.displayName = 'ShowUser';
export default withTranslation()(
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
connect(mapStateToProps, mapDispatchToProps)(ShowUser)
);

View File

@ -1,8 +1,3 @@
/* eslint-disable react/prop-types */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable import/no-unresolved */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import React from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
@ -10,7 +8,7 @@ import { useTranslation } from 'react-i18next';
import Login from './Login';
export interface AuthOrProfileProps {
user?: Object;
user?: Record<string, unknown>;
}
const AuthOrProfile = ({ user }: AuthOrProfileProps): JSX.Element => {
const { t } = useTranslation();
@ -30,7 +28,7 @@ const AuthOrProfile = ({ user }: AuthOrProfileProps): JSX.Element => {
<>
<Link
className={`avatar-nav-link ${badgeColorClass}`}
to={`/${user.username}`}
to={`/${user.username as string}`}
>
<AvatarRenderer
picture={user.picture}

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable react/prop-types */
import React, { RefObject } from 'react';
import { useTranslation } from 'react-i18next';
import AuthOrProfile from './auth-or-profile';
@ -9,7 +7,7 @@ export interface MenuButtonProps {
displayMenu?: boolean;
innerRef?: RefObject<HTMLButtonElement>;
onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined;
user?: Object;
user?: Record<string, unknown>;
}
const MenuButton = ({

View File

@ -8,13 +8,13 @@ import { Link, SkeletonSprite } from '../../helpers';
import NavLogo from './nav-logo';
import MenuButton from './menu-button';
import NavLinks from './nav-links';
import './universalNav.css';
import './universal-nav.css';
import { isLanding } from '../../../utils/path-parsers';
import Loadable from '@loadable/component';
const SearchBar = Loadable(() => import('../../search/searchBar/search-bar'));
const SearchBarOptimized = Loadable(() =>
import('../../search/searchBar/search-bar-optimized')
const SearchBarOptimized = Loadable(
() => import('../../search/searchBar/search-bar-optimized')
);
export interface UniversalNavProps {

View File

@ -1,9 +1,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/ban-types */
import React from 'react';
import Helmet from 'react-helmet';
@ -41,7 +39,7 @@ export class Header extends React.Component<
document.removeEventListener('click', this.handleClickOutside);
}
handleClickOutside(event: any): void {
handleClickOutside(event: globalThis.MouseEvent): void {
if (
this.state.displayMenu &&
this.menuButtonRef.current &&

View File

@ -7,6 +7,7 @@ function BlockSaveButton({
...restProps
}: {
children?: React.ReactNode;
disabled?: boolean;
}): JSX.Element {
const { t } = useTranslation();

View File

@ -5,7 +5,7 @@ function FullWidthRow({
children,
className
}: {
children?: JSX.Element[];
children?: React.ReactNode;
className?: string;
}): JSX.Element {
return (

View File

@ -1,8 +1,6 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import React, { useState } from 'react';
import './image-loader.css';
// @ts-ignore
import LazyLoad from 'react-lazy-load';
interface ImageLoaderProps {

View File

@ -5,7 +5,6 @@ import { create } from 'react-test-renderer';
import Link from './link';
describe('<Link />', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const externalLink = create(<Link external={true} to='/home' />).toJSON();
const gatsbyLink = create(<Link to='/home' />).toJSON();

View File

@ -2,12 +2,14 @@ import React from 'react';
import { Link as GatsbyLink } from 'gatsby';
interface LinkProps {
children?: JSX.ElementChildrenAttribute;
children?: React.ReactNode;
className?: string;
external?: boolean;
sameTab?: boolean;
state?: Record<string, unknown>;
to: string;
// TODO: figure out what these actually should be
other?: any[];
other?: unknown[];
}
const Link = ({

View File

@ -14,7 +14,7 @@ interface ButtonProps {
onChange: (value: string) => void;
onLabel: string;
value: boolean;
condition: boolean;
condition?: boolean;
}
type ActiveClass = Pick<ButtonProps, 'condition'>;

View File

@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from '@freecodecamp/react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {

View File

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import React from 'react';
import { render } from '@testing-library/react';
import TimeLine from './TimeLine';

View File

@ -1,3 +1,9 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/unbound-method */
import React, { Component, useMemo } from 'react';
import { reverse, sortBy } from 'lodash-es';
import {
@ -304,17 +310,15 @@ class TimelineInner extends Component<
<Modal.Header closeButton={true}>
<Modal.Title id='contained-modal-title'>
{`${username}'s Solution to ${
// @ts-ignore
// @ts-expect-error Need better TypeDef for this
idToNameMap.get(id).challengeTitle
}`}
</Modal.Title>
</Modal.Header>
<Modal.Body>
{/* @ts-ignore */}
<SolutionViewer
// @ts-ignore
// @ts-expect-error Need Better TypeDef
files={this.state.files}
// @ts-ignore
solution={this.state.solution}
/>
</Modal.Body>
@ -377,6 +381,7 @@ function useIdToNameMap(): Map<string, string> {
idToNameMap.set(id, { challengeTitle: title, challengePath: slug });
}
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return idToNameMap;
}

View File

@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';

View File

@ -6,7 +6,7 @@ interface noHitsSuggestionPropType {
title: string;
}
const NoHitsSuggestion = ({ title }: noHitsSuggestionPropType) => {
const NoHitsSuggestion = ({ title }: noHitsSuggestionPropType): JSX.Element => {
return (
<div className={'no-hits-footer fcc_suggestion_item'} role='region'>
<span className='hit-name'>{title}</span>

View File

@ -27,7 +27,7 @@ const searchUrl: string = searchPageUrl as string;
const mapStateToProps = createSelector(
isSearchDropdownEnabledSelector,
isSearchBarFocusedSelector,
(isDropdownEnabled, isSearchFocused) => ({
(isDropdownEnabled: boolean, isSearchFocused: boolean) => ({
isDropdownEnabled,
isSearchFocused
})
@ -184,7 +184,7 @@ export class SearchBar extends Component<searchBarPropType, classState> {
}
};
render() {
render(): JSX.Element {
const { isDropdownEnabled, isSearchFocused, innerRef, t } = this.props;
const { index } = this.state;
const placeholder = t ? t('search.placeholder') : '';

View File

@ -9,6 +9,7 @@ import NoHitsSuggestion from './no-hits-suggestion';
const searchUrl = searchPageUrl as string;
interface customHitsPropTypes {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
hits: Array<any>;
searchQuery: string;
handleMouseEnter: (e: React.SyntheticEvent<HTMLElement, Event>) => void;

View File

@ -12,7 +12,7 @@ const Suggestion = ({
hit,
handleMouseEnter,
handleMouseLeave
}: suggestionPropTypes) => {
}: suggestionPropTypes): JSX.Element => {
const dropdownFooter = hit.objectID.includes('footer-');
return (
<a

View File

@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import './empty-search.css';
function EmptySearch() {
function EmptySearch(): JSX.Element {
const { t } = useTranslation();
return <div className='empty-search-wrapper'>{t('search.try')}</div>;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Trans } from 'react-i18next';
function NoResults({ query }: { query: string }) {
function NoResults({ query }: { query: string }): JSX.Element {
return (
<div className='no-results-wrapper'>
<p>

View File

@ -15,6 +15,7 @@ type allHitType = {
handleClick?: EventHandler<SyntheticEvent>;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const AllHits: React.ComponentClass<AutocompleteExposed & allHitType, any> =
connectAutoComplete(({ hits, currentRefinement }) => {
const isHitsEmpty = !hits.length;

View File

@ -31,7 +31,7 @@ type AboutProps = {
points: number;
submitNewAbout: (formValues: FormValues) => void;
t: (str: string) => string;
toggleNightMode: () => void;
toggleNightMode: (theme: string) => void;
username: string;
};

View File

@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react';
import React, { Component, FormEvent, Fragment } from 'react';
import { nanoid } from 'nanoid';
import {
Button,
@ -107,7 +107,7 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
state => ({
portfolio: state.portfolio.filter(p => p.id !== id)
}),
() => this.handleSubmit(mockEvent)
() => this.handleSubmit(mockEvent as FormEvent<Element>)
);
};

View File

@ -4,3 +4,4 @@ declare module '@freecodecamp/strip-comments';
declare module '@types/react-redux';
declare module '@types/validator';
declare module '@types/lodash-es';
declare module 'react-lazy-load';

View File

@ -1,3 +1,11 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
/**
* TODO:
* Passing incomplete objects here is causing TS to be angry.
* We should either make the expected properties optional, or reevaluate
* these tests.
*/
import toLearnPath from '../utils/to-learn-path';
import { withPrefix } from 'gatsby';

View File

@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { bindActionCreators } from 'redux';
import type { Dispatch } from 'redux';
import { connect } from 'react-redux';
import SectionHeader from '../components/settings/SectionHeader';
import SectionHeader from '../components/settings/section-header';
import IntroDescription from '../components/Intro/components/IntroDescription';
import { withTranslation } from 'react-i18next';

View File

@ -8,6 +8,7 @@ import ShowUser from '../client-only-routes/show-user';
function User(): JSX.Element {
return (
<Router>
{/* @ts-expect-error Adding path property breaks username typing */}
<ShowUser path={withPrefix('/user/:username/report-user')} />
{/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
{/* @ts-ignore */}