diff --git a/frontend/package.json b/frontend/package.json index a393e002c4..8772d07fbc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "license": "BSD-2-Clause", "private": false, + "type": "module", "dependencies": { "@hotosm/id": "^2.30.2", "@hotosm/iso-countries-languages": "^1.1.2", diff --git a/frontend/src/components/banner/topBanner.tsx b/frontend/src/components/banner/topBanner.tsx index e1988b8b95..9fffe9d757 100644 --- a/frontend/src/components/banner/topBanner.tsx +++ b/frontend/src/components/banner/topBanner.tsx @@ -20,7 +20,7 @@ export function TopBanner() { return ( <> {/* @ts-expect-error TS Migrations */} - {location.pathname === '/' && data.visible && !error && ( + {location.pathname === '/' && data?.visible && !error && (
& { loading?: boolean; }; -export function Button(props: ButtonProps) { +export const Button = React.forwardRef((props, ref) => { const { children, icon, className, loading = false, disabled, ...rest } = props; return ( @@ -27,13 +27,14 @@ export function Button(props: ButtonProps) { className={`${className || ''} br1 f5 bn ${disabled || loading ? 'o-50' : 'pointer'}`} style={{ padding: '.75rem 1.5rem' }} disabled={disabled || loading} + ref={ref} {...rest} > {loading ? : icon && {icon}} {children} ); -} +}) export function FormSubmitButton( props: React.ButtonHTMLAttributes & { diff --git a/frontend/src/components/deleteModal/index.jsx b/frontend/src/components/deleteModal/index.jsx index 4161876ad0..bd2fcf1496 100644 --- a/frontend/src/components/deleteModal/index.jsx +++ b/frontend/src/components/deleteModal/index.jsx @@ -7,7 +7,7 @@ import Popup from 'reactjs-popup'; import messages from './messages'; import { fetchLocalJSONAPI } from '../../network/genericJSONRequest'; import { DeleteButton } from '../teamsAndOrgs/management'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { AlertIcon } from '../svgIcons'; const DeleteTrigger = forwardRef((props, ref) => ); diff --git a/frontend/src/components/header/index.tsx b/frontend/src/components/header/index.tsx index bb269d6914..cc70fe1018 100644 --- a/frontend/src/components/header/index.tsx +++ b/frontend/src/components/header/index.tsx @@ -10,7 +10,7 @@ import logo from '../../assets/img/main-logo.svg'; import { ExternalLinkIcon } from '../svgIcons'; import { Dropdown } from '../dropdown'; import { LocaleSelector } from '../localeSelect'; -import { Button, ButtonProps } from '../button.jsx'; +import { Button, ButtonProps } from '../button'; import { UpdateDialog } from './updateDialog'; import { BurgerMenu } from './burgerMenu'; import { TopNavLink } from './NavLink'; @@ -82,8 +82,10 @@ export const Header = () => { } }; + console.log("USERDETAILS", userDetails); + const checkUserEmail = () => - userDetails.hasOwnProperty('emailAddress') && !userDetails.emailAddress ? ( + userDetails?.hasOwnProperty('emailAddress') && !userDetails.emailAddress ? ( {(close) => } @@ -186,7 +188,7 @@ export function getMenuItemsForUser(userDetails: any, organisations?: any) { } let filteredMenuItems; - if (userDetails.username) { + if (userDetails?.username) { filteredMenuItems = menuItems.filter((item) => item.authenticated === true || item.showAlways); if ( userDetails.role !== 'ADMIN' && @@ -273,7 +275,7 @@ export const ActionItems = ({ location: any; getUserLinks: (role: string) => any; }) => - userDetails.username ? ( + userDetails?.username ? ( <> import('./timeline' /* webpackChunkName: "timeline" */)); diff --git a/frontend/src/components/projectDetail/privateProjectError.jsx b/frontend/src/components/projectDetail/privateProjectError.jsx index fd01c84d7d..c357b8f53d 100644 --- a/frontend/src/components/projectDetail/privateProjectError.jsx +++ b/frontend/src/components/projectDetail/privateProjectError.jsx @@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; import { LockIcon } from '../svgIcons'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; const PrivateProjectError = () => { const navigate = useNavigate(); diff --git a/frontend/src/components/projectDetail/questionsAndComments.jsx b/frontend/src/components/projectDetail/questionsAndComments.jsx index 07e19a4cb6..64c866b7c7 100644 --- a/frontend/src/components/projectDetail/questionsAndComments.jsx +++ b/frontend/src/components/projectDetail/questionsAndComments.jsx @@ -7,7 +7,7 @@ import ReactPlaceholder from 'react-placeholder'; import messages from './messages'; import { RelativeTimeWithUnit } from '../../utils/formattedRelativeTime'; import { PaginatorLine } from '../paginator'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { Alert } from '../alert'; import { MessageStatus } from '../comments/status'; import { UserAvatar } from '../user/avatar'; diff --git a/frontend/src/components/projectEdit/actionsForm.jsx b/frontend/src/components/projectEdit/actionsForm.jsx index bd5726b3ce..6aecb3ebdc 100644 --- a/frontend/src/components/projectEdit/actionsForm.jsx +++ b/frontend/src/components/projectEdit/actionsForm.jsx @@ -6,7 +6,7 @@ import { useNavigate } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import messages from './messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { Alert } from '../alert'; import { DeleteModal } from '../deleteModal'; import { styleClasses, StateContext } from '../../views/projectEdit'; diff --git a/frontend/src/components/projectEdit/partnersForm.jsx b/frontend/src/components/projectEdit/partnersForm.jsx index 4cb8ab3b0a..a938520e5b 100644 --- a/frontend/src/components/projectEdit/partnersForm.jsx +++ b/frontend/src/components/projectEdit/partnersForm.jsx @@ -12,7 +12,7 @@ import PropTypes from 'prop-types'; import messages from './messages'; import { Alert } from '../alert'; import { ChevronDownIcon, CloseIcon } from '../svgIcons'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { styleClasses } from '../../views/projectEdit'; import { pushToLocalJSONAPI } from '../../network/genericJSONRequest'; import { useAllPartnersQuery } from '../../api/projects'; diff --git a/frontend/src/components/projectEdit/partnersListing.jsx b/frontend/src/components/projectEdit/partnersListing.jsx index ae9a55f9a5..bc58793656 100644 --- a/frontend/src/components/projectEdit/partnersListing.jsx +++ b/frontend/src/components/projectEdit/partnersListing.jsx @@ -14,7 +14,7 @@ import PropTypes from 'prop-types'; import messages from './messages'; import { Alert } from '../alert'; import { BanIcon, CircleMinusIcon, CircleExclamationIcon } from '../svgIcons'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { styleClasses } from '../../views/projectEdit'; import { fetchLocalJSONAPI, pushToLocalJSONAPI } from '../../network/genericJSONRequest'; import { DateCustomInput } from './partnersForm'; diff --git a/frontend/src/components/projectEdit/permissionsBlock.jsx b/frontend/src/components/projectEdit/permissionsBlock.jsx index 1ceffa080d..b589c015f2 100644 --- a/frontend/src/components/projectEdit/permissionsBlock.jsx +++ b/frontend/src/components/projectEdit/permissionsBlock.jsx @@ -1,6 +1,6 @@ import { useContext } from 'react'; import { FormattedMessage } from 'react-intl'; -import messages from './messages.js'; +import messages from './messages'; import { StateContext, styleClasses } from '../../views/projectEdit'; export const PermissionsBlock = ({ permissions, type }) => { diff --git a/frontend/src/components/projectEdit/teamSelect.jsx b/frontend/src/components/projectEdit/teamSelect.jsx index 14b9e5ec09..3a97b3fafc 100644 --- a/frontend/src/components/projectEdit/teamSelect.jsx +++ b/frontend/src/components/projectEdit/teamSelect.jsx @@ -4,7 +4,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import messages from './messages'; import commonMessages from '../messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { StateContext } from '../../views/projectEdit'; import { PencilIcon, WasteIcon, ExternalLinkIcon } from '../svgIcons'; import { useFetchWithAbort } from '../../hooks/UseFetch'; diff --git a/frontend/src/components/projects/moreFiltersForm.jsx b/frontend/src/components/projects/moreFiltersForm.jsx index ab12880cba..90744613d8 100644 --- a/frontend/src/components/projects/moreFiltersForm.jsx +++ b/frontend/src/components/projects/moreFiltersForm.jsx @@ -4,7 +4,7 @@ import { useQueryParam, BooleanParam } from 'use-query-params'; import { FormattedMessage } from 'react-intl'; import messages from './messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { SwitchToggle } from '../formInputs'; import { useTagAPI } from '../../hooks/UseTagAPI'; import { useExploreProjectsQueryParams } from '../../hooks/UseProjectsQueryAPI'; diff --git a/frontend/src/components/projects/partnersFilterSelect.jsx b/frontend/src/components/projects/partnersFilterSelect.jsx index b5e831b33e..b7c765a07d 100644 --- a/frontend/src/components/projects/partnersFilterSelect.jsx +++ b/frontend/src/components/projects/partnersFilterSelect.jsx @@ -8,7 +8,7 @@ import PropTypes from 'prop-types'; import { DateCustomInput } from '../projectEdit/partnersForm'; import { useAllPartnersQuery } from '../../api/projects'; import messagesFromProjectEdit from '../projectEdit/messages'; -import messages from './messages.js'; +import messages from './messages'; export const PartnersFilterSelect = ({ fieldsetName, diff --git a/frontend/src/components/taskSelection/action.jsx b/frontend/src/components/taskSelection/action.jsx index 20fdcf9893..7546971dea 100644 --- a/frontend/src/components/taskSelection/action.jsx +++ b/frontend/src/components/taskSelection/action.jsx @@ -10,7 +10,7 @@ import messages from './messages'; import { ProjectInstructions } from './instructions'; import { TasksMap } from './map'; import { HeaderLine } from '../projectDetail/header'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import Portal from '../portal'; import { SidebarIcon } from '../svgIcons'; import { openEditor, getTaskGpxUrl, formatImageryUrl, formatJosmUrl } from '../../utils/openEditor'; diff --git a/frontend/src/components/taskSelection/contributions.jsx b/frontend/src/components/taskSelection/contributions.jsx index 348e15015d..ebd7cb5d98 100644 --- a/frontend/src/components/taskSelection/contributions.jsx +++ b/frontend/src/components/taskSelection/contributions.jsx @@ -4,7 +4,7 @@ import Select from 'react-select'; import ReactPlaceholder from 'react-placeholder'; import { FormattedMessage, useIntl } from 'react-intl'; -import messages from './messages.js'; +import messages from './messages'; import { UserAvatar } from '../user/avatar'; import { CheckCircle } from '../checkCircle'; import { CustomButton } from '../button'; diff --git a/frontend/src/components/taskSelection/extendSession.jsx b/frontend/src/components/taskSelection/extendSession.jsx index d0fde5c3d1..d6278a8f74 100644 --- a/frontend/src/components/taskSelection/extendSession.jsx +++ b/frontend/src/components/taskSelection/extendSession.jsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { FormattedMessage } from 'react-intl'; import Popup from 'reactjs-popup'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { Alert } from '../alert'; import { pushToLocalJSONAPI } from '../../network/genericJSONRequest'; import messages from './messages'; diff --git a/frontend/src/components/taskSelection/footer.jsx b/frontend/src/components/taskSelection/footer.jsx index 8e15d03f63..821a4cfc21 100644 --- a/frontend/src/components/taskSelection/footer.jsx +++ b/frontend/src/components/taskSelection/footer.jsx @@ -10,7 +10,7 @@ import { openEditor, formatJosmUrl } from '../../utils/openEditor'; import { useFetchLockedTasks } from '../../hooks/UseLockedTasks'; import { pushToLocalJSONAPI, fetchLocalJSONAPI } from '../../network/genericJSONRequest'; import { Dropdown } from '../dropdown'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { Imagery } from './imagery'; import { MappingTypes } from '../mappingTypes'; import { LockedTaskModalContent } from './lockedTasks'; diff --git a/frontend/src/components/taskSelection/lockedTasks.jsx b/frontend/src/components/taskSelection/lockedTasks.jsx index 562e28611a..584c0766c5 100644 --- a/frontend/src/components/taskSelection/lockedTasks.jsx +++ b/frontend/src/components/taskSelection/lockedTasks.jsx @@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'; import { FormattedMessage } from 'react-intl'; import messages from './messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { useGetLockedTasks } from '../../hooks/UseLockedTasks'; export function AnotherProjectLock({ projectId, lockedTasksLength, action }) { diff --git a/frontend/src/components/taskSelection/permissionErrorModal.jsx b/frontend/src/components/taskSelection/permissionErrorModal.jsx index bd222dca4c..c918985478 100644 --- a/frontend/src/components/taskSelection/permissionErrorModal.jsx +++ b/frontend/src/components/taskSelection/permissionErrorModal.jsx @@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; import { getPermissionErrorMessage } from '../../utils/projectPermissions'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { CloseIcon } from '../svgIcons'; import { TeamBox } from '../teamsAndOrgs/teams'; diff --git a/frontend/src/components/teamsAndOrgs/campaigns.jsx b/frontend/src/components/teamsAndOrgs/campaigns.jsx index 40448cc051..47427a82ae 100644 --- a/frontend/src/components/teamsAndOrgs/campaigns.jsx +++ b/frontend/src/components/teamsAndOrgs/campaigns.jsx @@ -7,7 +7,7 @@ import ReactPlaceholder from 'react-placeholder'; import { nCardPlaceholders } from './campaignsPlaceholder'; import messages from './messages'; import { Management } from './management'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { HashtagIcon } from '../svgIcons'; import { TextField } from '../formInputs'; diff --git a/frontend/src/components/teamsAndOrgs/leaveTeamConfirmationAlert.jsx b/frontend/src/components/teamsAndOrgs/leaveTeamConfirmationAlert.jsx index 0ef7586252..148e6bb3a7 100644 --- a/frontend/src/components/teamsAndOrgs/leaveTeamConfirmationAlert.jsx +++ b/frontend/src/components/teamsAndOrgs/leaveTeamConfirmationAlert.jsx @@ -2,7 +2,7 @@ import { FormattedMessage } from 'react-intl'; import commonMessages from '../../views/messages'; import messages from './messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { styleClasses } from '../../views/projectEdit'; export const LeaveTeamConfirmationAlert = ({ teamName, close, leaveTeam }) => { diff --git a/frontend/src/components/teamsAndOrgs/members.jsx b/frontend/src/components/teamsAndOrgs/members.jsx index 6c5cb90e7c..e623668aaa 100644 --- a/frontend/src/components/teamsAndOrgs/members.jsx +++ b/frontend/src/components/teamsAndOrgs/members.jsx @@ -7,7 +7,7 @@ import AsyncSelect from 'react-select/async'; import messages from './messages'; import { UserAvatar } from '../user/avatar'; import { EditModeControl } from './editMode'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { SwitchToggle } from '../formInputs'; import { fetchLocalJSONAPI, pushToLocalJSONAPI } from '../../network/genericJSONRequest'; import { Alert } from '../alert'; diff --git a/frontend/src/components/teamsAndOrgs/messageMembers.jsx b/frontend/src/components/teamsAndOrgs/messageMembers.jsx index 5e3684b2ef..7ed14381b3 100644 --- a/frontend/src/components/teamsAndOrgs/messageMembers.jsx +++ b/frontend/src/components/teamsAndOrgs/messageMembers.jsx @@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl'; import toast from 'react-hot-toast'; import messages from './messages'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { MessageStatus } from '../comments/status'; import { pushToLocalJSONAPI } from '../../network/genericJSONRequest'; import ReactPlaceholder from 'react-placeholder'; diff --git a/frontend/src/components/teamsAndOrgs/organisations.jsx b/frontend/src/components/teamsAndOrgs/organisations.jsx index eecaa2f650..743508ce2d 100644 --- a/frontend/src/components/teamsAndOrgs/organisations.jsx +++ b/frontend/src/components/teamsAndOrgs/organisations.jsx @@ -13,7 +13,7 @@ import { useUploadImage } from '../../hooks/UseUploadImage'; import { levels } from '../../hooks/UseOrganisationLevel'; import { Management } from './management'; import { InternalLinkIcon, ClipboardIcon } from '../svgIcons'; -import { Button } from '../button.jsx'; +import { Button } from '../button'; import { UserAvatarList } from '../user/avatar'; import { nCardPlaceholders } from './organisationsPlaceholder'; import { Alert } from '../alert'; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index bd4f683436..720e9d82a5 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -8,7 +8,7 @@ import 'react-tooltip/dist/react-tooltip.css'; // Needed by for { Tooltip } from import App from './App.jsx'; import { store, persistor } from './store'; -import { ConnectedIntl } from './utils/internationalization.jsx'; +import { ConnectedIntl } from './utils/internationalization'; import { register, unregister, onServiceWorkerUpdate } from './serviceWorkerRegistration'; import { ENABLE_SERVICEWORKER, SENTRY_FRONTEND_DSN, ENVIRONMENT } from './config'; diff --git a/frontend/src/utils/geoFileFunctions.js b/frontend/src/utils/geoFileFunctions.js index ae9b17a784..57e31f5624 100644 --- a/frontend/src/utils/geoFileFunctions.js +++ b/frontend/src/utils/geoFileFunctions.js @@ -5,7 +5,7 @@ import { kml } from '@tmcw/togeojson'; import { MAX_FILESIZE } from '../config'; import shpjs from 'shpjs'; -var osmToGeojson = require('osmtogeojson'); +import osmToGeojson from "osmtogeojson"; export const verifyFileSize = (file) => { if (file.size >= MAX_FILESIZE) { diff --git a/frontend/src/views/tests/notFound.test.js b/frontend/src/views/tests/notFound.test.js index 05c643cc89..20131ca30c 100644 --- a/frontend/src/views/tests/notFound.test.js +++ b/frontend/src/views/tests/notFound.test.js @@ -2,7 +2,7 @@ import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; import { IntlProviders } from '../../utils/testWithIntl'; import messages from '../messages'; -import { NotFound } from '../notFound.jsx'; +import { NotFound } from '../notFound'; describe('Not Found', () => { it('should display project not found error', () => { diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index ff4041ee12..65d41aee35 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -19,6 +19,7 @@ "jsx": "react-jsx", /* Linting */ "strict": false, + "strictNullChecks": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true,