Skip to content
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

Migrate Navigator from TSLint to ESLint #8172

Merged
merged 3 commits into from
Dec 4, 2020
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
60 changes: 60 additions & 0 deletions navigator/frontend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

module.exports = {
"env": {
"browser": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
},
"plugins": [
"react",
"@typescript-eslint",
],
"rules": {
"react/display-name": "off",
// Triggers falsely on FCs if you don’t annotate the argument as well, see
// https://github.com/yannickcr/eslint-plugin-react/issues/2353
"react/prop-types": "off",
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
// While {} is problematic in a lot of cases, using it as the
// props types is fine and this is very common in React, see
// https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492
"{}": false,
},
},
],
// Warning on redundant type annotations seems silly.
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/explicit-module-boundary-types": [
"error",
{
"allowArgumentsExplicitlyTypedAsAny": true,
},
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_",
}
],
},
"settings": {
"react": {
"version": "detect",
},
},
};

18 changes: 13 additions & 5 deletions navigator/frontend/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ nodejs_binary(
# name = "frontend",
# tsconfig = ":tsconfig.json",
# srcs = glob(["**/*.ts"]),
# data = [":package.json", ":tslint.json"],
# data = [":package.json", ":.eslintrc.js"],
# node_modules = "@navigator_frontend_deps//:node_modules",
# visibility = [
# "//navigator:__subpackages__",
Expand All @@ -79,7 +79,7 @@ genrule(
"webpack.config.js",
"declarations.d.ts",
"tsconfig.json",
"tslint.json",
".eslintrc.js",
"package.json",
".modernizrrc",
":src",
Expand All @@ -104,24 +104,32 @@ genrule(
cp -L "$$(pwd)/$(execpath webpack.config.js)" "$$IN/webpack.config.js"
cp -L "$$(pwd)/$(execpath .modernizrrc)" "$$IN/.modernizrrc"
cp -L "$$(pwd)/$(execpath tsconfig.json)" "$$IN/tsconfig.json"
cp -L "$$(pwd)/$(execpath tslint.json)" "$$IN/tslint.json"
cp -L "$$(pwd)/$(execpath .eslintrc.js)" "$$IN/.eslintrc.js"
cp -L "$$(pwd)/$(execpath declarations.d.ts)" "$$IN/declarations.d.ts"

# Webpack needs the HOME variable to be set
export HOME="$$IN"

PREV=$$PWD

WEBPACK=$$PREV/$(execpath :webpack)

cd $$IN

# Run webpack.
# To debug, add the following options:
# -d --progress --display-error-details --verbose
WP_IN={WP_IN}
WP_OUT={WP_OUT}
$(execpath :webpack) \\
--config="$$IN/webpack.config.js" \\
$$WEBPACK \\
--config="webpack.config.js" \\
--env prod \\
--env paths_case_check="{PATHS_CASE_CHECK}" \\
--env bazel_in_dir="{WP_IN_ESCAPED}" \\
--env bazel_out_dir="{WP_OUT_ESCAPED}"

cd $$PREV

# Package result (.TGZ)
# To debug, change 'c' to 'cv'.
echo "Packaging result from $$OUT to $(@D)/frontend.tgz"
Expand Down
2 changes: 1 addition & 1 deletion navigator/frontend/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ declare module "!raw-loader!*" {
}

declare module "modernizr" {
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var _a: any;
export = _a;
}
Expand Down
14 changes: 8 additions & 6 deletions navigator/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
"start": "webpack-dev-server",
"start-ui-core": "webpack-dev-server --config webpack.ui-core.js",
"build": "webpack --env prod",
"test": "echo 'No frontend tests exist yet.'",
"lint": "tslint --project tslint.json"
"test": "echo 'No frontend tests exist yet.'"
},
"devDependencies": {
"@bazel/hide-bazel-files": "^1.7.0",
Expand All @@ -36,9 +35,16 @@
"@types/react-virtualized": "^9.21.10",
"@types/route-parser": "^0.1.3",
"@types/styled-components": "^5.1.0",
"@typescript-eslint/eslint-plugin": "^4.9.0",
"@typescript-eslint/parser": "^4.9.0",
"case-sensitive-paths-webpack-plugin": "^2.3.0",
"classnames": "^2.2.5",
"css-loader": "^5.0.1",
"eslint": "^7.0.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsdoc": "^30.7.8",
"eslint-plugin-react": "^7.21.5",
"eslint-webpack-plugin": "^2.4.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
"json-loader": "^0.5.7",
Expand All @@ -48,9 +54,6 @@
"style-loader": "^2.0.0",
"ts-loader": "8.0.11",
"tsconfig-paths-webpack-plugin": "^3.3.0",
"tslint": "^6.1.3",
"tslint-loader": "3.5.4",
"tslint-react": "^5.0.0",
"typescript": "4.1.2",
"url-loader": "^4.1.1",
"webpack": "^4.44.2",
Expand Down Expand Up @@ -89,7 +92,6 @@
},
"resolutions": {
"**/elliptic": "^6.5.3",
"**/resize-img": "^2.0.0",
"**/jpeg-js": "^0.4.1",
"**/selfsigned": "^1.10.8"
}
Expand Down
6 changes: 3 additions & 3 deletions navigator/frontend/src/applets/about/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface BackendVersionInfo {

export type BackendVersionInfoResult
= {type: 'none'}
| {type: 'loading'}
| {type: 'loading'}
| {type: 'loaded', info: BackendVersionInfo}
| {type: 'fetch-error', error: string}
;
Expand Down Expand Up @@ -71,7 +71,7 @@ function handleBackendInfoResponse(to: ToSelf, dispatch: Dispatch<App.Action>) {
}

function handleBackendInfoFetchError(to: ToSelf, dispatch: Dispatch<App.Action>) {
// tslint:disable-next-line no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (reason: any) => {
if (reason instanceof Error) {
// Log to console to show error call stack
Expand Down Expand Up @@ -166,6 +166,6 @@ class Component extends React.Component<Props, {}> {
</Wrapper>
);
}
};
}

export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
16 changes: 9 additions & 7 deletions navigator/frontend/src/applets/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as Session from '@da/ui-core/lib/session';
import * as React from 'react';
import { connect, ConnectedComponent } from 'react-redux';
import { Action as ReduxAction } from 'redux';
import { ThunkAction } from 'redux-thunk';
import Frame from '../../components/Frame';
import {
ConfigType,
Expand All @@ -25,7 +26,7 @@ export type Action
| { type: 'TO_PAGE', action: Page.Action }
| { type: 'TO_WATCHER', action: LedgerWatcher.Action }
| { type: 'TO_CONFIG', action: ConfigSource.Action }
| { type: 'RESET_APP' }
| { type: 'RESET_APP' }

export const toPage = (action: Page.Action): Action =>
({ type: 'TO_PAGE', action });
Expand All @@ -42,8 +43,8 @@ export const toConfig = (action: ConfigSource.Action): Action =>
export const resetApp = (): Action =>
({ type: 'RESET_APP' });

export const initSession = () => Session.init(toSession);
export const initConfig = () => ConfigSource.reload(toConfig);
export const initSession = (): ThunkAction<void, void, undefined, Action> => Session.init(toSession);
export const initConfig = (): ThunkAction<void, State, undefined, Action> => ConfigSource.reload(toConfig);

export interface State {
session: Session.State;
Expand Down Expand Up @@ -131,14 +132,14 @@ class Component extends React.Component<Props, ComponentState> {
};
}

componentWillReceiveProps(nextProps: Props) {
UNSAFE_componentWillReceiveProps(nextProps: Props) {
// Fast skip if neither session nor config source have changed
if (
nextProps.state.session !== this.props.state.session ||
nextProps.state.configSource !== this.props.state.configSource
) {

this.setState<'config' | 'theme'>(this.computeStateFromSession(nextProps));
this.setState<'config' | 'theme'>(this.computeStateFromSession(nextProps));
}
}

Expand All @@ -157,7 +158,7 @@ class Component extends React.Component<Props, ComponentState> {
config: Either.left<Error, ConfigType>(new Error(configSource.result.error)),
theme: defaultTheme,
};
case 'loaded':
case 'loaded': {
// Got config source, try to parse and evaluate it (caching results)
const source = configSource.result.source;
const {result, cache: newCache} = evalConfigCached(user, source, configCache);
Expand All @@ -166,6 +167,7 @@ class Component extends React.Component<Props, ComponentState> {
configCache: newCache,
theme: result.type === 'right' ? {...defaultTheme, ...result.value.theme} : defaultTheme,
};
}
}
}

Expand Down Expand Up @@ -240,7 +242,7 @@ class Component extends React.Component<Props, ComponentState> {
return <p>Unknown session or config type</p>;
}
}
};
}

