diff --git a/airflow/www/.babelrc b/airflow/www/.babelrc index 7316527d05fe19..24da7a59d69b35 100644 --- a/airflow/www/.babelrc +++ b/airflow/www/.babelrc @@ -1,7 +1,7 @@ { "env": { "test": { - "presets": ["@babel/preset-env", "@babel/preset-react"], + "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"], "plugins": ["@babel/plugin-transform-runtime"] } } diff --git a/airflow/www/.eslintrc b/airflow/www/.eslintrc index 216c91070ca628..818b1ccf314591 100644 --- a/airflow/www/.eslintrc +++ b/airflow/www/.eslintrc @@ -5,6 +5,49 @@ "rules": { "no-param-reassign": 1, "react/prop-types": 0, - "react/jsx-props-no-spreading": 0 - } + "react/jsx-props-no-spreading": 0, + "import/extensions": [ + "error", + "ignorePackages", + { + "js": "never", + "jsx": "never", + "ts": "never", + "tsx": "never" + } + ], + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": true, + "optionalDependencies": false, + "peerDependencies": false + } + ] + }, + "settings": { + "import/resolver": { + "node": { + "extensions": [".js", ".jsx", ".ts", ".tsx"] + } + } + }, + // eslint that apply only to typescript files + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "extends": [ + "airbnb-typescript" + ], + "parser": "@typescript-eslint/parser", + "plugins": [ "@typescript-eslint" ], + "parserOptions": { + "project": "./tsconfig.json" + }, + "rules": { + "react/require-default-props": 0, + "@typescript-eslint/no-explicit-any": 1 + } + } + ] } diff --git a/airflow/www/jest.config.js b/airflow/www/jest.config.js index 43501e1c697fc5..677bdcc1122729 100644 --- a/airflow/www/jest.config.js +++ b/airflow/www/jest.config.js @@ -20,7 +20,7 @@ const config = { verbose: true, transform: { - '^.+\\.jsx?$': 'babel-jest', + '^.+\\.[jt]sx?$': 'babel-jest', }, testEnvironment: 'jsdom', setupFilesAfterEnv: ['./jest-setup.js'], diff --git a/airflow/www/package.json b/airflow/www/package.json index 5252f360a89b1a..efbc5058cf2549 100644 --- a/airflow/www/package.json +++ b/airflow/www/package.json @@ -5,8 +5,8 @@ "dev": "NODE_ENV=dev webpack --watch --colors --progress --debug --output-pathinfo --devtool eval-cheap-source-map --mode development", "prod": "NODE_ENV=production node --max_old_space_size=4096 ./node_modules/webpack/bin/webpack.js -p --colors --progress", "build": "NODE_ENV=production webpack --colors --progress", - "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx .", - "lint:fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx ." + "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && tsc --noEmit", + "lint:fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && tsc --noEmit" }, "author": "Apache", "license": "Apache-2.0", @@ -29,9 +29,12 @@ "@babel/plugin-transform-runtime": "^7.16.0", "@babel/preset-env": "^7.16.0", "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.17.12", "@testing-library/jest-dom": "^5.15.0", "@testing-library/react": "^12.1.2", "@testing-library/react-hooks": "^7.0.2", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.0.0", "babel": "^6.23.0", "babel-core": "^6.26.3", "babel-eslint": "^10.1.0", @@ -44,6 +47,7 @@ "css-loader": "^3.4.2", "eslint": "^7.2.0", "eslint-config-airbnb": "18.2.1", + "eslint-config-airbnb-typescript": "^17.0.0", "eslint-plugin-html": "^6.0.2", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.4.1", @@ -56,7 +60,7 @@ "imports-loader": "^1.1.0", "jest": "^27.3.1", "mini-css-extract-plugin": "1.6.0", - "moment": "^2.29.2", + "moment": "^2.29.3", "moment-locales-webpack-plugin": "^1.2.0", "nock": "^13.2.4", "optimize-css-assets-webpack-plugin": "6.0.0", @@ -64,6 +68,7 @@ "stylelint": "^13.6.1", "stylelint-config-standard": "^20.0.0", "terser-webpack-plugin": "<5.0.0", + "typescript": "^4.6.3", "url-loader": "4.1.0", "webpack": "4.44.2", "webpack-cli": "^3.3.12", @@ -90,7 +95,7 @@ "jquery": ">=3.5.0", "jshint": "^2.13.4", "lodash": "^4.17.21", - "moment-timezone": "^0.5.28", + "moment-timezone": "^0.5.34", "nvd3": "^1.8.6", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/airflow/www/static/js/dag.js b/airflow/www/static/js/dag.js index 0445e0686cb56d..2a99a0af1658e8 100644 --- a/airflow/www/static/js/dag.js +++ b/airflow/www/static/js/dag.js @@ -17,7 +17,7 @@ * under the License. */ -/* global document, window, Event, $ */ +/* global document, window, CustomEvent, $ */ import { getMetaValue } from './utils'; import { approxTimeFromNow, formatDateTime } from './datetime_utils'; @@ -367,9 +367,7 @@ $('#pause_resume').on('change', function onChange() { $input.removeClass('switch-input--error'); // dispatch an event that React can listen for - const event = new Event('paused'); - event.value = isPaused; - event.key = 'isPaused'; + const event = new CustomEvent('paused', { detail: isPaused }); document.dispatchEvent(event); $.post(url).fail(() => { diff --git a/airflow/www/static/js/grid/components/Time.test.jsx b/airflow/www/static/js/grid/components/Time.test.tsx similarity index 90% rename from airflow/www/static/js/grid/components/Time.test.jsx rename to airflow/www/static/js/grid/components/Time.test.tsx index c3044c59fc917e..a7de6f5f328b5d 100644 --- a/airflow/www/static/js/grid/components/Time.test.jsx +++ b/airflow/www/static/js/grid/components/Time.test.tsx @@ -17,7 +17,7 @@ * under the License. */ -/* global describe, test, expect, document, Event */ +/* global describe, test, expect, document, CustomEvent */ import React from 'react'; import { @@ -33,7 +33,7 @@ describe('Test Time and TimezoneProvider', () => { test('Displays a UTC time correctly', () => { const now = new Date(); const { getByText } = render( -