From 83c2d4137860204e04263ed9e57627cf8c8b5c7a Mon Sep 17 00:00:00 2001 From: Aditya Khatri Date: Fri, 6 Dec 2024 14:29:41 +0545 Subject: [PATCH] Fix left project visbility issue * Refetch regions when admin level is removed * Disable assisted tagging if project is private --- .../SimplifiedTextView/index.tsx | 5 ++- app/components/LeftPaneEntries/index.tsx | 31 +++++++++++++++---- app/components/entry/CompactSection/index.tsx | 18 ----------- app/components/entry/EntryInput/index.tsx | 6 ---- app/components/entry/types.ts | 5 +-- .../framework/CompactAttributeInput/index.tsx | 13 -------- .../framework/CompactAttributeInput/utils.ts | 21 ------------- app/views/Home/ProjectItem/index.tsx | 4 ++- app/views/Home/index.tsx | 14 +++++++++ .../ProjectEdit/GeoAreas/RegionCard/index.tsx | 3 ++ app/views/ProjectEdit/GeoAreas/index.tsx | 1 + .../LeadDuplicatesModal/LeadView/index.tsx | 1 - 12 files changed, 51 insertions(+), 71 deletions(-) diff --git a/app/components/LeftPaneEntries/SimplifiedTextView/index.tsx b/app/components/LeftPaneEntries/SimplifiedTextView/index.tsx index 824b777ff4..0100d0c418 100644 --- a/app/components/LeftPaneEntries/SimplifiedTextView/index.tsx +++ b/app/components/LeftPaneEntries/SimplifiedTextView/index.tsx @@ -15,6 +15,7 @@ import { GeoArea } from '#components/GeoMultiSelectInput'; import { PartialEntryType as EntryInput } from '#components/entry/schema'; import { Framework } from '#components/entry/types'; +import ProjectContext from '#base/context/ProjectContext'; import useTextSelection from './useTextSelection'; import EntryItem from '../EntryItem'; @@ -207,6 +208,8 @@ function SimplifiedTextView(props: Props) { setTextToAssist(undefined); }, []); + const { project } = React.useContext(ProjectContext); + let children: React.ReactNode = null; if (!text || splits.length === 0) { children = text; @@ -360,7 +363,7 @@ function SimplifiedTextView(props: Props) { )} - {isDefined(onAssistedEntryAdd) && ( + {isDefined(onAssistedEntryAdd) && !project?.isPrivate && ( ( listToMap( @@ -270,11 +273,22 @@ function LeftPaneEntries(props: Props) { setAttachmentsWithEntriesHidden, ] = useState(false); - const leadAttachmentIdsWithEntries = useMemo(() => ( - Object.values(entryAttachmentsMap ?? {}) - .map((entry) => entry?.leadAttachmentId) - .filter(isDefined) - ), [ + const currentEntryClientIds = useMemo(() => ( + entries?.map((item) => item.clientId) + ), [entries]); + + const leadAttachmentIdsWithEntries = useMemo(() => { + if (!entryAttachmentsMap) { + return []; + } + return ( + Object.keys(entryAttachmentsMap) + .filter((item) => currentEntryClientIds?.includes(item)) + .map((entry) => entryAttachmentsMap[entry]?.leadAttachmentId) + .filter(isDefined) + ); + }, [ + currentEntryClientIds, entryAttachmentsMap, ]); @@ -714,12 +728,16 @@ function LeftPaneEntries(props: Props) { }); }, []); - const isAutoExtractionCompatible = isDefined(leadPreview?.textExtractionId); + const isAutoExtractionCompatible = isDefined(leadPreview?.textExtractionId) + && !project?.isPrivate; const errorMessageForAutoExtraction = useMemo(() => { if (isAutoExtractionCompatible) { return undefined; } + if (project?.isPrivate) { + return 'The feature to extract entries through Natural Language Processing (NLP) is currently unavailable for the selected source because the project is private.'; + } if (isDefined(leadPreviewData?.project?.lead?.connectorLead)) { return 'The feature to extract entries through Natural Language Processing (NLP) is currently unavailable for the selected source. The connector associated with the chosen source may be outdated or incompatible with the NLP extraction functionality.'; } @@ -729,6 +747,7 @@ function LeftPaneEntries(props: Props) { return 'The feature to extract entries through Natural Language Processing (NLP) is currently unavailable for the selected source. The selected source appears to be outdated, and the NLP extraction feature is not compatible with older content formats.'; }, [ isAutoExtractionCompatible, + project?.isPrivate, leadPreviewData?.project?.lead, ]); diff --git a/app/components/entry/CompactSection/index.tsx b/app/components/entry/CompactSection/index.tsx index bf7602d934..5e0ee51782 100644 --- a/app/components/entry/CompactSection/index.tsx +++ b/app/components/entry/CompactSection/index.tsx @@ -16,7 +16,6 @@ import { IoAdd } from 'react-icons/io5'; import { GeoArea } from '#components/GeoMultiSelectInput'; import { Widget, - WidgetHint, getHiddenWidgetIds, } from '#types/newAnalyticalFramework'; import CompactAttributeInput, { Props as AttributeInputProps } from '#components/framework/CompactAttributeInput'; @@ -50,7 +49,6 @@ export interface Props { addButtonHidden?: boolean; geoAreaOptions: GeoArea[] | undefined | null; onGeoAreaOptionsChange: React.Dispatch>; - widgetsHints?: WidgetHint[]; recommendations?: PartialAttributeType[]; emptyMessageHidden?: boolean; suggestionMode?: boolean; @@ -78,7 +76,6 @@ function CompactSection(props: Props) { geoAreaOptions, onGeoAreaOptionsChange, onApplyToAll, - widgetsHints, emptyMessageHidden, suggestionMode, recommendations, @@ -102,15 +99,6 @@ function CompactSection(props: Props) { const error = getErrorObject(riskyError); - const hintsMap = useMemo( - () => listToMap( - widgetsHints?.filter((widgetHint) => widgetHint.hints.length > 0), - (widgetHint) => widgetHint.widgetPk, - (widgetHint) => widgetHint, - ), - [widgetsHints], - ); - const recommendationsMap = useMemo( () => listToMap( recommendations, @@ -127,9 +115,6 @@ function CompactSection(props: Props) { return filteredWidgets?.filter( // FIXME: should only check into data, not value (widget) => { - if ((hintsMap?.[widget.id]?.hints.length ?? 0) > 0) { - return true; - } if (widget.widgetId === 'MATRIX1D') { const hasValue = !doesObjectHaveNoData( attributesMap?.[widget.clientId]?.value?.data?.value, @@ -160,7 +145,6 @@ function CompactSection(props: Props) { ); }, [ recommendationsMap, - hintsMap, emptyValueHidden, attributesMap, filteredWidgets, @@ -204,7 +188,6 @@ function CompactSection(props: Props) { applyButtonsHidden: !onApplyToAll, onApplyBelowClick: handleApplyBelowClick, onApplyAllClick: handleApplyAllClick, - widgetsHints, recommendations, suggestionMode, rightComponent, @@ -213,7 +196,6 @@ function CompactSection(props: Props) { [ recommendations, suggestionMode, - widgetsHints, onApplyToAll, onAttributeChange, attributesMap, diff --git a/app/components/entry/EntryInput/index.tsx b/app/components/entry/EntryInput/index.tsx index 048e0e5896..e30a4e6745 100644 --- a/app/components/entry/EntryInput/index.tsx +++ b/app/components/entry/EntryInput/index.tsx @@ -38,7 +38,6 @@ import { GeoArea } from '#components/GeoMultiSelectInput'; import ExcerptInput from '#components/entry/ExcerptInput'; import { Widget, - WidgetHint, } from '#types/newAnalyticalFramework'; import { DeepReplace } from '#utils/types'; @@ -63,7 +62,6 @@ interface EntryInputProps { addButtonHidden?: boolean; hideEntryId?: boolean; - widgetsHints?: WidgetHint[]; recommendations?: PartialAttributeType[]; sectionContainerClassName?: string; @@ -112,7 +110,6 @@ function EntryInput(props: EntryInputProp leadId, variant = 'normal', entryImage, - widgetsHints, error: riskyError, geoAreaOptions, onGeoAreaOptionsChange, @@ -172,7 +169,6 @@ function EntryInput(props: EntryInputProp onAddButtonClick, addButtonHidden, entryClientId: value.clientId, - widgetsHints, recommendations, geoAreaOptions, onGeoAreaOptionsChange, @@ -185,7 +181,6 @@ function EntryInput(props: EntryInputProp }), [ variant, allWidgets, - widgetsHints, recommendations, geoAreaOptions, onGeoAreaOptionsChange, @@ -299,7 +294,6 @@ function EntryInput(props: EntryInputProp onApplyToAll={onApplyToAll} entryClientId={value.clientId} allWidgets={allWidgets} - widgetsHints={widgetsHints} recommendations={recommendations} emptyMessageHidden={variant === 'nlp'} suggestionMode={variant === 'nlp'} diff --git a/app/components/entry/types.ts b/app/components/entry/types.ts index 7fd9ec146a..929af37d8c 100644 --- a/app/components/entry/types.ts +++ b/app/components/entry/types.ts @@ -9,7 +9,6 @@ import { WidgetType as WidgetRaw, BulkEntryInputType, - AnalysisFrameworkPredictionMappingType as MappingsItemRaw, AttributeType as WidgetAttributeRaw, AttributeGqInputType as WidgetInputAttributeRaw, } from '#generated/types'; @@ -20,7 +19,6 @@ import { import { WidgetAttribute as WidgetAttributeFromEntry } from '#types/newEntry'; import { Widget as WidgetFromAF, - MappingsItem, } from '#types/newAnalyticalFramework'; export type EntryRaw = EntryResponseFragment; @@ -38,7 +36,6 @@ export type EntryInput = DeepReplace; -export type FrameworkWithWidgets = DeepReplace, WidgetFromAF>; -export type Framework = DeepReplace; +export type Framework = DeepReplace, WidgetFromAF>; export type Section = NonNullable[number]; export type Widget = WidgetFromAF; diff --git a/app/components/framework/CompactAttributeInput/index.tsx b/app/components/framework/CompactAttributeInput/index.tsx index a77ef8f7b6..7cbba75a9e 100644 --- a/app/components/framework/CompactAttributeInput/index.tsx +++ b/app/components/framework/CompactAttributeInput/index.tsx @@ -23,7 +23,6 @@ import { import { Widget, getWidgetVersion, - WidgetHint, } from '#types/newAnalyticalFramework'; import { PartialEntryType } from '#components/entry/schema'; @@ -45,8 +44,6 @@ import OrganigramWidgetInput from './OrganigramWidgetInput'; import GeoLocationWidgetInput from './GeoLocationWidgetInput'; import BaseWidgetInput from './BaseWidgetInput'; import { - filterSelectHints, - filterScaleHints, filterGeoRecommendations, filterMultiSelectRecommendations, filterOrganigramRecommendations, @@ -102,7 +99,6 @@ export interface Props { onApplyAllClick?: (widgetId: string) => void; applyButtonsHidden?: boolean; - widgetsHints?: WidgetHint[]; recommendations?: PartialAttributeType[]; suggestionMode?: boolean; @@ -128,7 +124,6 @@ function CompactAttributeInput(props: Pro onApplyAllClick, applyButtonsHidden = true, - widgetsHints, recommendations, suggestionMode, @@ -290,9 +285,6 @@ function CompactAttributeInput(props: Pro ); } else if (widget.widgetId === 'SCALE' && (isNotDefined(value) || value.widgetType === widget.widgetId)) { const data = value?.data; - const widgetHints = widgetsHints - ?.filter(filterScaleHints) - ?.find((hint) => hint.widgetPk === widget.id); component = ( (props: Pro widget={widget} error={error?.data as Error | undefined} actions={actions} - widgetHints={widgetHints?.hints} /> ); } else if (widget.widgetId === 'MULTISELECT' && (isNotDefined(value) || value.widgetType === widget.widgetId)) { @@ -334,9 +325,6 @@ function CompactAttributeInput(props: Pro ); } else if (widget.widgetId === 'SELECT' && (isNotDefined(value) || value.widgetType === widget.widgetId)) { const data = value?.data; - const widgetHints = widgetsHints - ?.filter(filterSelectHints) - ?.find((hint) => hint.widgetPk === widget.id); component = ( (props: Pro widget={widget} error={error?.data as Error | undefined} actions={actions} - widgetHints={widgetHints?.hints} suggestionMode={suggestionMode} /> ); diff --git a/app/components/framework/CompactAttributeInput/utils.ts b/app/components/framework/CompactAttributeInput/utils.ts index d4b7d220b4..54541593d3 100644 --- a/app/components/framework/CompactAttributeInput/utils.ts +++ b/app/components/framework/CompactAttributeInput/utils.ts @@ -1,6 +1,3 @@ -import { - WidgetHint, -} from '#types/newAnalyticalFramework'; import { PartialAttributeType, } from '#components/entry/schema'; @@ -45,21 +42,3 @@ export function filterGeoRecommendations( ): recommendation is GeoWidgetAttribute { return recommendation.widgetType === 'GEO'; } - -export function filterGeoHints( - hint: WidgetHint, -): hint is { hints: string[]; widgetPk: string; widgetType: 'GEO' } { - return hint.widgetType === 'GEO'; -} - -export function filterScaleHints( - hint: WidgetHint, -): hint is { hints: string[]; widgetPk: string; widgetType: 'SCALE' } { - return hint.widgetType === 'SCALE'; -} - -export function filterSelectHints( - hint: WidgetHint, -): hint is { hints: string[]; widgetPk: string; widgetType: 'SELECT' } { - return hint.widgetType === 'SELECT'; -} diff --git a/app/views/Home/ProjectItem/index.tsx b/app/views/Home/ProjectItem/index.tsx index 4e3c889674..d418c38558 100644 --- a/app/views/Home/ProjectItem/index.tsx +++ b/app/views/Home/ProjectItem/index.tsx @@ -142,6 +142,7 @@ export interface RecentProjectItemProps { isPinned?: boolean; pinnedId: string | undefined; onProjectPinChange: () => void; + onProjectLeaveSuccess: () => void; disablePinButton: boolean; } @@ -169,6 +170,7 @@ function ProjectItem(props: RecentProjectItemProps) { recentActiveUsers, isPinned, onProjectPinChange, + onProjectLeaveSuccess, disablePinButton, } = props; @@ -248,7 +250,7 @@ function ProjectItem(props: RecentProjectItemProps) { } = leaveProjectResponse; if (ok) { - onProjectPinChange(); + onProjectLeaveSuccess(); alert.show( 'Project successfully left.', { variant: 'success' }, diff --git a/app/views/Home/index.tsx b/app/views/Home/index.tsx index f535cd1c76..4a32276d41 100644 --- a/app/views/Home/index.tsx +++ b/app/views/Home/index.tsx @@ -133,6 +133,7 @@ function Home(props: ViewProps) { const { data: recentProjectsResponse, loading: recentProjectsPending, + refetch: retriggerRecentProjects, } = useQuery( RECENT_PROJECTS, ); @@ -209,6 +210,14 @@ function Home(props: ViewProps) { selectedProjectResponse, ]); + const handleProjectLeaveSuccess = useCallback(() => { + retriggerPinnedProjectsList(); + retriggerRecentProjects(); + }, [ + retriggerPinnedProjectsList, + retriggerRecentProjects, + ]); + const recentProjectsRendererParams = useCallback( (_: string, data: ProjectDetail): RecentProjectItemProps => ({ projectId: data?.id, @@ -232,11 +241,13 @@ function Home(props: ViewProps) { pinnedId: pinnedProjectsList?.find((item) => item.project.id === data?.id)?.id, isPinned: data?.isProjectPinned, onProjectPinChange: retriggerPinnedProjectsList, + onProjectLeaveSuccess: handleProjectLeaveSuccess, disablePinButton: pinButtonDisabled, }), [ pinnedProjectsList, retriggerPinnedProjectsList, + handleProjectLeaveSuccess, pinButtonDisabled, ], ); @@ -264,9 +275,11 @@ function Home(props: ViewProps) { pinnedId: data.id, isPinned: true, onProjectPinChange: retriggerPinnedProjectsList, + onProjectLeaveSuccess: handleProjectLeaveSuccess, disablePinButton: pinButtonDisabled, }), [ + handleProjectLeaveSuccess, retriggerPinnedProjectsList, pinButtonDisabled, ], @@ -352,6 +365,7 @@ function Home(props: ViewProps) { allowedPermissions={selectedProjectDetail?.allowedPermissions} recentActiveUsers={selectedProjectDetail?.recentActiveUsers} isPinned={selectedProjectDetail?.isProjectPinned} + onProjectLeaveSuccess={handleProjectLeaveSuccess} onProjectPinChange={retriggerPinnedProjectsList} disablePinButton={pinButtonDisabled} /> diff --git a/app/views/ProjectEdit/GeoAreas/RegionCard/index.tsx b/app/views/ProjectEdit/GeoAreas/RegionCard/index.tsx index 50efa3feb7..e74ed33d30 100644 --- a/app/views/ProjectEdit/GeoAreas/RegionCard/index.tsx +++ b/app/views/ProjectEdit/GeoAreas/RegionCard/index.tsx @@ -152,6 +152,7 @@ export interface Props { onRegionRetriggerSuccess: () => void; onRegionPublishSuccess: () => void; onRegionDeleteSuccess: () => void; + onAdminRemoveSuccess: () => void; } function RegionCard(props: Props) { @@ -172,6 +173,7 @@ function RegionCard(props: Props) { onRegionRetriggerSuccess, onRegionPublishSuccess, onRegionDeleteSuccess, + onAdminRemoveSuccess, } = props; // setting this so that when user add an admin level, it is updated @@ -312,6 +314,7 @@ function RegionCard(props: Props) { if (ok) { refetchAdminLevels(); + onAdminRemoveSuccess(); if (onAdminLevelUpdate) { onAdminLevelUpdate(); diff --git a/app/views/ProjectEdit/GeoAreas/index.tsx b/app/views/ProjectEdit/GeoAreas/index.tsx index ff77a57273..88d725ce68 100644 --- a/app/views/ProjectEdit/GeoAreas/index.tsx +++ b/app/views/ProjectEdit/GeoAreas/index.tsx @@ -171,6 +171,7 @@ function GeoAreas(props: Props) { onRegionPublishSuccess: regionsRefetch, onRegionDeleteSuccess: regionsRefetch, onAdminLevelAddSuccess: regionsRefetch, + onAdminRemoveSuccess: regionsRefetch, onRegionRetriggerSuccess: regionsRefetch, navigationDisabled, }; diff --git a/app/views/Sources/SourcesTable/LeadDuplicatesModal/LeadView/index.tsx b/app/views/Sources/SourcesTable/LeadDuplicatesModal/LeadView/index.tsx index ac13c721d1..d9db5fe5ef 100644 --- a/app/views/Sources/SourcesTable/LeadDuplicatesModal/LeadView/index.tsx +++ b/app/views/Sources/SourcesTable/LeadDuplicatesModal/LeadView/index.tsx @@ -61,7 +61,6 @@ function LeadView(props: Props) {