diff --git a/package.json b/package.json index 61e302d738..e2d709de9d 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "react-datepicker": "^4.7.0", "react-dom": "^16.13.1", "react-hot-loader": "^4.13.0", - "react-redux": "^8.1.3", + "react-redux": "^7.2.9", "react-select": "^4.3.1", "react-select-fast-filter-options": "^0.2.3", "react-simple-star-rating": "^4.0.5", diff --git a/src/client/components/forms/parts/achievement.js b/src/client/components/forms/parts/achievement.tsx similarity index 63% rename from src/client/components/forms/parts/achievement.js rename to src/client/components/forms/parts/achievement.tsx index 472f74eca5..7ca03dc6e2 100644 --- a/src/client/components/forms/parts/achievement.js +++ b/src/client/components/forms/parts/achievement.tsx @@ -1,5 +1,6 @@ /* * Copyright (C) 2016 Max Prettyjohns + * 2023 Meziyum * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,12 +18,13 @@ */ import * as bootstrap from 'react-bootstrap'; +import type {Achievement} from '../../input/drag-and-drop'; import DragAndDropImage from '../../input/drag-and-drop-image'; -import PropTypes from 'prop-types'; import React from 'react'; const {Card, Col, Container, Row} = bootstrap; +/* eslint-disable sort-keys */ const maxAchievementProgress = { 1: 1, 2: 50, @@ -33,7 +35,6 @@ const maxAchievementProgress = { 7: 1, 8: 10, 9: 100, - // eslint-disable-next-line sort-keys 10: 10, 11: 7, 12: 30, @@ -56,28 +57,41 @@ const maxAchievementProgress = { 29: 10, 30: 100 }; +/* eslint-enable sort-keys */ -function Achievement(props) { - const {achievement, counter, unlocked} = props; - const {id, name, description, badgeUrl} = achievement; +interface AchievementComponentProps { + achievement: Achievement +} + +/** + * Achievement Component + * + * A React component that displays an achievement card with its details, including name, + * description, badge image, and progress if the achievement is locked. + * + * @component + * + * @param {Object} props - The props for the Achievement component. + * @param {Achievement} props.achievement - The achievement object containing details. + * @param {number} props.counter - The current progress or counter for the achievement. + * @param {boolean} props.unlocked - A boolean indicating whether the achievement is unlocked. + * + * @returns {JSX.Element} The rendered Achievement card component. + */ +function AchievementComponent({achievement}: AchievementComponentProps): JSX.Element { + const {id, name, description, badgeUrl, counter, unlocked} = achievement; const imgElement = unlocked ? ( ) : ( {name} ); @@ -107,21 +121,6 @@ function Achievement(props) { ); } -Achievement.displayName = 'achievement'; - -Achievement.propTypes = { - achievement: PropTypes.shape({ - badgeUrl: PropTypes.string, - description: PropTypes.string, - id: PropTypes.number, - name: PropTypes.string - }).isRequired, - counter: PropTypes.number, - unlocked: PropTypes.bool -}; -Achievement.defaultProps = { - counter: 0, - unlocked: false -}; +AchievementComponent.displayName = 'achievement'; -export default Achievement; +export default AchievementComponent; diff --git a/src/client/components/input/drag-and-drop-image.tsx b/src/client/components/input/drag-and-drop-image.tsx index 82caa7b788..33564578b8 100644 --- a/src/client/components/input/drag-and-drop-image.tsx +++ b/src/client/components/input/drag-and-drop-image.tsx @@ -16,7 +16,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -import PropTypes from 'prop-types'; import React from 'react'; @@ -71,11 +70,5 @@ function DragAndDropImage({achievementId, achievementName, height, src}: Props): } DragAndDropImage.displayName = 'DragAndDropImage'; -DragAndDropImage.propTypes = { - achievementId: PropTypes.number.isRequired, - achievementName: PropTypes.string.isRequired, - height: PropTypes.string.isRequired, - src: PropTypes.string.isRequired -}; export default DragAndDropImage; diff --git a/src/client/components/input/drag-and-drop.tsx b/src/client/components/input/drag-and-drop.tsx index 306bcad22c..fed54f788b 100644 --- a/src/client/components/input/drag-and-drop.tsx +++ b/src/client/components/input/drag-and-drop.tsx @@ -17,7 +17,6 @@ */ import * as bootstrap from 'react-bootstrap'; -import PropTypes from 'prop-types'; import React from 'react'; @@ -31,10 +30,20 @@ const {useState, useCallback} = React; * @property {string} badgeUrl - The source URL of the achievement's badge image. * @property {number} id - The ID of the achievement. */ -type Achievement = { - name: string; +export type Achievement = { badgeUrl: string | null; + counter:number; + description: string; id: number; + name: string; + unlocked: boolean; +}; +type AchievementForDisplay = Pick; + +const blankBadge:AchievementForDisplay = { + badgeUrl: '/images/blankbadge.svg', + id: null, + name: 'drag badge to set' }; /** @@ -56,18 +65,14 @@ type Props = { * @returns {JSX.Element} A React component that displays a drag-and-drop card for an achievement. */ function DragAndDrop({name, initialAchievement}: Props): JSX.Element { - const [achievement, setAchievement] = useState(initialAchievement); + const [achievement, setAchievement] = useState(initialAchievement); const handleClick = useCallback((event: React.MouseEvent) => { event.preventDefault(); - setAchievement({ - badgeUrl: '/images/blankbadge.svg', - id: null, - name: 'drag badge to set' - }); - }); + setAchievement(blankBadge); + }, []); const handleDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); - }); + }, []); const handleDrop = useCallback((event: React.DragEvent) => { event.preventDefault(); let data; @@ -83,7 +88,7 @@ function DragAndDrop({name, initialAchievement}: Props): JSX.Element { id: data.id, name: data.name }); - }); + }, [setAchievement]); return ( ); if (achievement.unlocked) { diff --git a/src/client/entity-editor/alias-editor/reducer.js b/src/client/entity-editor/alias-editor/reducer.js index 3fc723a5cf..dc0d18eb71 100644 --- a/src/client/entity-editor/alias-editor/reducer.js +++ b/src/client/entity-editor/alias-editor/reducer.js @@ -50,7 +50,7 @@ function reducer( return state.delete(payload); case REMOVE_EMPTY_ALIASES: return state.filterNot(alias => - alias.get('name') === '' && alias.get('language') === null && alias.get('sortName') === ''); + alias.get('name') === ''); // no default } return state; diff --git a/src/client/entity-editor/identifier-editor/reducer.ts b/src/client/entity-editor/identifier-editor/reducer.ts index 9e5749ac98..0c07ccba23 100644 --- a/src/client/entity-editor/identifier-editor/reducer.ts +++ b/src/client/entity-editor/identifier-editor/reducer.ts @@ -58,7 +58,7 @@ function reducer( return state.delete(payload); case REMOVE_EMPTY_IDENTIFIERS: return state.filterNot(identifier => - identifier.get('value') === '' && identifier.get('type') === null); + identifier.get('value') === ''); case ADD_OTHER_ISBN: { const {rowId, value, type: typeId} = payload; // search if given identifier already exists diff --git a/yarn.lock b/yarn.lock index 726f798674..cbf9d9a324 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1210,13 +1210,20 @@ pirates "^4.0.6" source-map-support "^0.5.16" -"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.17.7", "@babel/runtime@^7.2.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.17.7", "@babel/runtime@^7.2.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.15.4": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" + integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.16.0", "@babel/template@^7.16.7", "@babel/template@^7.20.7": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" @@ -1901,10 +1908,10 @@ dependencies: "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.1": - version "3.3.3" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.3.tgz#8bb41d9a88164f82dd2745ff05e637e655f34d19" - integrity sha512-Wny3a2UXn5FEA1l7gc6BbpoV5mD1XijZqgkp4TRgDCDL5r3B5ieOFGUX5h3n78Tr1MEG7BfvoM8qeztdvNU0fw== +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" + integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== dependencies: "@types/react" "*" hoist-non-react-statics "^3.3.0" @@ -1995,6 +2002,16 @@ dependencies: "@types/react" "*" +"@types/react-redux@^7.1.20": + version "7.1.33" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15" + integrity sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react-select@^4.0.18": version "4.0.18" resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-4.0.18.tgz#f907f406411afa862217a9d86c54a301367a35c1" @@ -2061,11 +2078,6 @@ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== -"@types/use-sync-external-store@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" - integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== - "@types/warning@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" @@ -7240,6 +7252,11 @@ react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0, react-is@^16.8.6: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -7277,17 +7294,17 @@ react-popper@^2.2.5: react-fast-compare "^3.0.1" warning "^4.0.2" -react-redux@^8.1.3: - version "8.1.3" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.3.tgz#4fdc0462d0acb59af29a13c27ffef6f49ab4df46" - integrity sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw== +react-redux@^7.2.9: + version "7.2.9" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" + integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== dependencies: - "@babel/runtime" "^7.12.1" - "@types/hoist-non-react-statics" "^3.3.1" - "@types/use-sync-external-store" "^0.0.3" + "@babel/runtime" "^7.15.4" + "@types/react-redux" "^7.1.20" hoist-non-react-statics "^3.3.2" - react-is "^18.0.0" - use-sync-external-store "^1.0.0" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^17.0.2" react-select-fast-filter-options@^0.2.3: version "0.2.3" @@ -7449,6 +7466,13 @@ redux-thunk@^2.2.0: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== +redux@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" + integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== + dependencies: + "@babel/runtime" "^7.9.2" + redux@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.0.tgz#46f10d6e29b6666df758780437651eeb2b969f13" @@ -8553,11 +8577,6 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -use-sync-external-store@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"