diff --git a/.circleci/config.yml b/.circleci/config.yml index c9e617be81..00c1875ad7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,23 +2,47 @@ version: 2 jobs: build_PROD: docker: - - image: cimg/node:14.17.0 + - image: cimg/node:14.21.3 resource_class: large steps: - checkout + - restore_cache: + keys: + - v1-prod-dependencies-{{ checksum "package-lock.json" }} - run: - name: npm install + name: Install HighestGoodNetworkApp's NodeJS dependencies command: 'sudo npm install' - run: name: Run react build command: 'sudo REACT_APP_APIENDPOINT=$APIENDPOINT_PROD REACT_APP_DEF_PWD=$REACT_APP_DEF_PWD REACT_APP_SENTRY_URL=$SENTRY_URL_PROD SKIP_PREFLIGHT_CHECK=true NODE_OPTIONS=$NODE_OPTIONS npm run build && sudo mv build/index.html build/200.html' + - run: + name: Export error log if 'Build the React client' failed + command: | + mkdir -p /tmp/err_logs + cp -r /home/circleci/.npm/_logs/* /tmp/err_logs + when: on_fail + - store_artifacts: + path: /tmp/err_logs + - run: + name: Create ZIP archive of build directory + command: zip -r build.zip build + - run: + name: Calculate SHA256 hash of build.zip and place output into build/hash.txt + command: sha256sum build.zip > build/hash.txt + - run: + name: Create 200.html for (required for client-side routing support on Surge) + command: cp build/index.html build/200.html - run: name: Deploy app - command: ./node_modules/.bin/surge build --domain $SURGE_DOMAIN_PROD + command: ./node_modules/.bin/surge --domain $SURGE_DOMAIN_PROD --project ./build + - save_cache: + key: v1-prod-dependencies-{{ checksum "package-lock.json" }} + paths: + - ./node_modules build_development: docker: - # Change from Ubnutu to cimg/node:14.21.3. + # Change from ubuntu:20.04 to cimg/node:14.21.3. # cimg convient image comes with node, yarn, and other pre-installed software. # This will remove the steps of install node, yarn, and other software. - image: cimg/node:14.21.3 @@ -27,7 +51,7 @@ jobs: - checkout - restore_cache: keys: - # Update the key to v1.1-dependencies-{{ checksum "package-lock.json" }} since the base image switched. + # Update the key from v1-dependencies-{{ checksum "package-lock.json" }} to v1.1-dependencies-{{ checksum "package-lock.json" }} since the base image switched. # Otherwise, we would have persmission issues while retriving the cache saved from the preivous image - v1.1-dependencies-{{ checksum "package-lock.json" }} - run: @@ -63,37 +87,28 @@ jobs: build_beta: docker: - - image: ubuntu:20.04 + # - image: ubuntu:20.04 + - image: cimg/node:14.21.3 resource_class: large steps: - checkout - - run: - name: Install ubuntu updates - command: apt-get update && apt-get upgrade -y - - run: - name: Install curl and zip - command: apt-get install curl zip -y - - run: - name: Download and execute Node.js 14.x install script from node source - command: curl -sL https://deb.nodesource.com/setup_14.x | bash - - - run: - name: Install Node.js and NPM - command: apt-get install nodejs -y - - run: - name: Download and execute Yarn istallation script - command: curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null - - run: - name: Add yarn to sources.list - command: echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list - - run: - name: Install yarn - command: apt-get install yarn -y + - restore_cache: + keys: + - v1-beta-dependencies-{{ checksum "package-lock.json" }} - run: name: Install HighestGoodNetworkApp's NodeJS dependencies command: npm install - run: name: Build the React client command: export REACT_APP_APIENDPOINT=$APIENDPOINT_BETA REACT_APP_DEF_PWD=$REACT_APP_DEF_PWD SKIP_PREFLIGHT_CHECK=true NODE_OPTIONS=$NODE_OPTIONS && npm run build + - run: + name: Export error log if 'Build the React client' failed + command: | + mkdir -p /tmp/err_logs + cp -r /home/circleci/.npm/_logs/* /tmp/err_logs + when: on_fail + - store_artifacts: + path: /tmp/err_logs - run: name: Create ZIP archive of build directory command: zip -r build.zip build @@ -109,6 +124,10 @@ jobs: - run: name: Deploy compiled app to surge.sh on highestgood.com command: ./node_modules/.bin/surge --domain highestgood.com --project ./build + - save_cache: + key: v1-beta-dependencies-{{ checksum "package-lock.json" }} + paths: + - ./node_modules workflows: version: 2 diff --git a/.eslintignore b/.eslintignore index cd72fa0ebf..e40056162f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -12,16 +12,16 @@ src/styles.js src/utils/** src/__tests__/** - - +/public/ +/build/ +/node_modules/ src/components/App.jsx src/components/AutoReload/** +src/components/Badge/** src/components/common/** src/components/Header/** src/components/BMDashboard/BMHeader/** src/components/MonthlyEffort/** - -src/components/PermissionsManagement/** src/components/ProfileLinks/** src/components/Projects/** src/components/Reports/** @@ -33,7 +33,6 @@ src/components/TeamMemberTasks/** src/components/Teams/** src/components/TeamLocations/** src/components/Timelog/** -src/components/UpdatePassword/** src/components/UserManagement/** src/components/UserProfile/** src/components/Announcements/** diff --git a/.eslintrc.js b/.eslintrc.js index eaac765631..49275af70a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,19 +41,21 @@ module.exports = { rules: { 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }], 'no-underscore-dangle': 'off', - 'react/destructuring-assignment': 'off', 'react/prop-types': 'off', - 'react/no-array-index-key': 'off', 'react-hooks/exhaustive-deps': 'off', 'react/jsx-key': 'off', 'react/jsx-uses-react': 'off', 'react/display-name': 'off', 'react/no-direct-mutation-state': 'off', 'react/no-unknown-property': 'off', + 'react/destructuring-assignment': 'off', 'react/react-in-jsx-scope': 'off', 'import/no-duplicates': 'off', 'import/no-named-as-default': 'off', - 'no-alert': 'off', + 'jsx-a11y/label-has-associated-control': 'off', + 'jsx-a11y/no-static-element-interactions': 'off', + 'jsx-a11y/click-events-have-key-events': 'off', + 'no-alert': 'error', 'no-console': 'error', 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], }, diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4816bd1e20..0d07ba530c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -21,6 +21,7 @@ To test this backend PR you need to checkout the #XXX frontend PR. 4. log as admin user 5. go to dashboard→ Tasks→ task→… 6. verify function “A” (feel free to include screenshot here) +7. verify this new feature works in [dark mode](https://docs.google.com/document/d/11OXJfBBedK6vV-XvqWR8A9lOH0BsfnaHx01h1NZZXfI) ## Screenshots or videos of changes: diff --git a/.gitignore b/.gitignore index 8db17c55b0..a25bca638b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ yarn-error.log* .vscode/launch.json -**\ ** \ No newline at end of file +**\ ** + +/public/tinymce/ \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 75fac8e186..cedf192dbc 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -2,3 +2,4 @@ . "$(dirname -- "$0")/_/husky.sh" npm run lint +npm run test \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index e23c88a2aa..bd518e1332 100644 --- a/.prettierignore +++ b/.prettierignore @@ -18,14 +18,11 @@ src/__tests__/** src/components/App.jsx src/components/AutoReload/** -src/components/common/** src/components/Header/** src/components/Inventory/** src/components/Memberships/** src/components/MonthlyEffort/** src/components/NewProfileLink/** - -src/components/PermissionsManagement/** src/components/ProfileLinks/** src/components/Projects/** src/components/Reports/** @@ -37,7 +34,6 @@ src/components/TeamLocations/** src/components/TeamMemberTasks/** src/components/Teams/** src/components/Timelog/** -src/components/UpdatePassword/** src/components/UserManagement/** src/components/UserProfile/** src/components/Announcements/** diff --git a/README.md b/README.md index 5883340f44..d9126aa49d 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,11 @@ For setting up your project locally, please get a local copy up and running foll ```sh npm install ``` -3. Get your `.env` file ready and start the app +3. Run the `postinstall` script to copy TinyMCE to the public directory + ```sh + npm run postinstall + ``` +4. Get your `.env` file ready and start the app ```sh npm run start:local ``` @@ -131,6 +135,18 @@ Don't forget to give the project a star! Thanks again!
+ + +## Software License Agreement + +In this project, we are using TinyMCE (licensed under GPLv2 or later) as our rich text editor. This means that if you distribute this project (including TinyMCE), you must also comply with the terms of the GPLv2 license. [Read more](https://github.com/tinymce/tinymce/blob/main/LICENSE.md) + +**We encourage you to review the license terms.** + + [![License: GPL v2](https://img.shields.io/badge/License-GPL_v2-blue.svg)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) + + + ## Contact diff --git a/package-lock.json b/package-lock.json index b2324871a8..347d388356 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9248,20 +9248,19 @@ } }, "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "dependencies": { "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" } } }, @@ -11767,9 +11766,9 @@ }, "dependencies": { "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" } } }, @@ -12051,8 +12050,7 @@ "lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==" }, "magic-string": { "version": "0.25.9", @@ -15970,6 +15968,17 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "jest-circus": { "version": "26.6.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.6.0.tgz", @@ -16040,6 +16049,11 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" } } }, @@ -18811,9 +18825,9 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "tinymce": { - "version": "5.10.8", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.8.tgz", - "integrity": "sha512-iyoo3VGMAJhLMDdblAefKvYgBRk9kQi58GTwAmoieqsyggGsKZWlQl/YY6nTILFHUCA1FhYu0HdmM5YYjs17UQ==" + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.9.tgz", + "integrity": "sha512-5bkrors87X9LhYX2xq8GgPHrIgJYHl87YNs+kBcjQ5I3CiUgzo/vFcGvT3MZQ9QHsEeYMhYO6a5CLGGffR8hMg==" }, "tmp": { "version": "0.0.33", diff --git a/package.json b/package.json index 273992ecf1..2f15f0203a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "hgnreactapp", "version": "0.1.0", + "license": "GPL-2.0", "engines": { "node": ">=14.0.0 <15" }, @@ -11,7 +12,7 @@ "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.19", "@sentry/browser": "^4.6.6", - "@tinymce/tinymce-react": "^3.6.0", + "@tinymce/tinymce-react": "^3.14.0", "axios": "^0.21.2", "axios-mock-adapter": "^1.22.0", "bootstrap": "^4.5.3", @@ -21,6 +22,7 @@ "diff": "^5.0.0", "dompurify": "^3.0.6", "font-awesome": "^4.7.0", + "fs-extra": "^11.2.0", "history": "^4.10.1", "html-react-parser": "^1.4.14", "html-to-pdfmake": "^2.0.6", @@ -29,6 +31,7 @@ "jwt-decode": "^2.2.0", "leaflet": "^1.9.4", "lodash": "^4.17.21", + "lz-string": "^1.5.0", "moment": "^2.29.2", "moment-timezone": "^0.5.33", "pdfmake": "^0.1.65", @@ -65,13 +68,14 @@ "redux-concatenate-reducers": "^1.0.0", "redux-persist": "^5.10.0", "redux-thunk": "^2.3.0", - "tinymce": "^5.10.8", + "tinymce": "^5.10.9", "uuid": "^9.0.1" }, "scripts": { "prestart": "npm run test", + "postinstall": "node ./postinstall.js", "start": "react-scripts start", - "build": "react-scripts build", + "build": "npm run postinstall && react-scripts build", "test": "cross-env CI=true react-scripts test --env=jest-environment-jsdom-sixteen", "test:watch": " react-scripts test --env=jest-environment-jsdom-sixteen", "test:coverage": "cross-env CI=true react-scripts test --env=jest-environment-jsdom-sixteen --coverage", diff --git a/postinstall.js b/postinstall.js new file mode 100644 index 0000000000..6325c0e091 --- /dev/null +++ b/postinstall.js @@ -0,0 +1,10 @@ +// Script to copy tinymce to public folder. Read more: https://www.tiny.cloud/docs/tinymce/latest/react-pm-host/ +const fse = require('fs-extra'); +const path = require('path'); + +const topDir = __dirname; +// const topDir = import.meta.dirname; +fse.emptyDirSync(path.join(topDir, 'public', 'tinymce')); +fse.copySync(path.join(topDir, 'node_modules', 'tinymce'), path.join(topDir, 'public', 'tinymce'), { + overwrite: true, +}); diff --git a/public/index.html b/public/index.html index 17655ad810..8ee425319d 100644 --- a/public/index.html +++ b/public/index.html @@ -11,10 +11,6 @@ -