diff --git a/package.json b/package.json index ba8e9e5e51..315db8e629 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "deploy": "ui-scripts publish" }, "devDependencies": { + "babel-plugin-reflow": "^0.2.7", "lerna": "^3.17.0" }, "resolutions": { diff --git a/scm-ui/babel-preset/index.js b/scm-ui/babel-preset/index.js index c3c750e59c..54c71e3741 100644 --- a/scm-ui/babel-preset/index.js +++ b/scm-ui/babel-preset/index.js @@ -2,7 +2,8 @@ module.exports = () => ({ presets: [ require("@babel/preset-env"), require("@babel/preset-flow"), - require("@babel/preset-react") + require("@babel/preset-react"), + require("@babel/preset-typescript") ], plugins: [ require("@babel/plugin-proposal-class-properties"), diff --git a/scm-ui/babel-preset/package.json b/scm-ui/babel-preset/package.json index ba7f1eca06..4751670f65 100644 --- a/scm-ui/babel-preset/package.json +++ b/scm-ui/babel-preset/package.json @@ -13,7 +13,8 @@ "@babel/plugin-proposal-optional-chaining": "^7.6.0", "@babel/preset-env": "^7.6.3", "@babel/preset-flow": "^7.0.0", - "@babel/preset-react": "^7.6.3" + "@babel/preset-react": "^7.6.3", + "@babel/preset-typescript": "^7.6.0" }, "publishConfig": { "access": "public" diff --git a/scm-ui/jest-preset/jest-preset.js b/scm-ui/jest-preset/jest-preset.js index 0f8d359e1d..ffdeac244b 100644 --- a/scm-ui/jest-preset/jest-preset.js +++ b/scm-ui/jest-preset/jest-preset.js @@ -24,7 +24,7 @@ module.exports = { path.join(root, "src") ], transform: { - "^.+\\.js$": "@scm-manager/jest-preset" + "^.+\\.(ts|tsx|js)$": "@scm-manager/jest-preset" }, transformIgnorePatterns: [ "node_modules/(?!(@scm-manager)/)" @@ -39,7 +39,7 @@ module.exports = { setupFiles: [path.resolve(__dirname, "src", "setup.js")], collectCoverage: true, collectCoverageFrom: [ - "src/**/*.{js,jsx}" + "src/**/*.{ts,tsx,js,jsx}" ], coverageDirectory: path.join(reportDirectory, "coverage-" + name), coveragePathIgnorePatterns: [ diff --git a/scm-ui/ui-components/.storybook/config.js b/scm-ui/ui-components/.storybook/config.js index aedb86772a..0bfd5bbf42 100644 --- a/scm-ui/ui-components/.storybook/config.js +++ b/scm-ui/ui-components/.storybook/config.js @@ -25,4 +25,4 @@ addDecorator( }) ); -configure(require.context("../src", true, /\.stories\.js$/), module); +configure(require.context("../src", true, /\.stories\.tsx?$/), module); diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json index e2e5139ba6..7c44229a62 100644 --- a/scm-ui/ui-components/package.json +++ b/scm-ui/ui-components/package.json @@ -2,7 +2,7 @@ "name": "@scm-manager/ui-components", "version": "2.0.0-SNAPSHOT", "description": "UI Components for SCM-Manager and its plugins", - "main": "src/index.js", + "main": "src/index.ts", "files": [ "dist", "src" @@ -13,8 +13,8 @@ "scripts": { "test": "jest", "storybook": "start-storybook -s ../ui-webapp/public", - "storyshots": "jest --testPathPattern=\"storyshots.test.js\" --collectCoverage=false", - "update-storyshots": "jest --testPathPattern=\"storyshots.test.js\" --collectCoverage=false -u" + "storyshots": "jest --testPathPattern=\"storyshots.test.ts\" --collectCoverage=false", + "update-storyshots": "jest --testPathPattern=\"storyshots.test.ts\" --collectCoverage=false -u" }, "devDependencies": { "@scm-manager/ui-tests": "^2.0.0-SNAPSHOT", diff --git a/scm-ui/ui-components/src/Autocomplete.js b/scm-ui/ui-components/src/Autocomplete.tsx similarity index 70% rename from scm-ui/ui-components/src/Autocomplete.js rename to scm-ui/ui-components/src/Autocomplete.tsx index 116df6562a..55dc4d6182 100644 --- a/scm-ui/ui-components/src/Autocomplete.js +++ b/scm-ui/ui-components/src/Autocomplete.tsx @@ -1,28 +1,27 @@ -// @flow -import React from "react"; -import {Async, AsyncCreatable} from "react-select"; -import type {AutocompleteObject, SelectValue} from "@scm-manager/ui-types"; -import LabelWithHelpIcon from "./forms/LabelWithHelpIcon"; +import React from 'react'; +import { Async, AsyncCreatable } from 'react-select'; +import { AutocompleteObject, SelectValue } from '@scm-manager/ui-types'; +import LabelWithHelpIcon from './forms/LabelWithHelpIcon'; type Props = { - loadSuggestions: string => Promise, - valueSelected: SelectValue => void, - label: string, - helpText?: string, - value?: SelectValue, - placeholder: string, - loadingMessage: string, - noOptionsMessage: string, - creatable?: boolean + loadSuggestions: (p: string) => Promise; + valueSelected: (p: SelectValue) => void; + label: string; + helpText?: string; + value?: SelectValue; + placeholder: string; + loadingMessage: string; + noOptionsMessage: string; + creatable?: boolean; }; type State = {}; class Autocomplete extends React.Component { static defaultProps = { - placeholder: "Type here", - loadingMessage: "Loading...", - noOptionsMessage: "No suggestion available" + placeholder: 'Type here', + loadingMessage: 'Loading...', + noOptionsMessage: 'No suggestion available', }; handleInputChange = (newValue: SelectValue) => { @@ -33,12 +32,12 @@ class Autocomplete extends React.Component { isValidNewOption = ( inputValue: string, selectValue: SelectValue, - selectOptions: SelectValue[] + selectOptions: SelectValue[], ) => { const isNotDuplicated = !selectOptions .map(option => option.label) .includes(inputValue); - const isNotEmpty = inputValue !== ""; + const isNotEmpty = inputValue !== ''; return isNotEmpty && isNotDuplicated; }; @@ -51,7 +50,7 @@ class Autocomplete extends React.Component { loadingMessage, noOptionsMessage, loadSuggestions, - creatable + creatable, } = this.props; return (
@@ -70,7 +69,10 @@ class Autocomplete extends React.Component { onCreateOption={value => { this.handleInputChange({ label: value, - value: { id: value, displayName: value } + value: { + id: value, + displayName: value, + }, }); }} /> diff --git a/scm-ui/ui-components/src/BackendErrorNotification.js b/scm-ui/ui-components/src/BackendErrorNotification.tsx similarity index 74% rename from scm-ui/ui-components/src/BackendErrorNotification.js rename to scm-ui/ui-components/src/BackendErrorNotification.tsx index 31106593c4..256383241c 100644 --- a/scm-ui/ui-components/src/BackendErrorNotification.js +++ b/scm-ui/ui-components/src/BackendErrorNotification.tsx @@ -1,11 +1,13 @@ -// @flow -import React from "react"; -import { BackendError } from "./errors"; -import Notification from "./Notification"; +import React from 'react'; +import { BackendError } from './errors'; +import Notification from './Notification'; -import { translate } from "react-i18next"; +import { translate } from 'react-i18next'; -type Props = { error: BackendError, t: string => string }; +type Props = { + error: BackendError; + t: (p: string) => string; +}; class BackendErrorNotification extends React.Component { constructor(props: Props) { @@ -27,7 +29,7 @@ class BackendErrorNotification extends React.Component { renderErrorName = () => { const { error, t } = this.props; - const translation = t("errors." + error.errorCode + ".displayName"); + const translation = t('errors.' + error.errorCode + '.displayName'); if (translation === error.errorCode) { return error.message; } @@ -36,9 +38,9 @@ class BackendErrorNotification extends React.Component { renderErrorDescription = () => { const { error, t } = this.props; - const translation = t("errors." + error.errorCode + ".description"); + const translation = t('errors.' + error.errorCode + '.description'); if (translation === error.errorCode) { - return ""; + return ''; } return translation; }; @@ -49,7 +51,7 @@ class BackendErrorNotification extends React.Component { return ( <>

- {t("errors.violations")} + {t('errors.violations')}