From 953a006125c118bd278632b884ab203950ce6636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Tue, 22 Oct 2019 23:48:13 +0100 Subject: [PATCH] feat(ui): add typescript support --- Makefile | 2 +- ui/.storybook/config.js | 2 +- ui/jsconfig.json | 6 --- ui/package-lock.json | 93 +++++++++++++++++++--------------- ui/package.json | 7 ++- ui/src/Stores/Settings.js | 2 +- ui/src/index.test.js | 2 +- ui/src/{index.js => index.tsx} | 8 +-- ui/src/react-app-env.d.ts | 1 + ui/tsconfig.json | 20 ++++++++ 10 files changed, 88 insertions(+), 55 deletions(-) delete mode 100644 ui/jsconfig.json rename ui/src/{index.js => index.tsx} (86%) create mode 100644 ui/src/react-app-env.d.ts create mode 100644 ui/tsconfig.json diff --git a/Makefile b/Makefile index 03dde31a8..c6371fc83 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ format-go: .build/deps-build-go.ok .PHONY: format-js format-js: .build/deps-build-node.ok - cd ui && ./node_modules/.bin/prettier --write 'src/**/*.js' + cd ui && ./node_modules/.bin/prettier --write 'src/**/*.js' 'src/**/*.tsx' .PHONY: openapi-client openapi-client: diff --git a/ui/.storybook/config.js b/ui/.storybook/config.js index 4e5a19555..52284b361 100644 --- a/ui/.storybook/config.js +++ b/ui/.storybook/config.js @@ -10,7 +10,7 @@ setAddon(percyAddon); // mock date so the silence form always shows same preview advanceTo(new Date(Date.UTC(2018, 7, 14, 17, 36, 40))); -const req = require.context("../src/Components", true, /\.stories\.js$/); +const req = require.context("../src/Components", true, /\.stories\.(js|tsx)$/); function loadStories() { req.keys().forEach(filename => req(filename)); diff --git a/ui/jsconfig.json b/ui/jsconfig.json deleted file mode 100644 index 5875dc5b6..000000000 --- a/ui/jsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": "src" - }, - "include": ["src"] -} diff --git a/ui/package-lock.json b/ui/package-lock.json index a8ab194fd..deaeaa1a2 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -2814,22 +2814,33 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "24.0.19", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.19.tgz", + "integrity": "sha512-YYiqfSjocv7lk5H/T+v5MjATYjaTMsUkbDnjGqSMoO88jWdtJXJV4ST/7DKZcoMHMBvB2SeSfyOzZfkxXHR5xg==", + "requires": { + "@types/jest-diff": "*" + } + }, + "@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==" + }, "@types/json-schema": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz", "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==" }, "@types/node": { - "version": "12.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.2.tgz", - "integrity": "sha512-dsfE4BHJkLQW+reOS6b17xhZ/6FB1rB8eRRvO08nn5o+voxf3i74tuyFWNH6djdfgX7Sm5s6LD8t6mJug4dpDw==", - "dev": true + "version": "12.11.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.5.tgz", + "integrity": "sha512-LC8ALj/24PhByn39nr5jnTvpE7MujK8y7LQmV74kHYF5iQ0odCPkMH4IZNZw+cobKfSXqaC8GgegcbIsQpffdA==" }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", - "dev": true + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/q": { "version": "1.5.2", @@ -2850,12 +2861,19 @@ "version": "16.9.9", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.9.tgz", "integrity": "sha512-L+AudFJkDukk+ukInYvpoAPyJK5q1GanFOINOJnM0w6tUgITuWvJ4jyoBPFL7z4/L8hGLd+K/6xR5uUjXu0vVg==", - "dev": true, "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" } }, + "@types/react-dom": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.2.tgz", + "integrity": "sha512-hgPbBoI1aTSTvZwo8HYw35UaTldW6n2ETLvHAcfcg1FaOuBV3olmyCe5eMpx2WybWMBPv0MdU2t5GOcQhP+3zA==", + "requires": { + "@types/react": "*" + } + }, "@types/react-syntax-highlighter": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-10.1.0.tgz", @@ -4674,9 +4692,9 @@ } }, "bser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", - "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "requires": { "node-int64": "^0.4.0" } @@ -6503,9 +6521,9 @@ } }, "date-fns": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.5.1.tgz", - "integrity": "sha512-ZBrQmuaqH9YqIejbgu8f09ki7wdD2JxWsRTZ/+HnnLNmkI56ty0evnWzKY+ihLT0xX5VdUX0vDNZCxJJGKX2+Q==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.6.0.tgz", + "integrity": "sha512-F55YxqRdEfP/eYQmQjLN798v0AwLjmZ8nMBjdQvNwEE3N/zWVrlkkqT+9seBlPlsbkybG4JmWg3Ee3dIV9BcGQ==" }, "date-now": { "version": "0.1.4", @@ -6966,9 +6984,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.292", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.292.tgz", - "integrity": "sha512-hqkem5ANpt6mxVXmhAmlbdG8iicuyM/jEYgmP1tiHPeOLyZoTyGUzrDmJS/xyrrZy9frkW1uQcubicu7f6DS5g==" + "version": "1.3.293", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.293.tgz", + "integrity": "sha512-DQSBRuU2Z1vG+CEWUIfCEVMHtuaGlhVojzg39mX5dx7PLSFDJ7DSrGUWzaPFFgWR1jo26hj1nXXRQZvFwk7F8w==" }, "element-resize-detector": { "version": "1.1.15", @@ -12334,9 +12352,9 @@ } }, "node-releases": { - "version": "1.1.37", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.37.tgz", - "integrity": "sha512-0EOsAEdn6S2vQdDGBWBpmClm5BCkXVkVOURdnhfg7//rxI2XbleRdKig87WuBrk+0PHZ4OhO58fRm9mzWW4jNw==", + "version": "1.1.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.38.tgz", + "integrity": "sha512-/5NZAaOyTj134Oy5Cp/J8mso8OD/D9CSuL+6TOXXsTKO8yjc5e4up75SRPCganCjwFKMj2jbp5tR0dViVdox7g==", "requires": { "semver": "^6.3.0" } @@ -14832,17 +14850,6 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.17.0" - }, - "dependencies": { - "scheduler": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", - "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } } }, "react-draggable": { @@ -14941,9 +14948,9 @@ } }, "react-is": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.2.tgz", - "integrity": "sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==" + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", + "integrity": "sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==" }, "react-js-pagination": { "version": "3.0.2", @@ -15157,15 +15164,15 @@ } }, "react-test-renderer": { - "version": "16.10.2", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.10.2.tgz", - "integrity": "sha512-k9Qzyev6cTIcIfrhgrFlYQAFxh5EEDO6ALNqYqmKsWVA7Q/rUMTay5nD3nthi6COmYsd4ghVYyi8U86aoeMqYQ==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.11.0.tgz", + "integrity": "sha512-nh9gDl8R4ut+ZNNb2EeKO5VMvTKxwzurbSMuGBoKtjpjbg8JK/u3eVPVNi1h1Ue+eYK9oSzJjb+K3lzLxyA4ag==", "dev": true, "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", "react-is": "^16.8.6", - "scheduler": "^0.16.2" + "scheduler": "^0.17.0" } }, "react-textarea-autosize": { @@ -16149,10 +16156,9 @@ } }, "scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg==", - "dev": true, + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.17.0.tgz", + "integrity": "sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -17717,6 +17723,11 @@ "resolved": "https://registry.npmjs.org/typeface-open-sans/-/typeface-open-sans-0.0.75.tgz", "integrity": "sha512-0lLmB7pfj113OP4T78SbpSmC4OCdFQ0vUxdSXQccsSb6qF76F92iEuC/DghFgmPswTyidk8+Hwf+PS/htiJoRQ==" }, + "typescript": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", + "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==" + }, "ua-parser-js": { "version": "0.7.20", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", diff --git a/ui/package.json b/ui/package.json index c327c1491..bae67806c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -10,6 +10,10 @@ "@fortawesome/free-solid-svg-icons": "5.11.2", "@fortawesome/react-fontawesome": "0.1.7", "@sentry/browser": "5.7.1", + "@types/jest": "24.0.19", + "@types/node": "12.11.5", + "@types/react": "16.9.9", + "@types/react-dom": "16.9.2", "body-scroll-lock": "2.6.4", "bootstrap": "4.3.1", "bootswatch": "4.3.1", @@ -54,7 +58,8 @@ "react-transition-group": "4.3.0", "react-truncate": "2.4.0", "semver": "6.3.0", - "typeface-open-sans": "0.0.75" + "typeface-open-sans": "0.0.75", + "typescript": "3.6.4" }, "scripts": { "start": "NODE_ENV=dev REACT_APP_BACKEND_URI=http://localhost:8080 react-scripts start", diff --git a/ui/src/Stores/Settings.js b/ui/src/Stores/Settings.js index 114588e53..b9ac01396 100644 --- a/ui/src/Stores/Settings.js +++ b/ui/src/Stores/Settings.js @@ -113,7 +113,7 @@ class FilterBarConfig { class Settings { constructor(defaults) { let defaultSettings; - if (defaults === undefined) { + if (defaults === undefined || defaults === null) { defaultSettings = { Refresh: 30 * 1000 * 1000 * 1000, HideFiltersWhenIdle: true, diff --git a/ui/src/index.test.js b/ui/src/index.test.js index 70e6e7d83..330f8c64c 100644 --- a/ui/src/index.test.js +++ b/ui/src/index.test.js @@ -10,7 +10,7 @@ it("renders without crashing", () => { const response = EmptyAPIResponse(); response.filters = []; fetch.mockResponse(JSON.stringify(response)); - const Index = require("./index.js"); + const Index = require("./index.tsx"); expect(Index).toBeTruthy(); }); diff --git a/ui/src/index.js b/ui/src/index.tsx similarity index 86% rename from ui/src/index.js rename to ui/src/index.tsx index fd45b7331..43702d17a 100644 --- a/ui/src/index.js +++ b/ui/src/index.tsx @@ -17,9 +17,11 @@ import { } from "./AppBoot"; import { App } from "./App"; -const uiDefaults = ParseUIDefaults( - document.getElementById("defaults").innerHTML -); +let uiDefaults; +const defaultsElement = document.getElementById("defaults"); +if (defaultsElement !== null) { + uiDefaults = ParseUIDefaults(defaultsElement.innerHTML); +} const settingsElement = SettingsElement(); diff --git a/ui/src/react-app-env.d.ts b/ui/src/react-app-env.d.ts new file mode 100644 index 000000000..6431bc5fc --- /dev/null +++ b/ui/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 000000000..2b99637ee --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "baseUrl": "src", + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + }, + "include": ["src"] +}