From cceda38d4906dd39764325fb64718b11efc3fd28 Mon Sep 17 00:00:00 2001 From: Itay Date: Mon, 14 Aug 2023 22:36:10 +0300 Subject: [PATCH 1/2] Completed report receiving updates from ongoing analysis --- CHANGELOG.md | 1 + .../app/src/report/actions/clear-report-actions.ts | 10 ++++++++++ packages/app/src/report/actions/init-report-action.ts | 3 --- .../app/src/report/actions/subscribe-report-action.ts | 3 --- packages/app/src/report/components/ReportPage.tsx | 5 +++++ 5 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 packages/app/src/report/actions/clear-report-actions.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 027ce8f..82630c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ _Can be run using `npm run codetotal:beta`_ - Add a button in report toolbar to show code for snippet & file analysis - Add a report progress bar - Optimize new analysis dialog, drawer and linters list components' renders + - Fix completed report receiving updates from ongoing analysis - Back-End - Bug fix: SBOM packages not showing up in report page. Async parsing of packages information in SBOM module - Retry calls to pypi or npm in case first attempts are failing diff --git a/packages/app/src/report/actions/clear-report-actions.ts b/packages/app/src/report/actions/clear-report-actions.ts new file mode 100644 index 0000000..b793d69 --- /dev/null +++ b/packages/app/src/report/actions/clear-report-actions.ts @@ -0,0 +1,10 @@ +import { ReportStore } from "../stores/fe-report-store"; + +export const clearReport = () => { + const { unsubscribe, reset } = ReportStore.getState(); + // unsubscribe from updates + unsubscribe && unsubscribe(); + + // reset state + reset(); +}; diff --git a/packages/app/src/report/actions/init-report-action.ts b/packages/app/src/report/actions/init-report-action.ts index 75c4f64..02ca45a 100644 --- a/packages/app/src/report/actions/init-report-action.ts +++ b/packages/app/src/report/actions/init-report-action.ts @@ -6,9 +6,6 @@ import { subscribeToReportProgress } from "./subscribe-report-action"; export const initReport = async (requestId: string) => { try { - // reset report store - ReportStore.getState().reset(); - // fetch report const res = await axios.get(`${ApiUrl}/report/${requestId}`); diff --git a/packages/app/src/report/actions/subscribe-report-action.ts b/packages/app/src/report/actions/subscribe-report-action.ts index 661fa59..5be4472 100644 --- a/packages/app/src/report/actions/subscribe-report-action.ts +++ b/packages/app/src/report/actions/subscribe-report-action.ts @@ -5,9 +5,6 @@ import { subscribe } from "../utils/ws-client"; let unsubscribe: () => void; export const subscribeToReportProgress = (requestId: string) => { - // unsubscribe from previous connection - unsubscribe && unsubscribe(); - // clear previous error ReportStore.setState({ wsError: undefined }); diff --git a/packages/app/src/report/components/ReportPage.tsx b/packages/app/src/report/components/ReportPage.tsx index 7362f93..530f378 100644 --- a/packages/app/src/report/components/ReportPage.tsx +++ b/packages/app/src/report/components/ReportPage.tsx @@ -1,6 +1,7 @@ import { FC, useEffect } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { AnalysisErrorDialog } from "../../common/AnalysisErrorDialog"; +import { clearReport } from "../actions/clear-report-actions"; import { initReport } from "../actions/init-report-action"; import { LinterDrawer } from "./drawer/LinterDrawer"; import { CodeDialog } from "./header/CodeDialog"; @@ -24,6 +25,10 @@ const ReportPage: FC = () => { })(); }, [requestId, navigate]); + useEffect(() => { + return clearReport; + }); + return (
From 42793a7a5be3c52bade1d5fc3e7b00e7726e73f1 Mon Sep 17 00:00:00 2001 From: Itay Date: Tue, 15 Aug 2023 17:38:58 +0300 Subject: [PATCH 2/2] WIP --- package-lock.json | 274 +++++++++++++++++- packages/app/package.json | 2 + .../src/analysis/components/SubmitButton.tsx | 1 + packages/app/src/common/hooks/usePrevious.ts | 11 + .../app/src/report/components/ReportPage.tsx | 2 + .../components/SuccessfulAnalysisNotice.tsx | 146 ++++++++++ .../app/src/report/stores/fe-report-store.ts | 4 +- packages/shared-types/src/report-types.ts | 2 +- 8 files changed, 435 insertions(+), 7 deletions(-) create mode 100644 packages/app/src/common/hooks/usePrevious.ts create mode 100644 packages/app/src/report/components/SuccessfulAnalysisNotice.tsx diff --git a/package-lock.json b/package-lock.json index 19cf64a..9acef0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4475,6 +4475,11 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/js-cookie": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" + }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -5103,6 +5108,11 @@ "@xtuc/long": "4.2.2" } }, + "node_modules/@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6546,6 +6556,14 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core-js-compat": { "version": "3.31.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz", @@ -6642,6 +6660,14 @@ "node": "*" } }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -7332,6 +7358,14 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, "node_modules/es-abstract": { "version": "1.21.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", @@ -8331,8 +8365,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.0", @@ -8374,6 +8407,21 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-loops": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz", + "integrity": "sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==" + }, + "node_modules/fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, + "node_modules/fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==" + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -9091,6 +9139,11 @@ "node": ">=10.17.0" } }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9213,6 +9266,15 @@ "node": ">=10" } }, + "node_modules/inline-style-prefixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz", + "integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==", + "dependencies": { + "css-in-js-utils": "^3.1.0", + "fast-loops": "^1.1.3" + } + }, "node_modules/inquirer": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", @@ -11400,6 +11462,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12133,6 +12200,50 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/nano-css": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz", + "integrity": "sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==", + "dependencies": { + "css-tree": "^1.1.2", + "csstype": "^3.0.6", + "fastest-stable-stringify": "^2.0.2", + "inline-style-prefixer": "^6.0.0", + "rtl-css-js": "^1.14.0", + "sourcemap-codec": "^1.4.8", + "stacktrace-js": "^2.0.2", + "stylis": "^4.0.6" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/nano-css/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nano-css/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/nano-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -13335,6 +13446,20 @@ "node": ">=0.10.0" } }, + "node_modules/react-confetti": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-6.1.0.tgz", + "integrity": "sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==", + "dependencies": { + "tween-functions": "^1.2.0" + }, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "react": "^16.3.0 || ^17.0.1 || ^18.0.0" + } + }, "node_modules/react-countup": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/react-countup/-/react-countup-6.4.2.tgz", @@ -13462,6 +13587,45 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-universal-interface": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", + "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", + "peerDependencies": { + "react": "*", + "tslib": "*" + } + }, + "node_modules/react-use": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.4.0.tgz", + "integrity": "sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==", + "dependencies": { + "@types/js-cookie": "^2.2.6", + "@xobotyi/scrollbar-width": "^1.9.5", + "copy-to-clipboard": "^3.3.1", + "fast-deep-equal": "^3.1.3", + "fast-shallow-equal": "^1.0.0", + "js-cookie": "^2.2.1", + "nano-css": "^5.3.1", + "react-universal-interface": "^0.6.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.1.0", + "set-harmonic-interval": "^1.0.1", + "throttle-debounce": "^3.0.1", + "ts-easing": "^0.2.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-use/node_modules/tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -13674,6 +13838,11 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -13797,6 +13966,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/rtl-css-js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", + "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "dependencies": { + "@babel/runtime": "^7.1.2" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -13908,6 +14085,17 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/screenfull": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", + "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/semver": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", @@ -14006,6 +14194,14 @@ "node": ">= 0.8.0" } }, + "node_modules/set-harmonic-interval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", + "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "engines": { + "node": ">=6.9" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -14183,6 +14379,12 @@ "node": ">=0.10.0" } }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, "node_modules/space-separated-tokens": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", @@ -14266,6 +14468,14 @@ "node": ">=0.10.0" } }, + "node_modules/stack-generator": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", + "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -14287,6 +14497,38 @@ "node": ">=8" } }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/stacktrace-gps": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", + "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "dependencies": { + "source-map": "0.5.6", + "stackframe": "^1.3.4" + } + }, + "node_modules/stacktrace-gps/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "dependencies": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -14691,6 +14933,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "engines": { + "node": ">=10" + } + }, "node_modules/throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -14747,6 +14997,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -14791,6 +15046,11 @@ "node": ">= 4.0.0" } }, + "node_modules/ts-easing": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==" + }, "node_modules/ts-jest": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", @@ -14904,8 +15164,7 @@ "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/tss-react": { "version": "4.8.6", @@ -15050,6 +15309,11 @@ "win32" ] }, + "node_modules/tween-functions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", + "integrity": "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==" + }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -15997,6 +16261,7 @@ "md5": "^2.3.0", "monaco-editor": "^0.40.0", "react": "^18.2.0", + "react-confetti": "^6.1.0", "react-countup": "^6.4.2", "react-csv": "^2.2.2", "react-dom": "^18.2.0", @@ -16004,6 +16269,7 @@ "react-icons": "^4.10.1", "react-router-dom": "^6.13.0", "react-syntax-highlighter": "^15.5.0", + "react-use": "^17.4.0", "shared-types": "^1.0.0", "tss-react": "^4.8.6", "zustand": "^4.3.8" diff --git a/packages/app/package.json b/packages/app/package.json index af2bb36..65e0224 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -20,6 +20,7 @@ "md5": "^2.3.0", "monaco-editor": "^0.40.0", "react": "^18.2.0", + "react-confetti": "^6.1.0", "react-countup": "^6.4.2", "react-csv": "^2.2.2", "react-dom": "^18.2.0", @@ -27,6 +28,7 @@ "react-icons": "^4.10.1", "react-router-dom": "^6.13.0", "react-syntax-highlighter": "^15.5.0", + "react-use": "^17.4.0", "shared-types": "^1.0.0", "tss-react": "^4.8.6", "zustand": "^4.3.8" diff --git a/packages/app/src/analysis/components/SubmitButton.tsx b/packages/app/src/analysis/components/SubmitButton.tsx index 156ae3c..7eeff3b 100644 --- a/packages/app/src/analysis/components/SubmitButton.tsx +++ b/packages/app/src/analysis/components/SubmitButton.tsx @@ -6,6 +6,7 @@ export const SubmitButton: FC = ({ loading, ...props }) => { return (
); }; diff --git a/packages/app/src/report/components/SuccessfulAnalysisNotice.tsx b/packages/app/src/report/components/SuccessfulAnalysisNotice.tsx new file mode 100644 index 0000000..665e3bc --- /dev/null +++ b/packages/app/src/report/components/SuccessfulAnalysisNotice.tsx @@ -0,0 +1,146 @@ +import { Fade, Theme, darken, keyframes } from "@mui/material"; +import { FC, useEffect, useState } from "react"; +import Confetti from "react-confetti"; +import { createPortal } from "react-dom"; +import { IoCloseOutline } from "react-icons/io5"; +import { AnalysisStatus } from "shared-types"; +import { makeStyles } from "tss-react/mui"; +import { usePrevious } from "../../common/hooks/usePrevious"; +import { useReportStore } from "../stores/fe-report-store"; + +export const SuccessfulAnalysisNotice: FC = () => { + const { classes } = useStyles(); + const { progress, status, score } = useReportStore(); + const prevStatus = usePrevious(status); + const [show, setShow] = useState(false); + + useEffect(() => { + const noRisksFound = score === 0; + const completed = status === AnalysisStatus.Completed; + const justChanged = prevStatus === AnalysisStatus.Created; + + if (justChanged && completed && noRisksFound) { + setShow(true); + setTimeout(() => { + setShow(false); + }, 10000); + } + }, [prevStatus, progress, status, score]); + + const handleClose = () => { + setShow(false); + }; + + return createPortal( + +
+
+ 🥰 +
+ You Rock! +
+ No Issues Found +
+ +
+ + Close +
+
+
, + document.body + ); +}; + +const useStyles = makeStyles()((theme: Theme) => ({ + container: { + position: "fixed", + width: "100%", + height: "100%", + top: 0, + left: 0, + overflow: "hidden", + zIndex: 11, + display: "grid", + placeItems: "center", + background: "#000000AA", + }, + circle: { + width: 300, + height: 300, + display: "grid", + placeItems: "center", + background: `radial-gradient(${darken(theme.palette.success.light, 0.2)}, ${ + theme.palette.success.light + })`, + color: theme.palette.common.white, + borderRadius: "50%", + fontSize: 30, + textAlign: "center", + boxShadow: `0 0 25px 5px ${theme.palette.divider}`, + zIndex: 20, + "&:before": { + zIndex: -1, + position: "absolute", + transformOrigin: "center center", + content: "''", + width: 300, + height: 300, + display: "block", + borderRadius: "50%", + backgroundColor: theme.palette.success.light, + animation: `${keyframes` + 0% { + opacity: .5; + transform: scale(1); + } + 100% { + opacity: 0; + transform: scale(1.5); + } + `} 2s infinite ease-in-out`, + }, + }, + closeButton: { + display: "flex", + flexDirection: "row-reverse", + // gap: theme.spacing(2), + alignItems: "center", + justifyContent: "center", + minWidth: "4rem", + height: "4rem", + // overflow: "hidden", + position: "absolute", + borderRadius: "100vh", + right: theme.spacing(2), + bottom: theme.spacing(2), + backgroundColor: theme.palette.primary.main, + color: theme.palette.common.white, + transition: theme.transitions.create("width"), + fontSize: 20, + paddingInline: theme.spacing(2), + cursor: "pointer", + + "& > svg": { + width: "2rem", + height: "2rem", + }, + + "& > span": { + transform: "scaleX(0)", + transition: theme.transitions.create("all"), + width: 0, + }, + "&:hover, &:focus": { + backgroundColor: theme.palette.primary.main, + "& > span": { + width: "4rem", + transform: "scaleX(1)", + }, + }, + }, +})); diff --git a/packages/app/src/report/stores/fe-report-store.ts b/packages/app/src/report/stores/fe-report-store.ts index 3a686d4..21288aa 100644 --- a/packages/app/src/report/stores/fe-report-store.ts +++ b/packages/app/src/report/stores/fe-report-store.ts @@ -1,10 +1,10 @@ -import { AnalysisStatus, Issue, ReportState } from "shared-types"; +import { Issue, ReportState } from "shared-types"; import { createStore, useStore } from "zustand"; import { ScoreColorKey } from "../fe-report-types"; import { resolveScoreColor } from "../utils/score-utils"; const initialState: InitialState = { - status: AnalysisStatus.Created, + status: undefined, linters: [], packages: [], score: 0, diff --git a/packages/shared-types/src/report-types.ts b/packages/shared-types/src/report-types.ts index 1b0ab1f..377f3a6 100644 --- a/packages/shared-types/src/report-types.ts +++ b/packages/shared-types/src/report-types.ts @@ -6,7 +6,7 @@ export interface ReportState { requestId?: string; resourceType?: string; resourceValue?: string; - status: AnalysisStatus; + status?: AnalysisStatus; linters?: Linter[]; packages: SbomPackage[]; repoDetails?: RepoDetails;