diff --git a/.env.sample b/.env.sample index 464fe4d50..d6cb21ccc 100644 --- a/.env.sample +++ b/.env.sample @@ -1,7 +1,7 @@ # following keys are required #backend endpoint -REACT_APP_SERVER_URL=localhost/repo/api/v1 +REACT_APP_SERVER_URL=localhost/repo/api/v2 #for enabling https for backend url REACT_APP_HTTPS=false diff --git a/.eslintrc.json b/.eslintrc.json index 340a1a320..5c9d93158 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -34,7 +34,9 @@ } ], "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }], + "prefer-destructuring": ["error", { "object": true, "array": false }], "react/require-default-props": 0, - "jsx-a11y/control-has-associated-label": 0 + "jsx-a11y/control-has-associated-label": 0, + "react/jsx-props-no-spreading": 0 } } diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 933072508..870b0df6e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -38,7 +38,7 @@ jobs: - name: Build pages env: PUBLIC_URL: /FOSSologyUI - REACT_APP_SERVER_URL: localhost/repo/api/v1 + REACT_APP_SERVER_URL: localhost/repo/api/v2 REACT_APP_HTTPS: false run: yarn build diff --git a/README.md b/README.md index 7b9fbca3a..60be3f800 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,7 @@ The UI Migration project is an effort focused on generating the new component-ba ## Requirements -NodeJS and NPM or yarn\ -[https://nodejs.org/en/download/](https://nodejs.org/en/download/) -[https://yarnpkg.com/getting-started/install](https://yarnpkg.com/getting-started/install) +- [NodeJS](https://nodejs.org/en/download/) and NPM or [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable) ## Installation @@ -43,7 +41,7 @@ Run the following commands inside the project directory. ```sh docker build \ -t fossologyui:react1.0 \ ---build-arg REACT_APP_SERVER_URL="localhost/repo/api/v1" \ +--build-arg REACT_APP_SERVER_URL="localhost/repo/api/v2" \ --build-arg REACT_APP_HTTPS="false" . ``` @@ -51,37 +49,42 @@ docker build \ docker run -p 3000:3000 fossologyui:react1.0 ``` -The docker image can then be used using http://IP_OF_DOCKER_HOST:3000/ user fossy password fossy. +The docker image can then be used using `http://IP_OF_DOCKER_HOST:3000/` user `fossy` password `fossy`. -
+### Project Setup -In the project directory, you can run: +- Create a `.env` in root directory of project and copy the contents from `.env.sample` -create a `.env` in root directory of project and copy the contents from `.env.sample` +- Installs the packages: -#### `yarn` - -#### `yarn start` +```sh + yarn +``` -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +- Runs the app in the development mode at [http://localhost:3000](http://localhost:3000) -The page will reload if you make edits.\ -You will also see any lint errors in the console. +```sh +yarn start +``` -#### `yarn test` +### Deployment -Launches the test runner in the interactive watch mode.\ +Launches the test runner in the interactive watch mode. See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. -#### `yarn build` +```sh +yarn test +``` + +Builds the app for production to the `build` folder. -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. +```sh +yarn build +``` -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! +It correctly bundles React in production mode and optimizes the build for the best performance. +The build is minified and the filenames include the hashes. Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. ## Support diff --git a/package.json b/package.json index f34b05944..3c99b71dc 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react-helmet": "^6.1.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", + "react-table": "^7.7.0", "react-virtualized": "^9.22.3", "react-virtualized-tree": "^3.4.1", "styled-components": "^5.3.0", @@ -83,6 +84,7 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-react-hooks": "^1.7.0", + "jest-fetch-mock": "3.0.3", "prettier": "^2.3.1" } } diff --git a/src/App.jsx b/src/App.jsx index c17cd6e57..b48f37776 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -35,13 +35,18 @@ import "react-virtualized-tree/lib/main.css"; import "styles/global.css"; import GlobalStyles from "styles/globalStyle"; +// useAlert hook provider +import AlertProvider from "components/Widgets/AlertProvider"; + function App() { const { theme } = useContext(GlobalContext); return ( - - + + + + ); diff --git a/src/Routes.jsx b/src/Routes.jsx index ea4f24110..09ace567d 100644 --- a/src/Routes.jsx +++ b/src/Routes.jsx @@ -18,231 +18,295 @@ // React imports import React from "react"; +import routes from "constants/routes"; import { BrowserRouter, Switch, Route } from "react-router-dom"; // Guards imports -import PublicLayout from "shared/PublicLayout"; -import PrivateLayout from "shared/PrivateLayout"; -import AdminLayout from "shared/AdminLayout"; +const PublicLayout = React.lazy(() => import("shared/PublicLayout")); +const PrivateLayout = React.lazy(() => import("shared/PrivateLayout")); +const AdminLayout = React.lazy(() => import("shared/AdminLayout")); // Pages imports -import Home from "pages/Home"; -import Search from "pages/Search"; -import Browse from "pages/Browse"; +const Home = React.lazy(() => import("pages/Home")); +const Search = React.lazy(() => import("pages/Search")); +const Browse = React.lazy(() => import("pages/Browse")); + +// Browse Upload pages imports +const SoftwareHeritage = React.lazy(() => + import("pages/BrowseUploads/SoftwareHeritage") +); +const LicenseBrowse = React.lazy(() => + import("pages/BrowseUploads/LicenseBrowser") +); +const FileBrowser = React.lazy(() => import("pages/BrowseUploads/FileBrowser")); +const CopyrightBrowser = React.lazy(() => + import("pages/BrowseUploads/Copyright") +); +const Ecc = React.lazy(() => import("pages/BrowseUploads/Ecc")); // Help Pages -import About from "pages/Help/About"; -import Overview from "pages/Help/Overview"; -import LicenseBrowser from "pages/Help/LicenseBrowser"; -import ThirdPartyLicenses from "pages/Help/ThirdPartyLicenses"; +const About = React.lazy(() => import("pages/Help/About")); +const Overview = React.lazy(() => import("pages/Help/Overview")); +const LicenseBrowser = React.lazy(() => import("pages/Help/LicenseBrowser")); +const ThirdPartyLicenses = React.lazy(() => + import("pages/Help/ThirdPartyLicenses") +); // Upload Pages -import UploadFile from "pages/Upload/File"; -import UploadFromServer from "pages/Upload/Server"; -import UploadFromVcs from "pages/Upload/Vcs"; -import UploadFromUrl from "pages/Upload/Url"; -import ImportReport from "pages/Upload/ImportReport"; -import Instructions from "pages/Upload/Instructions"; -import OneShotAnalysis from "pages/Upload/OneShotAnalysis"; -import OneShotCopyright from "pages/Upload/OneShotCopyright"; -import OneShotMonk from "pages/Upload/OneShotMonk"; +const UploadFile = React.lazy(() => import("pages/Upload/File")); +const UploadFromServer = React.lazy(() => import("pages/Upload/Server")); +const UploadFromVcs = React.lazy(() => import("pages/Upload/Vcs")); +const UploadFromUrl = React.lazy(() => import("pages/Upload/Url")); +const ImportReport = React.lazy(() => import("pages/Upload/ImportReport")); +const Instructions = React.lazy(() => import("pages/Upload/Instructions")); +const OneShotAnalysis = React.lazy(() => + import("pages/Upload/OneShotAnalysis") +); +const OneShotCopyright = React.lazy(() => + import("pages/Upload/OneShotCopyright") +); +const OneShotMonk = React.lazy(() => import("pages/Upload/OneShotMonk")); // Jobs Pages -import AllJobs from "pages/Jobs/AllJobs"; -import MyRecentJobs from "pages/Jobs/MyRecentJobs"; -import ScheduleAgents from "pages/Jobs/ScheduleAgents"; +const AllJobs = React.lazy(() => import("pages/Jobs/AllJobs")); +const MyRecentJobs = React.lazy(() => import("pages/Jobs/MyRecentJobs")); +const ScheduleAgents = React.lazy(() => import("pages/Jobs/ScheduleAgents")); // Organize Pages -import DeleteFolder from "pages/Organize/Folder/Delete"; -import CreateFolder from "pages/Organize/Folder/Create"; -import EditFolder from "pages/Organize/Folder/Edit"; -import MoveFolder from "pages/Organize/Folder/Move"; -import UnlinkFolder from "pages/Organize/Folder/Unlink"; -import AdviceLicenses from "pages/Organize/License/CandidateLicense"; -import AddCandidateLicense from "pages/Organize/License/Create"; -import UploadEdit from "pages/Organize/Uploads/Edit"; -import UploadMove from "pages/Organize/Uploads/Move"; -import UploadDelete from "pages/Organize/Uploads/Delete"; +const DeleteFolder = React.lazy(() => import("pages/Organize/Folder/Delete")); +const CreateFolder = React.lazy(() => import("pages/Organize/Folder/Create")); +const EditFolder = React.lazy(() => import("pages/Organize/Folder/Edit")); +const MoveFolder = React.lazy(() => import("pages/Organize/Folder/Move")); +const UnlinkFolder = React.lazy(() => import("pages/Organize/Folder/Unlink")); +const AdviceLicenses = React.lazy(() => + import("pages/Organize/License/CandidateLicense") +); +const AddCandidateLicense = React.lazy(() => + import("pages/Organize/License/Create") +); +const UploadEdit = React.lazy(() => import("pages/Organize/Uploads/Edit")); +const UploadMove = React.lazy(() => import("pages/Organize/Uploads/Move")); +const UploadDelete = React.lazy(() => import("pages/Organize/Uploads/Delete")); // Admin Pages -import GroupCreate from "pages/Admin/Group/Create"; -import DeleteUser from "pages/Admin/Users/Delete"; -import AddLicense from "pages/Admin/License/Create"; -import SelectLicense from "pages/Admin/License/SelectLicense"; +const GroupCreate = React.lazy(() => import("pages/Admin/Group/Create")); +const DeleteUser = React.lazy(() => import("pages/Admin/Users/Delete")); +const AddLicense = React.lazy(() => import("pages/Admin/License/Create")); +const SelectLicense = React.lazy(() => + import("pages/Admin/License/SelectLicense") +); // Default Page -import ErrorPage from "pages/ErrorPage"; +const ErrorPage = React.lazy(() => import("pages/ErrorPage")); -// Routes imports -import routes from "constants/routes"; +// Footer +const Footer = React.lazy(() => import("components/Footer")); const Routes = () => { return ( - - - {/* Home Page */} - - - {/* Search Page */} - - - {/* Browse Page */} - - - {/* Help Pages */} - - - - - - {/* Upload Pages */} - - - - - - - - - - - {/* Jobs Page */} - - - - - {/* Organize pages */} - - - - - - - - - - - - {/* Admin Page */} - - - - - - {/* Default Page */} - - - - - + <> + + + {/* Home Page */} + + + {/* Search Page */} + + + {/* Browse Page */} + + + {/* Browse Uploads Pages */} + + + + + + + {/* Help Pages */} + + + + + + {/* Upload Pages */} + + + + + + + + + + + {/* Jobs Page */} + + + + + {/* Organize pages */} + + + + + + + + + + + + {/* Admin Page */} + + + + + + {/* Default Page */} + + + + + +