diff --git a/TestResultSummaryService/.Database.js.swp b/TestResultSummaryService/.Database.js.swp new file mode 100644 index 00000000..96c367b8 Binary files /dev/null and b/TestResultSummaryService/.Database.js.swp differ diff --git a/TestResultSummaryService/.trssConf.json.swp b/TestResultSummaryService/.trssConf.json.swp new file mode 100644 index 00000000..88ab0055 Binary files /dev/null and b/TestResultSummaryService/.trssConf.json.swp differ diff --git a/TestResultSummaryService/Database.js b/TestResultSummaryService/Database.js index 09f1677d..77984bb8 100644 --- a/TestResultSummaryService/Database.js +++ b/TestResultSummaryService/Database.js @@ -15,10 +15,22 @@ let db; const dbConnect = await MongoClient.connect(url, { useUnifiedTopology: true }); db = dbConnect.db("exampleDb"); - await db.createCollection('testResults'); - await db.createCollection('output'); - await db.createCollection('auditLogs'); - await db.createCollection('user'); + await db.createCollection('testResults').catch(err => { + if (err.code !== 48) throw err; + return db.collection('testResults'); + }); + await db.createCollection('output').catch(err => { + if (err.code !== 48) throw err; + return db.collection('output'); + }); + await db.createCollection('auditLogs').catch(err => { + if (err.code !== 48) throw err; + return db.collection('auditLogs'); + }); + await db.createCollection('user').catch(err => { + if (err.code !== 48) throw err; + return db.collection('user'); + }); })() class Database { @@ -301,4 +313,4 @@ class UserDB extends Database { } } -module.exports = { TestResultsDB, OutputDB, BuildListDB, ApplicationTestsDB, AuditLogsDB, UserDB, ObjectID }; \ No newline at end of file +module.exports = { TestResultsDB, OutputDB, BuildListDB, ApplicationTestsDB, AuditLogsDB, UserDB, ObjectID }; diff --git a/TestResultSummaryService/Dockerfile b/TestResultSummaryService/Dockerfile index 369f3f3d..929eb811 100644 --- a/TestResultSummaryService/Dockerfile +++ b/TestResultSummaryService/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /usr/src/app COPY . . -EXPOSE 3001 +EXPOSE 3002 CMD npm ci &&\ npm start diff --git a/TestResultSummaryService/frontend.js b/TestResultSummaryService/frontend.js index c2b40596..95eee3ce 100644 --- a/TestResultSummaryService/frontend.js +++ b/TestResultSummaryService/frontend.js @@ -43,7 +43,7 @@ let options = { expressSwagger(options); // all environments -app.set( 'port', process.env.PORT || 3001 ); +app.set( 'port', process.env.PORT || 3002 ); app.listen( app.get( 'port' ), function() { logger.info( 'Express server listening on port ' + app.get( 'port' ) ); diff --git a/TestResultSummaryService/nginx.conf b/TestResultSummaryService/nginx.conf index 4f35644e..1c915445 100644 --- a/TestResultSummaryService/nginx.conf +++ b/TestResultSummaryService/nginx.conf @@ -14,11 +14,11 @@ server { server_name trss.adoptium.net; location ~ /api-docs { - proxy_pass http://localhost:3001; + proxy_pass http://localhost:3002; proxy_http_version 1.1; } location /api/ { - proxy_pass http://localhost:3001; + proxy_pass http://localhost:3002; proxy_http_version 1.1; } @@ -34,4 +34,4 @@ server { try_files $uri $uri/ /index.html; } -} \ No newline at end of file +} diff --git a/test-result-summary-client/package-lock.json b/test-result-summary-client/package-lock.json index 28accd46..27d23c8c 100644 --- a/test-result-summary-client/package-lock.json +++ b/test-result-summary-client/package-lock.json @@ -2312,6 +2312,96 @@ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.3.2.tgz", "integrity": "sha512-28A2j9DISNtHRcfc+FSCkxIAMnQoORQYz+UQLjc0+KlsGl80MqfbG3EzqXxzVmCMatlgmHfcX7/DBoMg+ik/Fg==" }, + "@emotion/cache": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz", + "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.0.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "^4.0.3" + } + }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/memoize": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + }, + "@emotion/react": { + "version": "11.4.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.1.tgz", + "integrity": "sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/cache": "^11.4.0", + "@emotion/serialize": "^1.0.2", + "@emotion/sheet": "^1.0.2", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", + "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + } + } + }, + "@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "requires": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + }, + "dependencies": { + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + } + } + }, + "@emotion/sheet": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.2.tgz", + "integrity": "sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", + "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -2617,6 +2707,11 @@ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", "dev": true }, + "@popperjs/core": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", + "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==" + }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", @@ -6019,9 +6114,9 @@ } }, "date-fns": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.22.1.tgz", - "integrity": "sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg==" + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.23.0.tgz", + "integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA==" }, "de-indent": { "version": "1.0.2", @@ -6438,6 +6533,35 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", + "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + } + } + }, "dom-scroll-into-view": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-1.2.1.tgz", @@ -11591,6 +11715,11 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, + "multiselect-react-dropdown": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/multiselect-react-dropdown/-/multiselect-react-dropdown-2.0.6.tgz", + "integrity": "sha512-PZxHLaGJnCq4a+7IESmP1eST1O1CgvFxaAeB6aMDoWL/UN2hBgk5WJRxEZSCxCTkNpnWBzjPwclCZYiU2zQDGg==" + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -15604,6 +15733,54 @@ "semver": "^5.6.0" } }, + "react-date-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-date-range/-/react-date-range-1.3.0.tgz", + "integrity": "sha512-ximAsbdf28tT7jMRLenSUeMacZ+s3opgvlUKbXIg7qvpehVfjlcYfQ3MF1C59rUghk44yckPsCxqPm0l8Lb+KA==", + "requires": { + "classnames": "^2.2.6", + "prop-types": "^15.7.2", + "react-list": "^0.8.13", + "shallow-equal": "^1.2.1" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "react-datepicker": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.2.1.tgz", + "integrity": "sha512-0gcvHMnX8rS1fV90PjjsB7MQdsWNU77JeVHf6bbwK9HnFxgwjVflTx40ebKmHV+leqe+f+FgUP9Nvqbe5RGyfA==", + "requires": { + "@popperjs/core": "^2.9.2", + "classnames": "^2.2.6", + "date-fns": "^2.0.1", + "prop-types": "^15.7.2", + "react-onclickoutside": "^6.10.0", + "react-popper": "^2.2.5" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-day-picker": { "version": "7.4.10", "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-7.4.10.tgz", @@ -15917,6 +16094,11 @@ "integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==", "dev": true }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "react-grid-layout": { "version": "0.16.6", "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-0.16.6.tgz", @@ -15954,6 +16136,14 @@ "prop-types": "^15.5.8" } }, + "react-input-autosize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz", + "integrity": "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==", + "requires": { + "prop-types": "^15.5.8" + } + }, "react-is": { "version": "16.11.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.11.0.tgz", @@ -16001,11 +16191,33 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-list": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.16.tgz", + "integrity": "sha512-LSxfvdwB9Ip+E+8NBtLPW2pcIngzuV0rSoH9nMt9C2lFjZEbnoBY/ib/Zx121jPgFgg3xYkMlMXSzx5gaiP5ig==", + "requires": { + "prop-types": "15" + } + }, "react-nl2br": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/react-nl2br/-/react-nl2br-0.6.1.tgz", "integrity": "sha512-DNUcFMO4j9MjpxPBe1qZf6h+VQ9vhCT5Nyn7vDQp32/gpFzuKaGmWzfk9gDJ8NS0ez9BTxKhqeflirC6sWH3aQ==" }, + "react-onclickoutside": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.11.2.tgz", + "integrity": "sha512-640486eSwU/t5iD6yeTlefma8dI3bxPXD93hM9JGKyYITAd0P1JFkkcDeyHZRqNpY/fv1YW0Fad9BXr44OY8wQ==" + }, + "react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + } + }, "react-resizable": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.7.5.tgz", @@ -16146,6 +16358,40 @@ } } }, + "react-select": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", + "integrity": "sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==", + "requires": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.1.1", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^3.0.0", + "react-transition-group": "^4.3.0" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", + "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + } + } + }, "react-table": { "version": "6.11.5", "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz", @@ -16156,6 +16402,32 @@ "react-is": "^16.8.1" } }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz", + "integrity": "sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -17243,6 +17515,11 @@ } } }, + "shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, "shallowequal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", @@ -18046,6 +18323,11 @@ } } }, + "stylis": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz", + "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/test-result-summary-client/package.json b/test-result-summary-client/package.json index 7e1bf473..077f17e0 100644 --- a/test-result-summary-client/package.json +++ b/test-result-summary-client/package.json @@ -7,6 +7,7 @@ "antd": "^4.16.3", "classnames": "^2.3.1", "codemirror": "^5.62.0", + "date-fns": "^2.23.0", "highcharts": "^9.1.2", "highcharts-react-official": "^2.2.2", "highstock-release": "^6.0.4", @@ -15,9 +16,12 @@ "mathjs": "^7.6.0", "mergely": "^4.3.1", "moment": "^2.29.1", + "multiselect-react-dropdown": "^2.0.6", "npm-check": "^5.9.2", "qs": "^6.10.1", "react": "^16.14.0", + "react-date-range": "^1.3.0", + "react-datepicker": "^4.2.1", "react-day-picker": "^7.4.10", "react-dom": "^16.14.0", "react-grid-layout": "^0.16.6", @@ -28,6 +32,7 @@ "react-nl2br": "^0.6.1", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", + "react-select": "^4.3.1", "react-table": "^6.11.5", "sweetalert2": "^10.16.9" }, @@ -36,7 +41,7 @@ "build": "react-app-rewired build", "test": "react-app-rewired test --env=jsdom" }, - "proxy": "http://localhost:3001", + "proxy": "http://localhost:3002", "devDependencies": { "react-app-rewired": "^2.1.8", "react-scripts": "^3.4.4" diff --git a/test-result-summary-client/src/App.jsx b/test-result-summary-client/src/App.jsx index 134be576..87870894 100644 --- a/test-result-summary-client/src/App.jsx +++ b/test-result-summary-client/src/App.jsx @@ -11,7 +11,7 @@ import { TestCompare } from './TestCompare/'; import { ThirdPartyAppView } from './ThirdPartyAppView/'; import { PerfCompare } from './PerfCompare/'; import { TabularView } from './TabularView/'; -import { AllTestsInfo, BuildDetail, DeepHistory, GitNewIssue, TestPerPlatform, PossibleIssues, TopLevelBuilds, ResultSummary, ReleaseSummary } from './Build/'; +import { AllTestsInfo, BuildDetail, DeepHistory, GitNewIssue, TestPerPlatform, PossibleIssues, TopLevelBuilds, ResultSummary, ReleaseSummary} from './Build/'; import { SearchResult } from './Search/'; import { Settings } from './Settings/'; @@ -54,6 +54,7 @@ export default class App extends Component { Dashboard Third Party Applications + By Version @@ -77,6 +78,7 @@ export default class App extends Component { + @@ -84,4 +86,4 @@ export default class App extends Component { } -} \ No newline at end of file +} diff --git a/test-result-summary-client/src/Build/BuildComparisonTable.js b/test-result-summary-client/src/Build/BuildComparisonTable.js new file mode 100644 index 00000000..23e658cf --- /dev/null +++ b/test-result-summary-client/src/Build/BuildComparisonTable.js @@ -0,0 +1,337 @@ +import React, { Component } from 'react'; +import { CheckOutlined, CloseOutlined, InfoOutlined, LoadingOutlined, QuestionCircleOutlined } from '@ant-design/icons'; +import { Table, Tooltip, Checkbox, Popconfirm } from 'antd'; +import { Link } from 'react-router-dom'; +import { params } from '../utils/query'; +import { fetchData, timeConversion } from '../utils/Utils'; +import BuildLink from './BuildLink'; +import { components } from "react-select"; +import { default as ReactSelect } from "react-select"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; + +const Option = (props) => { + return ( +
+ + null} + />{" "} + + +
+ ); +}; + +const pageSize = 5; +export default class BuildCompare extends Component { + + state = { + currentPage: 1, + buildInfo: [], + startDate: new Date(1610188860945), // earlier this year for demo + endDate: new Date(), + optionSelected: [{value: 'Select', label: 'select'}], + allColumns: [ + { + value: 'Select', + label: 'select', + }, { + value: 'Build', + label: 'build', + }, { + value: 'JDK Implementation', + label: 'impl', + }, { + value: 'JDK Version', + label: 'version', + }, { + value: 'Start Date', + label: 'date', + }, { + value: 'Platforms', + label: 'platform', + }, { + value: 'Vendor', + label: 'vendor', + }, { + value: 'Duration', + label: 'time', + } + ] + }; + + async componentDidMount() { + await this.updateData(); + } + + async componentDidUpdate(prevProps, prevState) { + if (prevProps.url !== this.props.url) { + await this.updateData(); + } + + if (prevState.currentPage !== this.state.currentPage) { + await this.updateTotals(); + } + } + + retrieveParams(buildParams) { + var params = {} + buildParams.forEach((dict)=> params[dict.name] = dict.value) + return params + } + + async updateData() { + const { buildUrlList } = this.props; + // consolidates all build information into the buildsList array + const buildsList = [] + for (let i = 0; buildUrlList && i < buildUrlList.length; i++) { + const buildName = buildUrlList[i][0]; + const url = buildUrlList[i][1]; + const builds = await fetchData(`/api/getBuildHistory?buildName=${buildName}&url=${url}&limit=120`); + for (let j = 0; builds && j < builds.length; j++) { + buildsList.push(builds[j]); + } + } + const info = buildsList.map(build => { + const params = this.retrieveParams(build.buildParams) + const date = build.timestamp ? new Date(build.timestamp) : null + return { + key: build._id, + build: build, + date: (date > this.state.startDate && date < this.state.endDate) ? date.toLocaleString() : null, + vendor: "N/A", + impl: params.JDK_IMPL, + version: params.JDK_VERSION, + platform: params.PLATFORM, + time: timeConversion(build.buildDuration) + }}); + + const buildInfo = info.filter(build => build.date) + this.setState({ buildInfo }); + + await this.updateTotals(); + } + + async updateTotals() { + let { buildInfo, currentPage } = this.state; + if (buildInfo) { + const { buildName, url } = this.props; + // only query getTotals if buildInfo does not have the data + const i = pageSize * (currentPage - 1); + + await Promise.all(buildInfo.slice(i, pageSize * currentPage).map(async build => { + if (build.totals) return; + const totals = await fetchData(`/api/getTotals?buildName=${buildName}&url=${url}&buildNum=${build.build.buildNum}`); + build.totals = totals; + })); + this.forceUpdate(); + } + } + + onChange = page => { + this.setState({ + currentPage: page, + }); + }; + + handleChange = (selected) => { + this.setState({ + optionSelected: selected + }); + }; + + editColumns = () =>{ + var options = this.state.allColumns; + return + }; + + async setStartDate (startDate){ + this.setState({startDate}) + await this.updateData(); + } + + async setEndDate(endDate){ + this.setState({endDate}) + await this.updateData(); + } + + dateRangePicker = () =>{ + return
+ Date Range: + this.setStartDate(new Date(date))} + /> + this.setEndDate(new Date(date))} + /> +
+ } + + render() { + const { buildInfo } = this.state; + const { buildName, url, type } = this.props; + if (buildInfo) { + const renderFvTestBuild = (value) => { + if (value && value.buildNum) { + let icon = ""; + if (value.status !== "Done") { + icon = ; + value.buildResult = "PROGRESSING" + } else if (value.buildResult === "SUCCESS") { + icon = ; + } else if (value.buildResult === "FAILURE") { + icon = ; + } else { + icon = ; + } + return
+ Build #{value.buildNum} {icon} + + +
{renderPublishName(value)} +
+ } + return null; + }; + + const renderBuild = (value) => { + if (value && value.buildNum) { + let result = value.buildResult; + if (value.tests && value.tests.length > 0) { + result = value.tests[0].testResult; + if (value.tests[0]._id) { + return
+ + Build #{value.buildNum} + +
; + } + } else { + return
+ Build #{value.buildNum} + +
; + } + } + return null; + }; + + const renderBuildResults = (value) => { + return
+ +
; + }; + + const renderPublishName = ({ buildParams = [] }) => { + if (buildParams) { + const param = buildParams.find(param => param.name === "overridePublishName"); + if (param) + return param.value; + } + return; + }; + + const columns=[ + { + title: 'Select', + dataIndex: 'select', + key: 'select', + render: (value, record) => { + return + + + } + }, { + title: 'Build', + dataIndex: 'build', + key: 'buildName', + render: renderBuildResults, + }, { + title: 'Vendor', + dataIndex: 'vendor', + key: 'vendorName', + }, { + title: 'JDK Implementation', + dataIndex: 'impl', + key: 'impl', + }, { + title: 'Platforms', + dataIndex: 'platform', + key: 'platform', + }, { + title: 'JDK Version', + dataIndex: 'version', + key: 'version', + sorter: (a, b) => { + return a.version.localeCompare(b.version); + } + }, { + title: 'Start Date', + dataIndex: 'date', + key: 'date', + sorter: (a, b) => { + return a.date.localeCompare(b.date); + }, + }, { + title: 'Duration', + dataIndex: 'time', + key: 'time', + sorter: (a, b) => { + return a.time.localeCompare(b.time); + } + } + ]; + + const getOptions =() => { + var activeOptions = []; + if (this.state.optionSelected.length < 2) { + const optionSelected = this.state.allColumns.slice(0,5) + this.setState({ optionSelected }) + } + columns.forEach(c => { + this.state.optionSelected.forEach(col => { + if (col.value === c.title) { activeOptions.push(c)} + }) + }) + return activeOptions + } + return
+ {this.dateRangePicker()} + {this.editColumns()} + ; + + } else { + return null; + } + } +} diff --git a/test-result-summary-client/src/Build/TopLevelBuilds.jsx b/test-result-summary-client/src/Build/TopLevelBuilds.jsx index b46ef719..b1a25cbf 100644 --- a/test-result-summary-client/src/Build/TopLevelBuilds.jsx +++ b/test-result-summary-client/src/Build/TopLevelBuilds.jsx @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import TopLevelBuildTable from './TopLevelBuildTable'; +import BuildComparisonTable from './BuildComparisonTable'; const { order, fetchData } = require('../utils/Utils'); export default class TopLevelBuilds extends Component { @@ -37,20 +38,24 @@ export default class TopLevelBuilds extends Component { this.setState({ builds, type }); } - - render() { const { builds, type } = this.state; + const pageUrl=this.props.location.pathname if (builds && type) { - return ( -
- {Object.keys(builds).sort().map((url, i) => { - return builds[url].sort(order).map((buildName, j) => { - return - }); - })} -
); + if( pageUrl !== "/build/compare" ) { + Object.keys(builds).sort().map((url, i) => { + return builds[url].sort(order).map((buildName, j) => { + return + }); + }) + } else { + const buildUrlList = []; + Object.keys(builds).map((url, index) => ( + buildUrlList.push([builds[url], url]) + )) + return + } } else { return null; } diff --git a/test-result-summary-client/src/Build/index.js b/test-result-summary-client/src/Build/index.js index 5ee77bed..c861a3e7 100644 --- a/test-result-summary-client/src/Build/index.js +++ b/test-result-summary-client/src/Build/index.js @@ -5,5 +5,6 @@ export { default as GitNewIssue } from "./GitNewIssue"; export { default as TestPerPlatform } from "./TestPerPlatform"; export { default as PossibleIssues } from "./PossibleIssues"; export { default as TopLevelBuilds } from "./TopLevelBuilds"; +export { default as BuildComparisonTable } from "./BuildComparisonTable"; export { default as ResultSummary } from "./Summary/ResultSummary"; export {default as ReleaseSummary} from "./ReleaseSummary"; diff --git a/test-result-summary-client/src/Build/table.css b/test-result-summary-client/src/Build/table.css index 112f1d1f..a95d0e1c 100644 --- a/test-result-summary-client/src/Build/table.css +++ b/test-result-summary-client/src/Build/table.css @@ -8,4 +8,4 @@ .card-body { word-break: break-all; white-space: pre-wrap; -} \ No newline at end of file +} diff --git a/test-result-summary-client/src/utils/Utils.js b/test-result-summary-client/src/utils/Utils.js index 28a59fd9..5d9581b4 100644 --- a/test-result-summary-client/src/utils/Utils.js +++ b/test-result-summary-client/src/utils/Utils.js @@ -58,3 +58,28 @@ export const fetchData = async(url) => { console.error(e); } } + +export function timeConversion(duration: number) { + const portions: string[] = []; + + const msInHour = 1000 * 60 * 60; + const hours = Math.trunc(duration / msInHour); + if (hours > 0) { + portions.push(hours + 'h'); + duration = duration - (hours * msInHour); + } + + const msInMinute = 1000 * 60; + const minutes = Math.trunc(duration / msInMinute); + if (minutes > 0) { + portions.push(minutes + 'm'); + duration = duration - (minutes * msInMinute); + } + + const seconds = Math.trunc(duration / 1000); + if (seconds > 0) { + portions.push(seconds + 's'); + } + + return portions.join(' '); +}