From 6302f60de25a677b3b31dabd581799bcce549f8c Mon Sep 17 00:00:00 2001 From: tnagorra Date: Wed, 19 Jan 2022 10:02:19 +0545 Subject: [PATCH] WIP --- .eslintrc.js | 3 + app/Base/components/Navbar/index.tsx | 2 +- app/Base/index.tsx | 11 +- app/Base/utils/apollo.ts | 2 +- app/Base/utils/common.ts | 14 ++ app/Base/utils/restRequest.ts | 10 +- .../GeoLocationMapInput/index.tsx | 21 ++- app/components/NonFieldError/index.tsx | 2 +- .../NotificationContainer/index.tsx | 4 +- .../ProjectJoinRequestItem/index.tsx | 14 +- .../Notifications/NotificationItem/index.tsx | 130 +++++++++--------- app/components/OrganigramInput/index.tsx | 4 +- app/components/RechartsLegend/index.tsx | 2 +- app/components/Screenshot/index.tsx | 18 +-- app/components/SortableList/index.tsx | 14 +- app/components/TreeSelection/index.tsx | 7 - app/components/entry/CompactSection/index.tsx | 6 +- .../entryReview/EntryCommentWrapper/index.tsx | 4 +- .../EntryComments/Comment/index.tsx | 6 +- .../Matrix1dWidgetInput/index.tsx | 8 +- .../Matrix2dWidgetInput/index.tsx | 16 +-- .../MultiSelectWidgetInput/index.tsx | 2 +- .../AttributeInput/ScaleWidgetInput/index.tsx | 6 +- .../SingleSelectWidgetInput/index.tsx | 2 +- .../DateRangeWidgetInput/index.tsx | 4 +- .../GeoLocationWidgetInput/index.tsx | 2 +- .../Matrix1dWidgetInput/index.tsx | 8 +- .../Matrix2dWidgetInput/index.tsx | 14 +- .../MultiSelectWidgetInput/index.tsx | 4 +- .../OrganigramWidgetInput/index.tsx | 2 +- .../ScaleWidgetInput/index.tsx | 6 +- .../SingleSelectWidgetInput/index.tsx | 2 +- .../TimeRangeWidgetInput/index.tsx | 4 +- .../general/AddLeadGroupModal/index.tsx | 4 +- .../general/AddOrganizationModal/index.tsx | 8 +- .../general/AddStakeholderModal/index.tsx | 2 +- .../lead/LeadInput/EmmStats/index.tsx | 8 +- app/components/lead/LeadPreview/index.tsx | 4 +- app/components/region/RegionMap/index.tsx | 6 +- app/translate/index.tsx | 10 +- app/types/newAnalyticalFramework.ts | 8 +- app/utils/browserExtension.tsx | 27 ++-- .../PrimaryTagging/index.tsx | 6 +- .../AnalyticalFramework/UserTable/index.tsx | 14 +- .../components/Canvas/index.tsx | 4 +- .../DateConditionalWidgetForm/index.tsx | 8 +- .../DateRangeConditionalWidgetForm/index.tsx | 8 +- .../index.tsx | 8 +- .../Matrix1dConditionalWidgetForm/index.tsx | 8 +- .../Matrix2dConditionalWidgetForm/index.tsx | 8 +- .../index.tsx | 8 +- .../NumberConditionalWidgetForm/index.tsx | 8 +- .../OrganigramConditionalWidgetForm/index.tsx | 8 +- .../ScaleConditionalWidgetForm/index.tsx | 8 +- .../index.tsx | 8 +- .../TextConditionalWidgetForm/index.tsx | 8 +- .../TimeConditionalWidgetForm/index.tsx | 8 +- .../TimeRangeConditionalWidgetForm/index.tsx | 8 +- .../OrganigramWidgetForm/index.tsx | 20 +-- app/views/AnalyticalFramework/index.tsx | 14 +- app/views/AnalyticalFramework/utils.ts | 14 +- .../ActionCell/ProjectJoinModal/index.tsx | 2 +- .../ExploreDeep/MapView/ProjectList/index.tsx | 22 +-- app/views/ExploreDeep/MapView/index.tsx | 4 +- .../ExploreDeep/ProjectFilterForm/index.tsx | 10 +- .../PublicMapView/ProjectList/index.tsx | 18 +-- app/views/ExploreDeep/PublicMapView/index.tsx | 4 +- .../ExploreDeep/PublicTableView/index.tsx | 12 +- app/views/ExploreDeep/TableView/index.tsx | 20 +-- app/views/ExploreDeep/index.tsx | 4 +- .../ForgotPasswordForm/index.tsx | 2 +- .../Home/Assignment/AssignmentItem/index.tsx | 8 +- app/views/Home/ProjectItem/index.tsx | 2 +- app/views/Login/LoginForm/index.tsx | 8 +- .../MyProfile/ChangePasswordModal/index.tsx | 2 +- .../Analysis/AnalysisCloneModal/index.tsx | 2 +- .../Analysis/AnalysisPillar/index.tsx | 2 +- .../Analysis/PillarList/index.tsx | 2 +- .../Project/AnalysisModule/Analysis/index.tsx | 2 +- .../AnalysisEditModal/index.tsx | 6 +- app/views/Project/AnalysisModule/index.tsx | 10 +- .../EntryEdit/LeftPane/EntryItem/index.tsx | 2 +- .../Project/EntryEdit/LeftPane/index.tsx | 14 +- app/views/Project/EntryEdit/index.tsx | 43 +++--- .../AnalyticalNGramsModal/index.tsx | 2 +- .../AnalyticalStatementInput/index.tsx | 2 +- .../DiscardedEntries/DiscardedEntry/index.tsx | 4 +- .../PillarAnalysis/DiscardedEntries/index.tsx | 2 +- .../PillarAnalysis/SourceEntryItem/index.tsx | 4 +- app/views/Project/PillarAnalysis/index.tsx | 14 +- .../Tagging/Assessments/ActionCell/index.tsx | 2 +- .../AssessmentFilterForm/index.tsx | 6 +- .../Project/Tagging/Assessments/index.tsx | 8 +- .../VisualizationShareModal/index.tsx | 8 +- app/views/Project/Tagging/Dashboard/index.tsx | 6 +- .../AssessmentsExportSelection/index.tsx | 6 +- .../Export/EntriesExportSelection/index.tsx | 13 +- .../Tagging/Export/ExportHistory/index.tsx | 2 +- .../Tagging/Export/ExportPreview/index.tsx | 2 +- .../Tagging/Export/LeadsSelection/index.tsx | 6 +- app/views/Project/Tagging/Export/utils.ts | 4 +- .../Tagging/LeadGroups/ActionCell/index.tsx | 2 +- .../LeadGroups/LeadGroupFilterForm/index.tsx | 6 +- .../Project/Tagging/LeadGroups/index.tsx | 8 +- .../DropboxPicker/index.tsx | 2 +- .../Tagging/Sources/BulkUpload/index.tsx | 14 +- .../Sources/EntriesGrid/EntryCard/index.tsx | 4 +- .../Tagging/Sources/EntriesGrid/index.tsx | 4 +- .../Tagging/Sources/LeadEditModal/index.tsx | 18 +-- .../EntryFilter/FrameworkFilterItem/index.tsx | 24 ++-- .../SourcesFilter/EntryFilter/index.tsx | 4 +- .../Tagging/Sources/SourcesFilter/index.tsx | 4 +- .../SourcesTable/BulkActions/index.tsx | 4 +- .../Sources/SourcesTable/EntryList/index.tsx | 6 +- .../SourcesTable/LeadCopyModal/index.tsx | 8 +- .../Tagging/Sources/SourcesTable/index.tsx | 4 +- .../components/EditableEntry/index.tsx | 2 +- .../Framework/FrameworkDetail/index.tsx | 30 ++-- .../ProjectEdit/GeoAreas/RegionsMap/index.tsx | 6 +- .../ProjectEdit/ProjectDetailsForm/index.tsx | 18 +-- .../ProjectEdit/Users/UserGroupList/index.tsx | 4 +- .../Users/UserList/AddUserModal/index.tsx | 4 +- .../ProjectEdit/Users/UserList/index.tsx | 6 +- app/views/ProjectEdit/Users/index.tsx | 4 +- app/views/Register/RegisterForm/index.tsx | 10 +- .../UserGroupItem/AddUserModal/index.tsx | 2 +- app/views/UserGroup/UserGroupItem/index.tsx | 2 +- app/views/UserGroup/index.tsx | 4 +- tsconfig.json | 3 + 129 files changed, 560 insertions(+), 546 deletions(-) create mode 100644 app/Base/utils/common.ts diff --git a/.eslintrc.js b/.eslintrc.js index 214ecd86af..e60712ad57 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -35,6 +35,7 @@ const config = { }, sourceType: 'module', allowImportExportEverywhere: true, + project: ['tsconfig.json'], }, rules: { strict: 1, @@ -53,6 +54,8 @@ const config = { '@typescript-eslint/explicit-function-return-type': 0, '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/no-unnecessary-condition': 'warn', + 'no-console': 1, indent: ['error', 4, { SwitchCase: 1 }], diff --git a/app/Base/components/Navbar/index.tsx b/app/Base/components/Navbar/index.tsx index 98072fae3d..7d5778c390 100644 --- a/app/Base/components/Navbar/index.tsx +++ b/app/Base/components/Navbar/index.tsx @@ -118,7 +118,7 @@ function Navbar(props: Props) { const notificationsCount = notifications?.notifications?.totalCount; const handleCloseNotificationClick = useCallback(() => { - notificationRef?.current?.setShowPopup(false); + notificationRef.current?.setShowPopup(false); }, []); return ( diff --git a/app/Base/index.tsx b/app/Base/index.tsx index cdfd090bb8..9aebb333c5 100644 --- a/app/Base/index.tsx +++ b/app/Base/index.tsx @@ -33,6 +33,7 @@ import { } from '#base/utils/restRequest'; import 'mapbox-gl/dist/mapbox-gl.css'; +import { find } from '#base/utils/common'; import localforageInstance from '#base/configs/localforage'; import { mapboxToken } from '#base/configs/env'; @@ -119,7 +120,7 @@ function Base() { setAlerts((prevAlerts) => unique( [...prevAlerts, alert], (a) => a.name, - ) ?? prevAlerts); + )); }, [setAlerts], ); @@ -144,18 +145,18 @@ function Base() { const updateAlertContent = React.useCallback( (name: string, children: React.ReactNode) => { setAlerts((prevAlerts) => { - const i = prevAlerts.findIndex((a) => a.name === name); - if (i === -1) { + const prevAlert = find(prevAlerts, (a) => a.name === name); + if (prevAlert.index === undefined) { return prevAlerts; } const updatedAlert = { - ...prevAlerts[i], + ...prevAlert.value, children, }; const newAlerts = [...prevAlerts]; - newAlerts.splice(i, 1, updatedAlert); + newAlerts.splice(prevAlert.index, 1, updatedAlert); return newAlerts; }); diff --git a/app/Base/utils/apollo.ts b/app/Base/utils/apollo.ts index 8c28ad43bf..96c9e012ec 100644 --- a/app/Base/utils/apollo.ts +++ b/app/Base/utils/apollo.ts @@ -6,7 +6,7 @@ export function isArrayEqual(foo: readonly T[], bar: T[]) { export function checkErrorCode(errors: ApolloError['graphQLErrors'], path: (string | number)[], code: string) { return errors.some((error) => ( - error.path && error.extensions?.code + error.path && error.extensions.code && isArrayEqual(error.path, path) && code === error.extensions.code )); } diff --git a/app/Base/utils/common.ts b/app/Base/utils/common.ts new file mode 100644 index 0000000000..6226f7f05f --- /dev/null +++ b/app/Base/utils/common.ts @@ -0,0 +1,14 @@ +// eslint-disable-next-line import/prefer-default-export +export function find(list: T[], selector: (value: T, index: number, obj: T[]) => boolean) { + const index = list.findIndex(selector); + if (index === -1) { + return { + index: undefined, + value: undefined, + }; + } + return { + index, + value: list[index] as T, + }; +} diff --git a/app/Base/utils/restRequest.ts b/app/Base/utils/restRequest.ts index afa7548993..2485fb2112 100644 --- a/app/Base/utils/restRequest.ts +++ b/app/Base/utils/restRequest.ts @@ -45,9 +45,9 @@ type FormDataCompatibleObj = Record { - const value = jsonData?.[key]; + const value = jsonData[key]; if (value && Array.isArray(value)) { value.forEach((v) => { formData.append(key, v instanceof Blob ? v : String(v)); @@ -179,9 +179,7 @@ export const processDeepOptions: DeepContextInterface['transformOptions'] = ( const csrftoken = getCookie(`deep-${deepEnvironment}-csrftoken`); finalOptions.credentials = 'include'; - if (finalOptions.headers) { - finalOptions.headers['X-CSRFToken'] = csrftoken; - } + finalOptions.headers['X-CSRFToken'] = csrftoken; } return finalOptions; @@ -251,7 +249,7 @@ export const processDeepError = ( const faramErrors = alterResponse(res.errors); const messageForNotification = ( - faramErrors?.$internal + faramErrors.$internal ?? 'Some error occurred while performing this action.' ); diff --git a/app/components/GeoLocationInput/GeoLocationModal/GeoLocationMapInput/index.tsx b/app/components/GeoLocationInput/GeoLocationModal/GeoLocationMapInput/index.tsx index 94b5a42c20..a0f0f26b7c 100644 --- a/app/components/GeoLocationInput/GeoLocationModal/GeoLocationMapInput/index.tsx +++ b/app/components/GeoLocationInput/GeoLocationModal/GeoLocationMapInput/index.tsx @@ -97,13 +97,24 @@ function GeoLocationMapInput(props: Props) { skip: !projectId, variables, onCompleted: (data) => { - const [topRegion] = data.project?.regions?.filter( + if (!data.project?.regions) { + return; + } + + const regions = data.project.regions.filter( (region) => region.isPublished, - ) ?? []; - const topAdminLevel = topRegion?.adminLevels?.find((v) => v.level === 0) - ?? topRegion?.adminLevels?.[0]; + ); + const topRegion = regions[0]; + if (!topRegion) { + // eslint-disable-next-line no-console + console.error('There must be at least on region'); + return; + } + + const topAdminLevel = topRegion.adminLevels?.find((v) => v.level === 0) + ?? topRegion.adminLevels?.[0]; - setSelectedRegion(topRegion?.id); + setSelectedRegion(topRegion.id); setActiveAdminLevel(topAdminLevel?.id); }, }, diff --git a/app/components/NonFieldError/index.tsx b/app/components/NonFieldError/index.tsx index e8486fac01..62ca13b94a 100644 --- a/app/components/NonFieldError/index.tsx +++ b/app/components/NonFieldError/index.tsx @@ -29,7 +29,7 @@ function NonFieldError(props: Props) { ); } - const internalError = error?.[internal]; + const internalError = error[internal]; if (!internalError) { return null; diff --git a/app/components/Notifications/NotificationContainer/index.tsx b/app/components/Notifications/NotificationContainer/index.tsx index 2454c7bfd2..85809cf917 100644 --- a/app/components/Notifications/NotificationContainer/index.tsx +++ b/app/components/Notifications/NotificationContainer/index.tsx @@ -93,8 +93,8 @@ function NotificationContainer(props: Props) { { refetchQueries: ['UserNotificationsCount'], onCompleted: (response) => { - if (response?.notificationStatusUpdate?.ok) { - const newStatus = response.notificationStatusUpdate?.result?.statusDisplay; + if (response.notificationStatusUpdate?.ok) { + const newStatus = response.notificationStatusUpdate.result?.statusDisplay; alert.show( `Successfully updated notification status as ${newStatus?.toLowerCase() ?? 'required'}.`, { diff --git a/app/components/Notifications/NotificationItem/ProjectJoinRequestItem/index.tsx b/app/components/Notifications/NotificationItem/ProjectJoinRequestItem/index.tsx index 308a737bd3..60831fa582 100644 --- a/app/components/Notifications/NotificationItem/ProjectJoinRequestItem/index.tsx +++ b/app/components/Notifications/NotificationItem/ProjectJoinRequestItem/index.tsx @@ -68,8 +68,8 @@ function ProjectJoinRequestItem(props: Props) { { refetchQueries: ['UserNotificationsCount'], onCompleted: (response) => { - if (response?.project?.acceptRejectProject?.ok) { - const status = response.project.acceptRejectProject?.result?.status; + if (response.project?.acceptRejectProject?.ok) { + const status = response.project.acceptRejectProject.result?.status; alert.show( status === 'ACCEPTED' ? 'Successfully added user to the project.' @@ -129,20 +129,20 @@ function ProjectJoinRequestItem(props: Props) { {data?.requested_by?.display_name}), - projectTitle: ({data?.project?.title}), + requestorName: ({data.requested_by.display_name}), + projectTitle: ({data.project.title}), }, ) } - actions={data?.status === 'pending' && ( + actions={data.status === 'pending' && ( <>