UI: Add support for deleting a post in table entity (#3405)

* UI: Add support for deleting a post in table entity

* Addressing review comment
This commit is contained in:
Sachin Chaurasiya 2022-03-14 19:21:10 +05:30 committed by GitHub
parent 3dfae301fe
commit eb436adcb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 358 additions and 135 deletions

View File

@ -74,3 +74,10 @@ export const postFeedById: Function = (
): Promise<AxiosResponse> => {
return APIClient.post(`/feed/${id}/posts`, data);
};
export const deletePostById: Function = (
threadId: string,
postId: string
): Promise<AxiosResponse> => {
return APIClient.delete(`/feed/${threadId}/posts/${postId}`);
};

View File

@ -0,0 +1,61 @@
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Post } from 'Models';
import { HTMLAttributes } from 'react';
export interface ConfirmState {
state: boolean;
threadId: string | undefined;
postId: string | undefined;
}
export interface ActivityFeedCardProp extends HTMLAttributes<HTMLDivElement> {
feed: Post;
entityLink?: string;
repliedUsers?: Array<string>;
replies?: number;
isEntityFeed?: boolean;
threadId?: string;
lastReplyTimeStamp?: number;
isFooterVisible?: boolean;
onThreadSelect?: (id: string) => void;
deletePostHandler?: (threadId: string, postId: string) => void;
}
export interface FeedHeaderProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityFeedCardProp, 'isEntityFeed'> {
createdBy: string;
timeStamp: number;
entityType: string;
entityFQN: string;
entityField: string;
}
export interface FeedBodyProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityFeedCardProp, 'deletePostHandler'> {
message: string;
postId: string;
threadId: string;
onConfirmation: (data: ConfirmState) => void;
}
export interface FeedFooterProp
extends HTMLAttributes<HTMLDivElement>,
Pick<
ActivityFeedCardProp,
| 'replies'
| 'repliedUsers'
| 'threadId'
| 'onThreadSelect'
| 'lastReplyTimeStamp'
| 'isFooterVisible'
> {}

View File