export const UI: ConnectedComponent<typeof Component, OwnProps> =
connect((state) => ({state}), (dispatch) => ({dispatch}))(Component);
4 changes: 2 additions & 2 deletions navigator/frontend/src/applets/configsource/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function handleResponse(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined
}

function handleFetchError(to: ToSelf, dispatch: ThunkDispatch<App.State, undefined, App.Action>) {
// tslint:disable-next-line no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (reason: any) => {
if (reason instanceof Error) {
// Log to console to show error call stack
Expand Down Expand Up @@ -182,6 +182,6 @@ class Component extends React.Component<Props, {}> {
</Wrapper>
);
}
};
}

export const UI: ConnectedComponent<typeof Component, OwnProps> = connect()(Component);
6 changes: 3 additions & 3 deletions navigator/frontend/src/applets/contract/ContractComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { DamlLfValue } from '@da/ui-core/lib/api/DamlLfValue';
import * as React from 'react';
import Link, {OwnProps} from '../../components/Link';
import * as Routes from '../../routes';
import { Contract } from './';
import { Contract } from './';
import Exercise from './Exercise';

const Wrapper = styled.div`
Expand Down Expand Up @@ -100,7 +100,7 @@ interface Props {
exercise(e: React.MouseEvent<HTMLButtonElement>, argument?: DamlLfValue): void;
}

export default (props: Props) => {
export default (props: Props): JSX.Element => {
const { contract, choice, exercise, choiceLoading, error } = props;
const choices = contract.template.choices;
const isArchived = contract.archiveEvent !== null;
Expand Down Expand Up @@ -129,7 +129,7 @@ export default (props: Props) => {
key={name}
route={Routes.contract}
params={{id: encodeURIComponent(contract.id), choice: name}}
isActive={isActive || !isAnyActive}
isActive={isActive || !isAnyActive}
>
{name}
</ChoiceLink>
Expand Down
4 changes: 2 additions & 2 deletions navigator/frontend/src/applets/contract/Exercise.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface Props {
error?: string;
onSubmit(e: React.MouseEvent<HTMLButtonElement>, argument?: DamlLfValue): void;
className?: string;
// tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
client: ApolloClient<any>;
}

Expand All @@ -41,7 +41,7 @@ class Component extends React.Component<Props, Local> {
this.state = { argument: DamlLfValueF.initialValue(props.parameter) };
}

componentWillReceiveProps(nextProps: Props) {
UNSAFE_componentWillReceiveProps(nextProps: Props) {
// If the choice changes, re-initialize the argument
// (trying to reuse as much argument values as possible).
if (this.props.choice !== nextProps.choice) {
Expand Down
10 changes: 5 additions & 5 deletions navigator/frontend/src/applets/contract/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ interface QueryProps {
}
interface MutationProps {
exercise?(contractId: string, choiceId: string, argument?: DamlLfValue):
//tslint:disable-next-line:no-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Promise<any>;
}

Expand All @@ -79,7 +79,7 @@ class Component extends React.Component<Props, {}> {
this.gotoParent = this.gotoParent.bind(this);
}

componentWillUnmount(): void { this.gotoParent = () => { ; }; }
componentWillUnmount(): void { this.gotoParent = () => { return; }; }

/**
* This component deals with displaying a form for exercising a choice and
Expand All @@ -103,7 +103,7 @@ class Component extends React.Component<Props, {}> {
// It is meant to be used in the asynchronous exercise function.
const { toSelf, dispatch } = this.props;
dispatch(toSelf(setChoice()));
};
}

exercise(e: React.MouseEvent<HTMLButtonElement>, argument?: DamlLfValue): void {
e.preventDefault();
Expand Down Expand Up @@ -144,7 +144,7 @@ class Component extends React.Component<Props, {}> {
);
}
}
};
}

const query = gql`
query ContractDetailsById($id: ID!) {
Expand Down Expand Up @@ -189,7 +189,7 @@ const _withMutation =
withMutation<OwnProps, ContractExercise, {}, MutationProps>(mutation,
{
props: ({mutate}): MutationProps => ({
exercise: mutate && ((contractId: string, choiceId: String, argument?: DamlLfValue) =>
exercise: mutate && ((contractId: string, choiceId: string, argument?: DamlLfValue) =>
mutate({variables: { contractId, choiceId, argument}})
)}),
},
Expand Down
2 changes: 1 addition & 1 deletion navigator/frontend/src/applets/contracts/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function makeQueryVariables(config: ContractTableConfig): ContractsQueryV
};
}

export function dataToRows(data: QueryControls & ContractsQuery) {
export function dataToRows(data: QueryControls & ContractsQuery): { contracts: Contract[], totalCount: number } {
if (data.loading || data.error) {
return { contracts: [], totalCount: 0 }
} else {
Expand Down
Loading