From 83c05d8785865c6330b27ab87d2a1483981971f6 Mon Sep 17 00:00:00 2001 From: barshathakuri Date: Tue, 4 Jun 2024 10:37:48 +0545 Subject: [PATCH] Add table tab and add image --- .../LeftPaneEntries/EntryItem/index.tsx | 46 +++- .../LeftPaneEntries/EntryItem/styles.css | 1 + .../TableAndVisualItem/index.tsx | 257 ++++++++++++++++++ .../TableAndVisualItem/styles.css | 72 +++++ app/components/LeftPaneEntries/index.tsx | 196 ++++++++++++- app/components/LeftPaneEntries/styles.css | 14 +- app/components/entry/EditableEntry/index.tsx | 3 - app/components/entry/EntryInput/index.tsx | 2 - app/components/entry/ExcerptInput/index.tsx | 63 ++++- app/components/entry/schema.ts | 1 + app/gqlFragments.ts | 13 + app/views/EntryEdit/index.tsx | 38 ++- .../AnalyticalEntryInput/index.tsx | 1 - .../StoryAnalysisModal/EntryCard/index.tsx | 1 - .../DiscardedEntries/DiscardedEntry/index.tsx | 1 - .../PillarAnalysis/SourceEntryItem/index.tsx | 1 - .../Sources/EntriesGrid/EntryCard/index.tsx | 3 - 17 files changed, 669 insertions(+), 44 deletions(-) create mode 100644 app/components/LeftPaneEntries/TableAndVisualItem/index.tsx create mode 100644 app/components/LeftPaneEntries/TableAndVisualItem/styles.css diff --git a/app/components/LeftPaneEntries/EntryItem/index.tsx b/app/components/LeftPaneEntries/EntryItem/index.tsx index bc6bbac111..3afe7eec20 100644 --- a/app/components/LeftPaneEntries/EntryItem/index.tsx +++ b/app/components/LeftPaneEntries/EntryItem/index.tsx @@ -6,7 +6,7 @@ import { IoArrowUndoSharp, IoTrashBinOutline, } from 'react-icons/io5'; -import { BsFileDiff } from 'react-icons/bs'; +import { BsDownload, BsFileDiff } from 'react-icons/bs'; import { requiredStringCondition } from '@togglecorp/toggle-form'; import { _cs, isDefined } from '@togglecorp/fujs'; import { @@ -20,6 +20,7 @@ import { Heading, useInputState, Button, + QuickActionLink, } from '@the-deep/deep-ui'; import ExcerptInput from '#components/entry/ExcerptInput'; @@ -28,9 +29,12 @@ import EntryCommentWrapper from '#components/entryReview/EntryCommentWrapper'; import { PartialEntryType as EntryInput } from '#components/entry/schema'; import { Entry } from '#components/entry/types'; +import { LeadPreviewAttachmentType } from '#generated/types'; import styles from './styles.css'; +export type EntryAttachmentsMap = { [key: string]: Entry['entryAttachment'] | undefined }; + interface ExcerptModalProps { title: string; excerpt?: string; @@ -99,6 +103,8 @@ interface EntryItemProps extends EntryInput { projectId: string | undefined; entryServerId: string | undefined; draftEntry?: string; + leadAttachmentImage?: LeadPreviewAttachmentType; + entryAttachment?: Entry['entryAttachment'] | undefined | null; } function EntryItem(props: EntryItemProps) { @@ -120,12 +126,13 @@ function EntryItem(props: EntryItemProps) { disableClick, onEntryDelete, onEntryRestore, - imageRaw, entryImage, entryType, deleted, errored, stale, + leadAttachmentImage, + entryAttachment, } = props; const editExcerptDropdownRef: QuickActionDropdownMenuProps['componentRef'] = React.useRef(null); @@ -177,9 +184,8 @@ function EntryItem(props: EntryItemProps) { @@ -310,16 +316,26 @@ function EntryItem(props: EntryItemProps) { onClick={handleClick} role="presentation" > - + + + + )} + > + +
diff --git a/app/components/LeftPaneEntries/EntryItem/styles.css b/app/components/LeftPaneEntries/EntryItem/styles.css index 548c2082bf..959e999226 100644 --- a/app/components/LeftPaneEntries/EntryItem/styles.css +++ b/app/components/LeftPaneEntries/EntryItem/styles.css @@ -1,6 +1,7 @@ .tagged-excerpt { /* NOTE: when user select tagged excerpt, the add button will be visible */ position: relative; + flex-shrink: 0; border: var(--dui-width-separator-thin) solid var(--dui-color-accent); background-color: var(--dui-color-foreground); max-height: 360px; diff --git a/app/components/LeftPaneEntries/TableAndVisualItem/index.tsx b/app/components/LeftPaneEntries/TableAndVisualItem/index.tsx new file mode 100644 index 0000000000..f0de72bb6f --- /dev/null +++ b/app/components/LeftPaneEntries/TableAndVisualItem/index.tsx @@ -0,0 +1,257 @@ +import React, { useMemo } from 'react'; +import { BsDownload } from 'react-icons/bs'; +import { + IoCheckmark, + IoClose, +} from 'react-icons/io5'; + +import { + _cs, + isDefined, + isNotDefined, +} from '@togglecorp/fujs'; +import { + Container, + QuickActionButton, + useInputState, + Button, + QuickActionButtonProps, + QuickActionLink, + NumberOutput, + Tag, +} from '@the-deep/deep-ui'; +import { requiredStringCondition } from '@togglecorp/toggle-form'; + +import ExcerptTextArea from '#components/entry/ExcerptTextArea'; +import ExcerptInput from '#components/entry/ExcerptInput'; +import { + EntryTagTypeEnum, + LeadPreviewAttachmentType, +} from '#generated/types'; + +import styles from './styles.css'; + +interface ExcerptModalProps { + title: string; + excerpt?: string; + onComplete?: (modifiedExcerpt: string | undefined) => void; +} + +export function ExcerptModal(props: ExcerptModalProps) { + const { + title, + excerpt: excerptFromProps, + onComplete, + } = props; + + const [excerpt, setExcerpt] = useInputState(excerptFromProps); + + const handleSubmit = React.useCallback( + () => { + if (onComplete) { + onComplete(excerpt); + } + }, + [onComplete, excerpt], + ); + + return ( + + Done + + )} + > + + + ); +} + +interface TableAndVisualItemProps { + attachmentId: string; + onClick?: (dataId: LeadPreviewAttachmentType['id']) => void; + onApproveButtonClick?: QuickActionButtonProps['onClick']; + onDiscardButtonClick?: QuickActionButtonProps['onClick']; + className?: string; + disableApproveButton?: boolean; + disableDiscardButton?: boolean; + disableClick?: boolean; + errored?: boolean; + deleted?: boolean; + stale?: boolean; + data: LeadPreviewAttachmentType; + isActive?: boolean; + entryId: string | undefined; +} + +function TableAndVisualItem(props: TableAndVisualItemProps) { + const { + className, + attachmentId, + onClick, + onApproveButtonClick, + onDiscardButtonClick, + disableApproveButton, + disableDiscardButton, + disableClick, + deleted, + errored, + stale, + data, + isActive, + entryId, + } = props; + + const entryTypeFromLead = useMemo((): EntryTagTypeEnum | undefined => { + if (data?.type === 'IMAGE' || data?.type === 'XLSX') { + return 'IMAGE'; + } + return undefined; + }, [data]); + + const handleClick = React.useCallback(() => { + if (onClick && !disableClick) { + onClick(attachmentId); + } + }, [attachmentId, onClick, disableClick]); + + if (isNotDefined(entryId)) { + return ( +
+ + + + ) : undefined} + > + {isDefined(entryTypeFromLead) && ( + + )} + +
+ ); + } + + return ( +
+ + + + ) : undefined} + heading={isNotDefined(attachmentId) ? ( + + ) : ( + (unsaved entry) + )} + headingClassName={styles.heading} + headingSize="extraSmall" + headingSectionClassName={styles.headingSection} + footerIcons={( + <> + {stale && !deleted && !errored && ( + + Changed + + )} + {deleted && ( + + Deleted + + )} + {errored && ( + + Error + + )} + + )} + footerQuickActions={isActive && ( + <> + + + + + + + + )} + contentClassName={styles.content} + > + {isDefined(entryTypeFromLead) && ( + + )} +
+ +
+ ); +} + +export default TableAndVisualItem; diff --git a/app/components/LeftPaneEntries/TableAndVisualItem/styles.css b/app/components/LeftPaneEntries/TableAndVisualItem/styles.css new file mode 100644 index 0000000000..3e91d14c8f --- /dev/null +++ b/app/components/LeftPaneEntries/TableAndVisualItem/styles.css @@ -0,0 +1,72 @@ +.tagged-excerpt { + /* NOTE: when user select tagged excerpt, the add button will be visible */ + position: relative; + flex-shrink: 0; + border: var(--dui-width-separator-thin) solid var(--dui-color-accent); + background-color: var(--dui-color-foreground); + max-height: 360px; + overflow-y: auto; + font-weight: var(--dui-font-weight-bold); + user-select: none; + + .heading-section { + overflow: visible; + + .heading { + display: flex; + align-items: baseline; + gap: var(--dui-spacing-medium); + + .entry-id { + color: var(--dui-color-accent); + font-weight: var(--dui-font-weight-bold); + } + + .unsaved-entry { + color: var(--dui-color-text-description); + font-weight: var(--dui-font-weight-light); + font-style: italic; + } + } + } + + .vertical-border { + position: absolute; + top: 0; + right: 0; + background-color: 1px solid red; + width: var(--dui-width-separator-thick); + height: 100%; + } + + &.created-from-assisted { + border-color: var(--dui-color-nlp); + } + + &.active { + .vertical-border { + background-color: var(--dui-color-accent); + animation: grow var(--dui-duration-transition-medium) ease-in forwards; + } + + &.created-from-assisted { + .vertical-border { + background-color: var(--dui-color-nlp); + } + } + } + + .content { + display: flex; + flex-direction:column; + overflow-y: auto; + + .clickable-area { + display: flex; + flex-direction:column; + flex-grow: 1; + cursor: pointer; + overflow-y: auto; + } + } +} diff --git a/app/components/LeftPaneEntries/index.tsx b/app/components/LeftPaneEntries/index.tsx index bc463e50f9..edade5290d 100644 --- a/app/components/LeftPaneEntries/index.tsx +++ b/app/components/LeftPaneEntries/index.tsx @@ -11,6 +11,7 @@ import { isNotDefined, isDefined, randomString, + listToMap, } from '@togglecorp/fujs'; import { gql, useQuery } from '@apollo/client'; import { @@ -37,6 +38,9 @@ import { PendingMessage, Message, Tooltip, + Pager, + ListView, + Switch, } from '@the-deep/deep-ui'; import { IoAdd, @@ -59,6 +63,7 @@ import { LeadPreviewForTextQuery, LeadPreviewForTextQueryVariables, LeadEntriesQuery, + LeadPreviewAttachmentType, } from '#generated/types'; import { PartialEntryType as EntryInput } from '#components/entry/schema'; @@ -70,19 +75,50 @@ import { import CanvasDrawModal from './CanvasDrawModal'; import SimplifiedTextView from './SimplifiedTextView'; import AutoEntriesModal from './AutoEntriesModal'; +import TablesAndVisualsItem from './TableAndVisualItem'; import EntryItem, { ExcerptModal } from './EntryItem'; + import styles from './styles.css'; type EntryImagesMap = { [key: string]: Entry['image'] | undefined }; +export type EntryAttachmentsMap = { [key: string]: Entry['entryAttachment'] | undefined }; + type Lead = NonNullable['lead']>; const LEAD_PREVIEW = gql` query LeadPreviewForText( $leadId: ID!, $projectId: ID!, + $page: Int, + $pageSize: Int, + $excludeAttachmentId: [ID!], ) { project(id: $projectId) { id + leadPreviewAttachments( + lead: $leadId, + page: $page, + pageSize: $pageSize, + excludeAttachmentIds: $excludeAttachmentId, + ) { + results { + id + pageNumber + type + file { + name + url + } + filePreview { + name + url + } + order + } + totalCount + page + pageSize + } lead(id: $leadId) { id extractionStatus @@ -99,7 +135,9 @@ const LEAD_PREVIEW = gql` const entryKeySelector = (e: EntryInput) => e.clientId; -export type TabOptions = 'simplified' | 'original' | 'entries' | undefined; +const leadAttachmentKeySelector = (e: LeadPreviewAttachmentType) => e.id; + +export type TabOptions = 'simplified' | 'original' | 'entries' | 'visuals' | undefined; interface Props { className?: string; @@ -113,15 +151,18 @@ interface Props { onEntryRestore?: (entryClientId: string) => void; onApproveButtonClick?: (entryClientId: string) => void; onDiscardButtonClick?: (entryClientId: string) => void; + onAttachmentClick?: (entryClientId: string) => void; lead?: Lead | null; leadId: string; hideSimplifiedPreview?: boolean; hideOriginalPreview?: boolean; entryImagesMap: EntryImagesMap | undefined; + entryAttachmentsMap?: EntryAttachmentsMap | undefined; isEntrySelectionActive?: boolean; entriesError?: Partial> | undefined; projectId: string | undefined; - defaultTab?: 'entries' | 'simplified' | 'original'; + leadAttachmentId?: string; + defaultTab?: 'entries' | 'simplified' | 'original' | 'visuals'; frameworkDetails?: Framework; activeTabRef?: React.MutableRefObject<{ setActiveTab: React.Dispatch>; @@ -129,8 +170,14 @@ interface Props { listComponentRef?: React.MutableRefObject<{ scrollTo: (item: string) => void; } | null>; + page?: number; + pageSize?: number; + setPage?: (page: number) => void; + setPageSize?: (pageSize: number) => void; } +const defaultMaxItemsPerPage = 10; + function LeftPane(props: Props) { const { className, @@ -156,8 +203,16 @@ function LeftPane(props: Props) { activeTabRef, frameworkDetails, onAssistedEntryAdd, + leadAttachmentId, + entryAttachmentsMap, } = props; + const [showResults, setShowResults] = useState(false); + + const handleToggle = () => { + setShowResults(!showResults); + }; + const alert = useAlert(); const { project } = useContext(ProjectContext); const { user } = useContext(UserContext); @@ -202,13 +257,22 @@ function LeftPane(props: Props) { const [fullScreenMode, setFullScreenMode] = useState(false); const editExcerptDropdownRef: QuickActionDropdownMenuProps['componentRef'] = useRef(null); + const [activePage, setActivePage] = useState(1); + const [maxItemsPerPage, setMaxItemsPerPage] = useState(defaultMaxItemsPerPage); const variables = useMemo( () => ((leadId && projectId) ? ({ leadId, projectId, + page: activePage, + pageSize: maxItemsPerPage, }) : undefined), - [leadId, projectId], + [ + leadId, + projectId, + activePage, + maxItemsPerPage, + ], ); const { @@ -225,6 +289,8 @@ function LeftPane(props: Props) { const leadPreview = leadPreviewData?.project?.lead?.leadPreview; const extractionStatus = leadPreviewData?.project?.lead?.extractionStatus; + const leadPreviewAttachments = leadPreviewData?.project?.leadPreviewAttachments?.results; + const leadPreviewCount = leadPreviewData?.project?.leadPreviewAttachments?.totalCount; const handleScreenshotCaptureError = useCallback((message: React.ReactNode) => { alert.show( @@ -256,6 +322,7 @@ function LeftPane(props: Props) { entryType: 'IMAGE', lead: leadId, imageRaw: capturedImageUrl, + leadAttachment: leadAttachmentId, }); } if (fullScreenMode && isDefined(document.exitFullscreen)) { @@ -265,6 +332,7 @@ function LeftPane(props: Props) { fullScreenMode, capturedImageUrl, leadId, + leadAttachmentId, onEntryCreate, setShowCanvasDrawModalFalse, setShowScreenshotFalse, @@ -304,6 +372,19 @@ function LeftPane(props: Props) { } }, [leadId, onEntryCreate]); + const handleAttachmentClick = useCallback((selectedAttachment: string) => { + if (onEntryCreate) { + onEntryCreate({ + clientId: randomString(), + entryType: 'ATTACHMENT', + lead: leadId, + leadAttachment: selectedAttachment, + excerpt: '', + droppedExcerpt: '', + }); + } + }, [leadId, onEntryCreate]); + const handleExcerptAddFromOriginal = useCallback((selectedText: string | undefined) => { if (onEntryCreate) { onEntryCreate({ @@ -321,6 +402,23 @@ function LeftPane(props: Props) { } }, [leadId, onEntryCreate]); + const entriesWithLeadAttachments = useMemo(() => (listToMap( + entries?.filter((entry) => isDefined(entry.leadAttachment)), + (entry) => entry.leadAttachment ?? '', + (entry) => entry.clientId, + )), [entries]); + + const allEntriesWithLeadAttachments = entries?.filter( + (entry) => isDefined(entry.entryAttachment?.leadAttachmentId), + ); + + const leadAttachmentIdsToExclude = useMemo( + () => ([ + ...Object.keys(entriesWithLeadAttachments ?? {}), + ...(allEntriesWithLeadAttachments ?? []), + ]), [entriesWithLeadAttachments, allEntriesWithLeadAttachments], + ); + const entryItemRendererParams = useCallback(( entryId: string, entry: EntryInput, @@ -336,7 +434,12 @@ function LeftPane(props: Props) { onExcerptChange, onEntryDelete, onEntryRestore, + leadAttachmentImage: entry?.leadAttachment ? leadPreviewAttachments?.find( + (attachment) => attachment.id === entry.leadAttachment, + ) : undefined, entryImage: entry?.image ? entryImagesMap?.[entry.image] : undefined, + entryAttachment: entry?.entryAttachment + ? entryAttachmentsMap?.[entry.entryAttachment] : undefined, onApproveButtonClick, onDiscardButtonClick, disableClick: isEntrySelectionActive, @@ -354,6 +457,37 @@ function LeftPane(props: Props) { onEntryRestore, entryImagesMap, isEntrySelectionActive, + leadPreviewAttachments, + entryAttachmentsMap, + ]); + + const leadAttachmentItemRendererParams = useCallback(( + attachmentId: string, + attachment: LeadPreviewAttachmentType, + index: number, + ) => ({ + ...attachment, + attachmentId: attachment.id, + index, + entryServerId: attachment?.id, + isActive: isDefined(activeEntry) + && activeEntry === entriesWithLeadAttachments?.[attachment.id], + entryId: entriesWithLeadAttachments?.[attachmentId], + onClick: handleAttachmentClick, + onApproveButtonClick, + onDiscardButtonClick, + className: styles.entryItem, + disableClick: isEntrySelectionActive, + errored: entriesError?.[attachmentId], + data: attachment, + }), [ + handleAttachmentClick, + onApproveButtonClick, + entriesError, + onDiscardButtonClick, + activeEntry, + isEntrySelectionActive, + entriesWithLeadAttachments, ]); const activeEntryDetails = useMemo(() => ( @@ -602,6 +736,12 @@ function LeftPane(props: Props) { Simplified Text )} + + Tables & Visuals + {!hideOriginalPreview && ( )} + + + )} + footerActions={( + + )} + > + + )} + emptyMessage="No entries found" + messageShown + messageIconShown + /> + + {!hideOriginalPreview && ( @@ -388,8 +387,6 @@ function EditableEntry(props: Props) { value={value.excerpt} image={entryImage} imageRaw={undefined} - // FIXME: pass this after image drag/drop is implemented - leadImageUrl={undefined} entryType={value.entryType} readOnly /> diff --git a/app/components/entry/EntryInput/index.tsx b/app/components/entry/EntryInput/index.tsx index fea7d32160..cdc71f704b 100644 --- a/app/components/entry/EntryInput/index.tsx +++ b/app/components/entry/EntryInput/index.tsx @@ -254,8 +254,6 @@ function EntryInput(props: EntryInputProp image={entryImage} imageRaw={value.imageRaw} readOnly={readOnly} - // FIXME: pass this after image drag/drop is implemented - leadImageUrl={undefined} />
)} diff --git a/app/components/entry/ExcerptInput/index.tsx b/app/components/entry/ExcerptInput/index.tsx index 40eadc6ea0..14b304d066 100644 --- a/app/components/entry/ExcerptInput/index.tsx +++ b/app/components/entry/ExcerptInput/index.tsx @@ -1,8 +1,11 @@ import React from 'react'; +import { BsDownload } from 'react-icons/bs'; import { _cs } from '@togglecorp/fujs'; import { + Container, ImagePreview, Message, + QuickActionLink, } from '@the-deep/deep-ui'; import { genericMemo } from '#utils/common'; @@ -19,9 +22,10 @@ type Props = { entryType: EntryType['entryType']; value: string | undefined | null; // droppedExcerpt: EntryType['droppedExcerpt'] | undefined; - image: EntryType['image'] | undefined; - imageRaw: string | undefined; - leadImageUrl: string | undefined; + + image: EntryType['image'] | undefined; // image from server (screenshot) + imageRaw: string | undefined; // temporary image + entryAttachment?: EntryType['entryAttachment'] | undefined; // copy of lead attachment that also has image from server } & ({ name: N; onChange: (newVal: string | undefined, name: N) => void; @@ -40,12 +44,12 @@ function ExcerptInput(props: Props) { entryType, image, imageRaw, - leadImageUrl, value, + entryAttachment, } = props; if (entryType === 'IMAGE') { - const imageSrc = image?.file?.url ?? leadImageUrl ?? imageRaw; + const imageSrc = imageRaw ?? image?.file?.url; return (
{imageSrc ? ( @@ -83,6 +87,55 @@ function ExcerptInput(props: Props) {
); } + if (entryType === 'ATTACHMENT') { + const attachmentSrc = imageRaw ?? entryAttachment?.filePreview?.url; + return ( + + + + ) : undefined} + > + {attachmentSrc ? ( + + ) : ( + + )} + {!props.readOnly && ( // eslint-disable-line react/destructuring-assignment + + )} + {props.readOnly && value && ( // eslint-disable-line react/destructuring-assignment +
+ {value} +
+ )} +
+ ); + } if (entryType === 'EXCERPT') { // eslint-disable-next-line react/destructuring-assignment return props.readOnly ? ( diff --git a/app/components/entry/schema.ts b/app/components/entry/schema.ts index 2291ed9cb1..a124e5cf1e 100644 --- a/app/components/entry/schema.ts +++ b/app/components/entry/schema.ts @@ -109,6 +109,7 @@ export const getEntrySchema = (widgets: Partial>): EntryS leadImage: [defaultUndefinedType], // NOTE: to send images from lead tabularField: [], excerpt: [], + leadAttachment: [], droppedExcerpt: [], // highlightHidden: [], attributes: getAttributesSchema(widgets), diff --git a/app/gqlFragments.ts b/app/gqlFragments.ts index de8d00c0f9..684831baf9 100644 --- a/app/gqlFragments.ts +++ b/app/gqlFragments.ts @@ -13,6 +13,19 @@ export const ENTRY_FRAGMENT = gql` verifiedBy { id } + entryAttachment { + entryFileType + id + leadAttachmentId + file { + name + url + } + filePreview { + name + url + } + } controlled attributes { clientId diff --git a/app/views/EntryEdit/index.tsx b/app/views/EntryEdit/index.tsx index d2547efb82..2456e1777f 100644 --- a/app/views/EntryEdit/index.tsx +++ b/app/views/EntryEdit/index.tsx @@ -104,6 +104,7 @@ interface VirtualizedEntryListComponent { } export type EntryImagesMap = { [key: string]: Entry['image'] | undefined }; +export type EntryAttachmentsMap = { [key: string]: Entry['entryAttachment'] | undefined }; const DELETE_LEN = 100; const UPDATE_LEN = 100; @@ -117,6 +118,7 @@ function transformEntry(entry: Entry): EntryInputType { ...entry, lead: entry.lead.id, image: entry.image?.id, + entryAttachment: entry.entryAttachment?.id, attributes: entry.attributes?.map((attribute) => ({ ...attribute, // NOTE: we don't need this on form @@ -134,6 +136,8 @@ function EntryEdit(props: Props) { const { project } = React.useContext(ProjectContext); const { user } = React.useContext(UserContext); const { leadId } = useParams<{ leadId: string }>(); + const { leadAttachmentId } = useParams<{ leadAttachmentId: string }>(); + const [ commentsCountMap, setCommentsCountMap, @@ -357,6 +361,10 @@ function EntryEdit(props: Props) { } | undefined>(); const [entryImagesMap, setEntryImagesMap] = useState(); + const [ + entryAttachmentsMap, + setEntryAttachmentMap, + ] = useState(); const [ updateLead, @@ -420,6 +428,7 @@ function EntryEdit(props: Props) { shouldFinalizeRef.current = undefined; return; } + const submit = createSubmitHandler( leadFormValidate, (err) => { @@ -452,6 +461,7 @@ function EntryEdit(props: Props) { leadId, projectId, updateLead, + // leadAttachmentId, ]); // NOTE: handling bulkUpdateEntriesPending because we are making another @@ -623,6 +633,17 @@ function EntryEdit(props: Props) { ...newImagesMap, })); + const newAttachmentMap = listToMap( + saveResult?.map((attachment) => attachment?.entryAttachment) + .filter(isDefined), + (d) => d.id, + (d) => d, + ); + setEntryAttachmentMap((oldMap) => ({ + ...oldMap, + ...newAttachmentMap, + })); + setFormValue((oldValue) => { const entries = oldValue?.entries ?? []; const filteredEntries = entries.filter((item) => ( @@ -1135,6 +1156,16 @@ function EntryEdit(props: Props) { (d) => d, ); setEntryImagesMap(imagesMap); + + const attachmentMap = listToMap( + leadFromResponse.entries + ?.map((attachment) => attachment?.entryAttachment) + .filter(isDefined), + (d) => d.id, + (d) => d, + ); + setEntryAttachmentMap(attachmentMap); + const finalEntryIdFromLocation = entryIdFromLocation ?? entries?.find( (e) => e.id === String(entryServerIdFromLocation), @@ -1351,8 +1382,6 @@ function EntryEdit(props: Props) { value={datum.excerpt} image={datum?.image ? entryImagesMap?.[datum.image] : undefined} imageRaw={undefined} - // FIXME: pass this after image drag/drop is implemented - leadImageUrl={undefined} entryType={datum.entryType} readOnly /> @@ -1366,7 +1395,6 @@ function EntryEdit(props: Props) { value={datum.excerpt} image={datum?.image ? entryImagesMap?.[datum.image] : undefined} imageRaw={undefined} - leadImageUrl={undefined} entryType={datum.entryType} readOnly /> @@ -1407,7 +1435,6 @@ function EntryEdit(props: Props) { ? entryImagesMap?.[currentEntry.image] : undefined} imageRaw={undefined} - leadImageUrl={undefined} entryType={currentEntry.entryType} readOnly /> @@ -1586,6 +1613,7 @@ function EntryEdit(props: Props) { leadId={leadId} listComponentRef={primaryPageListComponentRef} entryImagesMap={entryImagesMap} + entryAttachmentsMap={entryAttachmentsMap} isEntrySelectionActive={isEntrySelectionActive} entriesError={entriesErrorStateMap} frameworkDetails={frameworkDetails ?? undefined} @@ -1672,6 +1700,8 @@ function EntryEdit(props: Props) { onDiscardButtonClick={handleEntryChangeDiscard} lead={lead} leadId={leadId} + leadAttachmentId={leadAttachmentId} + entryAttachmentsMap={entryAttachmentsMap} hideSimplifiedPreview hideOriginalPreview listComponentRef={secondaryPageListComponentRef} diff --git a/app/views/PillarAnalysis/AnalyticalStatementInput/AnalyticalEntryInput/index.tsx b/app/views/PillarAnalysis/AnalyticalStatementInput/AnalyticalEntryInput/index.tsx index 11d3ae12ae..d4a68ce35f 100644 --- a/app/views/PillarAnalysis/AnalyticalStatementInput/AnalyticalEntryInput/index.tsx +++ b/app/views/PillarAnalysis/AnalyticalStatementInput/AnalyticalEntryInput/index.tsx @@ -270,7 +270,6 @@ function AnalyticalEntryInput(props: AnalyticalEntryInputProps) { entryType={entry.entryType} readOnly imageRaw={undefined} - leadImageUrl={undefined} /> )} {entry && entryCardFlipped && ( diff --git a/app/views/PillarAnalysis/AnalyticalStatementInput/StoryAnalysisModal/EntryCard/index.tsx b/app/views/PillarAnalysis/AnalyticalStatementInput/StoryAnalysisModal/EntryCard/index.tsx index c089ef810a..4927cc0103 100644 --- a/app/views/PillarAnalysis/AnalyticalStatementInput/StoryAnalysisModal/EntryCard/index.tsx +++ b/app/views/PillarAnalysis/AnalyticalStatementInput/StoryAnalysisModal/EntryCard/index.tsx @@ -156,7 +156,6 @@ function EntryCard(props: Props) { entryType={entry.entryType} readOnly imageRaw={undefined} - leadImageUrl={undefined} /> )} {entry && entryCardFlipped && ( diff --git a/app/views/PillarAnalysis/DiscardedEntries/DiscardedEntry/index.tsx b/app/views/PillarAnalysis/DiscardedEntries/DiscardedEntry/index.tsx index 9f23c9e59f..792651f37b 100644 --- a/app/views/PillarAnalysis/DiscardedEntries/DiscardedEntry/index.tsx +++ b/app/views/PillarAnalysis/DiscardedEntries/DiscardedEntry/index.tsx @@ -153,7 +153,6 @@ function DiscardedEntry(props: Props) { image={image} value={excerpt} imageRaw={undefined} - leadImageUrl={undefined} readOnly /> diff --git a/app/views/PillarAnalysis/SourceEntryItem/index.tsx b/app/views/PillarAnalysis/SourceEntryItem/index.tsx index b6dc53de21..33eb9b0478 100644 --- a/app/views/PillarAnalysis/SourceEntryItem/index.tsx +++ b/app/views/PillarAnalysis/SourceEntryItem/index.tsx @@ -302,7 +302,6 @@ function SourceEntryItem(props: Props) { image={image} value={excerpt} imageRaw={undefined} - leadImageUrl={undefined} readOnly /> )} diff --git a/app/views/Sources/EntriesGrid/EntryCard/index.tsx b/app/views/Sources/EntriesGrid/EntryCard/index.tsx index 498f9d43eb..b2c1bdf527 100644 --- a/app/views/Sources/EntriesGrid/EntryCard/index.tsx +++ b/app/views/Sources/EntriesGrid/EntryCard/index.tsx @@ -223,10 +223,7 @@ function EntryCard(props: Props) { entryType={entry.entryType} value={entry.excerpt} image={entry.image} - // NOTE: no need to pass imageRaw and leadImageUrl as they - // are not retrieved from server imageRaw={undefined} - leadImageUrl={undefined} // droppedExcerpt={entry.droppedExcerpt} // tabularFieldData={entry.tabularFieldData} readOnly