@ -14,8 +14,7 @@
import { AxiosResponse } from 'axios';
import classNames from 'classnames';
import { isUndefined, toLower } from 'lodash';
import { Post } from 'Models';
import React, { FC, Fragment, HTMLAttributes, useState } from 'react';
import React, { FC, Fragment, useState } from 'react';
import { Link } from 'react-router-dom';
import AppState from '../../../AppState';
import { getUserByName } from '../../../axiosAPIs/userAPI';
@ -36,41 +35,14 @@ import Avatar from '../../common/avatar/Avatar';
import PopOver from '../../common/popover/PopOver';
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
import Loader from '../../Loader/Loader';
interface ActivityFeedCardProp extends HTMLAttributes<HTMLDivElement> {
feed: Post;
entityLink?: string;
repliedUsers?: Array<string>;
replies?: number;
isEntityFeed?: boolean;
threadId?: string;
lastReplyTimeStamp?: number;
isFooterVisible?: boolean;
onThreadSelect?: (id: string) => void;
}
interface FeedHeaderProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityFeedCardProp, 'isEntityFeed'> {
createdBy: string;
timeStamp: number;
entityType: string;
entityFQN: string;
entityField: string;
}
interface FeedBodyProp extends HTMLAttributes<HTMLDivElement> {
message: string;
}
interface FeedFooterProp
extends HTMLAttributes<HTMLDivElement>,
Pick<
import ConfirmationModal from '../../Modals/ConfirmationModal/ConfirmationModal';
import {
ActivityFeedCardProp,
| 'replies'
| 'repliedUsers'
| 'threadId'
| 'onThreadSelect'
| 'lastReplyTimeStamp'
| 'isFooterVisible'
> {}
ConfirmState,
FeedBodyProp,
FeedFooterProp,
FeedHeaderProp,
} from './ActivityFeedCard.interface';
const FeedHeader: FC<FeedHeaderProp> = ({
className,
@ -230,15 +202,31 @@ const FeedHeader: FC<FeedHeaderProp> = ({
);
};
const FeedBody: FC<FeedBodyProp> = ({ message, className }) => {
const FeedBody: FC<FeedBodyProp> = ({
message,
className,
threadId,
postId,
deletePostHandler,
onConfirmation,
}) => {
return (
<Fragment>
<div className={className}>
<RichTextEditorPreviewer
className="activity-feed-card-text"
enableSeeMoreVariant={false}
markdown={getFrontEndFormat(message)}
/>
{threadId && postId && deletePostHandler ? (
<span
className="tw-opacity-0 hover:tw-opacity-100 tw-cursor-pointer"
onClick={() => onConfirmation({ state: true, postId, threadId })}>
<SVGIcons alt="delete" icon={Icons.DELETE} width="12px" />
</span>
) : null}
</div>
</Fragment>
);
};
@ -296,11 +284,37 @@ const ActivityFeedCard: FC<ActivityFeedCardProp> = ({
lastReplyTimeStamp,
onThreadSelect,
isFooterVisible = false,
deletePostHandler,
}) => {
const entityType = getEntityType(entityLink as string);
const entityFQN = getEntityFQN(entityLink as string);
const entityField = getEntityField(entityLink as string);
const [confirmationState, setConfirmationState] = useState<ConfirmState>({
state: false,
threadId: undefined,
postId: undefined,
});
const onCancel = () => {
setConfirmationState({
state: false,
threadId: undefined,
postId: undefined,
});
};
const onDelete = () => {
if (confirmationState.postId && confirmationState.threadId) {
deletePostHandler?.(confirmationState.threadId, confirmationState.postId);
}
onCancel();
};
const onConfirmation = (data: ConfirmState) => {
setConfirmationState(data);
};
return (
<div className={classNames(className)}>
<FeedHeader
@ -312,8 +326,12 @@ const ActivityFeedCard: FC<ActivityFeedCardProp> = ({
timeStamp={feed.postTs}
/>
<FeedBody
className="tw-mx-7 tw-ml-9 tw-bg-white tw-p-3 tw-border tw-border-main tw-rounded-md tw-break-all"
className="tw-mx-7 tw-ml-9 tw-bg-white tw-p-3 tw-border tw-border-main tw-rounded-md tw-break-all tw-flex tw-justify-between "
deletePostHandler={deletePostHandler}
message={feed.message}
postId={feed.id}
threadId={threadId as string}
onConfirmation={onConfirmation}
/>
<FeedFooter
className="tw-ml-9 tw-mt-3"
@ -324,6 +342,18 @@ const ActivityFeedCard: FC<ActivityFeedCardProp> = ({
threadId={threadId}
onThreadSelect={onThreadSelect}
/>
{confirmationState.state && (
<ConfirmationModal
bodyClassName="tw-h-18"
bodyText="Are you sure you want to permanently remove this post?"
cancelText="Cancel"
className="tw-w-auto"
confirmText="Delete"
header="Delete Post?"
onCancel={onCancel}
onConfirm={onDelete}
/>
)}
</div>
);
};

View File

@ -0,0 +1,44 @@
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EntityThread } from 'Models';
import { HTMLAttributes } from 'react';
export interface ActivityFeedListProp extends HTMLAttributes<HTMLDivElement> {
feedList: EntityThread[];
withSidePanel?: boolean;
isEntityFeed?: boolean;
entityName?: string;
postFeedHandler?: (value: string, id: string) => void;
deletePostHandler?: (threadId: string, postId: string) => void;
}
export interface FeedListSeparatorProp extends HTMLAttributes<HTMLDivElement> {
relativeDay: string;
}
export interface FeedListBodyProp
extends HTMLAttributes<HTMLDivElement>,
Pick<FeedListSeparatorProp, 'relativeDay'>,
Pick<
ActivityFeedListProp,
'isEntityFeed' | 'withSidePanel' | 'deletePostHandler'
> {
updatedFeedList: Array<EntityThread & { relativeDay: string }>;
selctedThreadId: string;
onThreadIdSelect: (value: string) => void;
onThreadIdDeselect: () => void;
onThreadSelect: (value: string) => void;
postFeed: (value: string) => void;
onViewMore: () => void;
}

View File

@ -14,13 +14,7 @@
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import { EntityThread } from 'Models';
import React, {
FC,
Fragment,
HTMLAttributes,
useEffect,
useState,
} from 'react';
import React, { FC, Fragment, useEffect, useState } from 'react';
import { withLoader } from '../../../hoc/withLoader';
import { getFeedListWithRelativeDays } from '../../../utils/FeedUtils';
import ActivityFeedCard, {
@ -29,30 +23,11 @@ import ActivityFeedCard, {
import ActivityFeedEditor from '../ActivityFeedEditor/ActivityFeedEditor';
import ActivityFeedPanel from '../ActivityFeedPanel/ActivityFeedPanel';
import NoFeedPlaceholder from '../NoFeedPlaceholder/NoFeedPlaceholder';
interface ActivityFeedListProp extends HTMLAttributes<HTMLDivElement> {
feedList: EntityThread[];
withSidePanel?: boolean;
isEntityFeed?: boolean;
entityName?: string;
postFeedHandler?: (value: string, id: string) => void;
}
interface FeedListSeparatorProp extends HTMLAttributes<HTMLDivElement> {
relativeDay: string;
}
interface FeedListBodyProp
extends HTMLAttributes<HTMLDivElement>,
Pick<FeedListSeparatorProp, 'relativeDay'>,
Pick<ActivityFeedListProp, 'isEntityFeed' | 'withSidePanel'> {
updatedFeedList: Array<EntityThread & { relativeDay: string }>;
selctedThreadId: string;
onThreadIdSelect: (value: string) => void;
onThreadIdDeselect: () => void;
onThreadSelect: (value: string) => void;
postFeed: (value: string) => void;
onViewMore: () => void;
}
import {
ActivityFeedListProp,
FeedListBodyProp,
FeedListSeparatorProp,
} from './ActivityFeedList.interface';
export const FeedListSeparator: FC<FeedListSeparatorProp> = ({
className,
@ -81,6 +56,7 @@ const FeedListBody: FC<FeedListBodyProp> = ({
postFeed,
onViewMore,
selctedThreadId,
deletePostHandler,
}) => {
return (
<Fragment>
@ -91,6 +67,7 @@ const FeedListBody: FC<FeedListBodyProp> = ({
message: feed.message,
postTs: feed.threadTs,
from: feed.createdBy,
id: feed.id,
};
const postLength = feed.posts.length;
const replies = feed.postsCount - 1;
@ -128,8 +105,10 @@ const FeedListBody: FC<FeedListBodyProp> = ({
) : null}
<ActivityFeedCard
className="tw-mb-6 tw-ml-9"
deletePostHandler={deletePostHandler}
feed={lastPost}
isEntityFeed={isEntityFeed}
threadId={feed.id}
/>
<p
className="link-text tw-text-xs tw-underline tw-ml-9 tw-pl-9 tw--mt-4 tw-mb-6"
@ -170,6 +149,7 @@ const ActivityFeedList: FC<ActivityFeedListProp> = ({
isEntityFeed = false,
postFeedHandler,
entityName,
deletePostHandler,
}) => {
const { updatedFeedList, relativeDays } =
getFeedListWithRelativeDays(feedList);
@ -234,6 +214,7 @@ const ActivityFeedList: FC<ActivityFeedListProp> = ({
relativeDay={d}
/>
<FeedListBody
deletePostHandler={deletePostHandler}
isEntityFeed={isEntityFeed}
postFeed={postFeed}
relativeDay={d}
@ -251,6 +232,7 @@ const ActivityFeedList: FC<ActivityFeedListProp> = ({
{withSidePanel && selectedThread && isPanelOpen ? (
<Fragment>
<ActivityFeedPanel
deletePostHandler={deletePostHandler}
open={!isUndefined(selectedThread) && isPanelOpen}
postFeed={postFeed}
selectedThread={selectedThread}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EntityThread } from 'Models';
import { HTMLAttributes } from 'react';
export interface ActivityFeedPanelProp extends HTMLAttributes<HTMLDivElement> {
selectedThread: EntityThread;
open?: boolean;
onCancel: () => void;
postFeed: (value: string) => void;
deletePostHandler?: (threadId: string, postId: string) => void;
}
export interface FeedPanelHeaderProp
extends HTMLAttributes<HTMLHeadingElement>,
Pick<ActivityFeedPanelProp, 'onCancel'> {
entityField: string;
noun?: string;
onShowNewConversation?: (v: boolean) => void;
}
export interface FeedPanelOverlayProp
extends HTMLAttributes<HTMLButtonElement>,
Pick<ActivityFeedPanelProp, 'onCancel'> {}
export interface FeedPanelBodyProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityFeedPanelProp, 'deletePostHandler'> {
threadData: EntityThread;
isLoading: boolean;
}

View File

@ -15,13 +15,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { AxiosResponse } from 'axios';
import classNames from 'classnames';
import { EntityThread, Post } from 'Models';
import React, {
FC,
Fragment,
HTMLAttributes,
useEffect,
useState,
} from 'react';
import React, { FC, Fragment, useEffect, useState } from 'react';
import { getFeedById } from '../../../axiosAPIs/feedsAPI';
import { getEntityField, getReplyText } from '../../../utils/FeedUtils';
import { Button } from '../../buttons/Button/Button';
@ -29,28 +23,12 @@ import PopOver from '../../common/popover/PopOver';
import Loader from '../../Loader/Loader';
import ActivityFeedCard from '../ActivityFeedCard/ActivityFeedCard';
import ActivityFeedEditor from '../ActivityFeedEditor/ActivityFeedEditor';
interface ActivityFeedPanelProp extends HTMLAttributes<HTMLDivElement> {
selectedThread: EntityThread;
open?: boolean;
onCancel: () => void;
postFeed: (value: string) => void;
}
interface FeedPanelHeaderProp
extends HTMLAttributes<HTMLHeadingElement>,
Pick<ActivityFeedPanelProp, 'onCancel'> {
entityField: string;
noun?: string;
onShowNewConversation?: (v: boolean) => void;
}
interface FeedPanelOverlayProp
extends HTMLAttributes<HTMLButtonElement>,
Pick<ActivityFeedPanelProp, 'onCancel'> {}
interface FeedPanelBodyProp extends HTMLAttributes<HTMLDivElement> {
threadData: EntityThread;
isLoading: boolean;
}
import {
ActivityFeedPanelProp,
FeedPanelBodyProp,
FeedPanelHeaderProp,
FeedPanelOverlayProp,
} from './ActivityFeedPanel.interface';
export const FeedPanelHeader: FC<FeedPanelHeaderProp> = ({
onCancel,
@ -118,12 +96,14 @@ const FeedPanelBody: FC<FeedPanelBodyProp> = ({
threadData,
className,
isLoading,
deletePostHandler,
}) => {
const repliesLength = threadData?.posts?.length ?? 0;
const mainThread = {
message: threadData.message,
from: threadData.createdBy,
postTs: threadData.threadTs,
id: threadData.id,
};
return (
@ -151,8 +131,10 @@ const FeedPanelBody: FC<FeedPanelBodyProp> = ({
<ActivityFeedCard
isEntityFeed
className="tw-mb-3"
deletePostHandler={deletePostHandler}
feed={reply}
key={key}
threadId={threadData.id}
/>
))}
</Fragment>
@ -169,6 +151,7 @@ const ActivityFeedPanel: FC<ActivityFeedPanelProp> = ({
onCancel,
className,
postFeed,
deletePostHandler,
}) => {
const [threadData, setThreadData] = useState<EntityThread>(selectedThread);
const [isLoading, setIsLoading] = useState<boolean>(false);
@ -204,6 +187,7 @@ const ActivityFeedPanel: FC<ActivityFeedPanelProp> = ({
<FeedPanelBody
className="tw-p-4 tw-pl-8 tw-mb-3"
deletePostHandler={deletePostHandler}
isLoading={isLoading}
threadData={threadData as EntityThread}
/>

View File

@ -0,0 +1,42 @@
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EntityThread } from 'Models';
import { HTMLAttributes } from 'react';
import { CreateThread } from '../../../generated/api/feed/createThread';
export interface ActivityThreadPanelProp
extends HTMLAttributes<HTMLDivElement> {
threadLink: string;
open?: boolean;
postFeedHandler: (value: string, id: string) => void;
onCancel: () => void;
createThread: (data: CreateThread) => void;
deletePostHandler?: (threadId: string, postId: string) => void;
}
export interface ActivityThreadListProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityThreadPanelProp, 'deletePostHandler'> {
threads: EntityThread[];
selectedThreadId: string;
postFeed: (value: string) => void;
onThreadIdSelect: (value: string) => void;
onThreadSelect: (value: string) => void;
}
export interface ActivityThreadProp
extends HTMLAttributes<HTMLDivElement>,
Pick<ActivityThreadPanelProp, 'deletePostHandler'> {
selectedThread: EntityThread;
postFeed: (value: string) => void;
}

View File

@ -15,16 +15,9 @@ import { AxiosResponse } from 'axios';
import classNames from 'classnames';
import { isUndefined } from 'lodash';
import { EntityThread, Post } from 'Models';
import React, {
FC,
Fragment,
HTMLAttributes,
useEffect,
useState,
} from 'react';
import React, { FC, Fragment, useEffect, useState } from 'react';
import AppState from '../../../AppState';
import { getAllFeeds, getFeedById } from '../../../axiosAPIs/feedsAPI';
import { CreateThread } from '../../../generated/api/feed/createThread';
import {
getEntityField,
getFeedListWithRelativeDays,
@ -39,26 +32,11 @@ import {
FeedPanelHeader,
FeedPanelOverlay,
} from '../ActivityFeedPanel/ActivityFeedPanel';
interface ActivityThreadPanelProp extends HTMLAttributes<HTMLDivElement> {
threadLink: string;
open?: boolean;
postFeedHandler: (value: string, id: string) => void;
onCancel: () => void;
createThread: (data: CreateThread) => void;
}
interface ActivityThreadListProp extends HTMLAttributes<HTMLDivElement> {
threads: EntityThread[];
selectedThreadId: string;
postFeed: (value: string) => void;
onThreadIdSelect: (value: string) => void;
onThreadSelect: (value: string) => void;
}
interface ActivityThreadProp extends HTMLAttributes<HTMLDivElement> {
selectedThread: EntityThread;
postFeed: (value: string) => void;
}
import {
ActivityThreadListProp,
ActivityThreadPanelProp,
ActivityThreadProp,
} from './ActivityThreadPanel.interface';
const ActivityThreadList: FC<ActivityThreadListProp> = ({
className,
@ -67,6 +45,7 @@ const ActivityThreadList: FC<ActivityThreadListProp> = ({
postFeed,
onThreadIdSelect,
onThreadSelect,
deletePostHandler,
}) => {
const { updatedFeedList: updatedThreads, relativeDays } =
getFeedListWithRelativeDays(threads);
@ -87,6 +66,7 @@ const ActivityThreadList: FC<ActivityThreadListProp> = ({
message: thread.message,
postTs: thread.threadTs,
from: thread.createdBy,
id: thread.id,
};
const postLength = thread.posts.length;
const replies = thread.postsCount - 1;
@ -123,7 +103,9 @@ const ActivityThreadList: FC<ActivityThreadListProp> = ({
<ActivityFeedCard
isEntityFeed
className="tw-mb-6 tw-ml-9"
deletePostHandler={deletePostHandler}
feed={lastPost}
threadId={thread.id}
/>
<p
className="link-text tw-text-xs tw-underline tw-ml-9 tw-pl-9 tw--mt-4 tw-mb-6"
@ -161,6 +143,7 @@ const ActivityThread: FC<ActivityThreadProp> = ({
className,
selectedThread,
postFeed,
deletePostHandler,
}) => {
const [threadData, setThreadData] = useState<EntityThread>(selectedThread);
const repliesLength = threadData?.posts?.length ?? 0;
@ -168,6 +151,7 @@ const ActivityThread: FC<ActivityThreadProp> = ({
message: threadData.message,
from: threadData.createdBy,
postTs: threadData.threadTs,
id: threadData.id,
};
useEffect(() => {
@ -198,8 +182,10 @@ const ActivityThread: FC<ActivityThreadProp> = ({
<ActivityFeedCard
isEntityFeed
className="tw-mb-3"
deletePostHandler={deletePostHandler}
feed={reply}
key={key}
threadId={threadData.id}
/>
))}
</Fragment>
@ -221,6 +207,7 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
open,
postFeedHandler,
createThread,
deletePostHandler,
}) => {
const [threads, setThreads] = useState<EntityThread[]>([]);
const [selectedThread, setSelectedThread] = useState<EntityThread>();
@ -276,6 +263,13 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
}, 500);
};
const onPostDelete = (threadId: string, postId: string) => {
deletePostHandler?.(threadId, postId);
setTimeout(() => {
getThreads();
}, 500);
};
useEffect(() => {
const escapeKeyHandler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
@ -332,6 +326,7 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
</p>
<ActivityThread
className="tw-pb-6 tw-pl-5"
deletePostHandler={onPostDelete}
postFeed={postFeed}
selectedThread={selectedThread}
/>
@ -353,6 +348,7 @@ const ActivityThreadPanel: FC<ActivityThreadPanelProp> = ({
) : null}
<ActivityThreadList
className="tw-py-6 tw-pl-5"
deletePostHandler={onPostDelete}
postFeed={postFeed}
selectedThreadId={selectedThreadId}
threads={threads}

View File

@ -118,6 +118,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
qualityTestFormHandler,
handleSelectedColumn,
selectedColumn,
deletePostHandler,
}: DatasetDetailsProps) => {
const { isAuthDisabled } = useAuthContext();
const [isEdit, setIsEdit] = useState(false);
@ -565,6 +566,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
{threadLink ? (
<ActivityThreadPanel
createThread={createThread}
deletePostHandler={deletePostHandler}
open={Boolean(threadLink)}
postFeedHandler={postFeedHandler}
threadLink={threadLink}
@ -595,6 +597,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
isEntityFeed
withSidePanel
className=""
deletePostHandler={deletePostHandler}
entityName={entityName}
feedList={entityThread}
isLoading={isentityThreadLoading}

View File

@ -108,4 +108,5 @@ export interface DatasetDetailsProps {
columnName: string,
testType: ColumnTestType
) => void;
deletePostHandler: (threadId: string, postId: string) => void;
}

View File

@ -109,6 +109,7 @@ const DatasetDetailsProps = {
handleRemoveColumnTest: jest.fn(),
handleTestModeChange: jest.fn(),
qualityTestFormHandler: jest.fn(),
deletePostHandler: jest.fn(),
};
jest.mock('../ManageTab/ManageTab.component', () => {
return jest.fn().mockReturnValue(<p>ManageTab</p>);

View File

@ -17,6 +17,7 @@ import React, { ReactNode } from 'react';
import { Button } from '../../buttons/Button/Button';
import Loader from '../../Loader/Loader';
type Props = {
className?: string;
loadingState?: LoadingState;
cancelText: string | ReactNode;
confirmText: string | ReactNode;
@ -43,9 +44,12 @@ const ConfirmationModal = ({
onConfirm,
onCancel,
bodyText,
className,
}: Props) => {
return (
<dialog className="tw-modal" data-testid="confirmation-modal">
<dialog
className={classNames('tw-modal', className)}
data-testid="confirmation-modal">
<div className="tw-modal-backdrop" />
<div className="tw-modal-container tw-w-120">
<div className={classNames('tw-modal-header', headerClassName)}>

View File

@ -568,6 +568,7 @@ declare module 'Models' {
message: string;
postTs: number;
from: string;
id: string;
}
export interface EntityFieldThreadCount {

View File

@ -27,6 +27,7 @@ import React, { FunctionComponent, useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import AppState from '../../AppState';
import {
deletePostById,
getAllFeeds,
getFeedCount,
postFeedById,
@ -753,6 +754,30 @@ const DatasetDetailsPage: FunctionComponent = () => {
});
};
const deletePostHandler = (threadId: string, postId: string) => {
deletePostById(threadId, postId)
.then((res: AxiosResponse) => {
if (res.data) {
const { id } = res.data;
setEntityThread((pre) => {
return pre.map((thread) => {
const posts = thread.posts.filter((post) => post.id !== id);
return { ...thread, posts: posts };
});
});
getEntityFeedCount();
showToast({
variant: 'success',
body: 'Post got deleted successfully',
});
}
})
.catch(() => {
showToast({ variant: 'error', body: 'Error while deleting post' });
});
};
useEffect(() => {
fetchTableDetail();
setActiveTab(getCurrentDatasetTab(tab));
@ -786,6 +811,7 @@ const DatasetDetailsPage: FunctionComponent = () => {
createThread={createThread}
dataModel={tableDetails.dataModel}
datasetFQN={tableFQN}
deletePostHandler={deletePostHandler}
deleted={deleted}
description={description}
descriptionUpdateHandler={descriptionUpdateHandler}

View File

@ -179,6 +179,7 @@ const TourPage = () => {
columnsUpdateHandler={handleCountChange}
createThread={handleCountChange}
datasetFQN={mockDatasetData.datasetFQN}
deletePostHandler={handleCountChange}
description={mockDatasetData.description}
descriptionUpdateHandler={handleCountChange}
entityFieldThreadCount={[]}