Fix: #21276 Only 3 Comments Shown by Default in Incident View (#21577)

* Fix: #21276 Only 3 Comments Shown by Default in Incident View

* fixed failing unit test

* addressing comments.
This commit is contained in:
Shailesh Parmar 2025-06-09 11:22:18 +05:30 committed by GitHub
parent 78f523fd13
commit 436df10a7f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 207 additions and 75 deletions

View File

@ -365,6 +365,52 @@ test.describe('Activity feed', () => {
await checkTaskCountInActivityFeed(page, 0, 1); await checkTaskCountInActivityFeed(page, 0, 1);
}); });
test('Replies should be visible in the task feed', async ({ page }) => {
const value: TaskDetails = {
term: entity2.entity.displayName,
assignee: user1.responseData.name,
};
await redirectToHomePage(page);
await entity2.visitEntityPage(page);
await page.getByTestId('request-description').click();
await createDescriptionTask(page, value);
// Task 1 - Update Description right panel check
const descriptionTask = await page.getByTestId('task-title').innerText();
expect(descriptionTask).toContain('Request to update description');
for (let i = 0; i < 10; i++) {
const commentInput = page.locator('[data-testid="comments-input-field"]');
commentInput.click();
await page.fill(
'[data-testid="editor-wrapper"] .ql-editor',
`Reply message ${i}`
);
const sendReply = page.waitForResponse('/api/v1/feed/*/posts');
await page.getByTestId('send-button').click({ force: true });
await sendReply;
}
await page.reload();
await page.waitForSelector('[data-testid="loader"]', {
state: 'hidden',
});
await page.waitForLoadState('networkidle');
await expect(page.getByTestId('feed-reply-card')).toHaveCount(10);
for (let i = 0; i < 10; i++) {
await expect(
page.locator('.right-container [data-testid="feed-replies"]')
).toContainText(`Reply message ${i}`);
}
});
test('Open and Closed Task Tab with approve from Task Feed Card', async ({ test('Open and Closed Task Tab with approve from Task Feed Card', async ({
page, page,
}) => { }) => {

View File

@ -10,10 +10,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Card, Col, Input, Space, Tooltip, Typography } from 'antd'; import { Card, Col, Input, Skeleton, Space, Tooltip, Typography } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { compare } from 'fast-json-patch'; import { compare } from 'fast-json-patch';
import { isUndefined } from 'lodash'; import { isUndefined, orderBy } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -75,10 +75,10 @@ const ActivityFeedCardNew = ({
}, [feed.about]); }, [feed.about]);
const { t } = useTranslation(); const { t } = useTranslation();
const { currentUser } = useApplicationStore(); const { currentUser } = useApplicationStore();
const { selectedThread, postFeed } = useActivityFeedProvider(); const { selectedThread, postFeed, updateFeed, isPostsLoading } =
useActivityFeedProvider();
const [showFeedEditor, setShowFeedEditor] = useState<boolean>(false); const [showFeedEditor, setShowFeedEditor] = useState<boolean>(false);
const [isEditPost, setIsEditPost] = useState<boolean>(false); const [isEditPost, setIsEditPost] = useState<boolean>(false);
const { updateFeed } = useActivityFeedProvider();
const [, , user] = useUserProfile({ const [, , user] = useUserProfile({
permission: true, permission: true,
name: feed.createdBy ?? '', name: feed.createdBy ?? '',
@ -183,6 +183,38 @@ const ActivityFeedCardNew = ({
setShowFeedEditor(false); setShowFeedEditor(false);
}; };
const posts = useMemo(() => {
if (!showThread) {
return null;
}
if (isPostsLoading) {
return (
<Space className="m-y-md" direction="vertical" size={16}>
<Skeleton active />
<Skeleton active />
<Skeleton active />
</Space>
);
}
const posts = orderBy(feed.posts, ['postTs'], ['desc']);
return (
<Col className="p-l-0 p-r-0" data-testid="feed-replies">
{posts.map((reply, index, arr) => (
<CommentCard
closeFeedEditor={closeFeedEditor}
feed={feed}
isLastReply={index === arr.length - 1}
key={reply.id}
post={reply}
/>
))}
</Col>
);
}, [feed, showThread, closeFeedEditor, isPostsLoading]);
return ( return (
<Card <Card
className={classNames( className={classNames(
@ -330,22 +362,7 @@ const ActivityFeedCardNew = ({
</div> </div>
)} )}
{showThread && feed?.posts && feed?.posts?.length > 0 && ( {posts}
<Col className="p-l-0 p-r-0" data-testid="feed-replies">
{feed?.posts
?.slice()
.sort((a, b) => (b.postTs as number) - (a.postTs as number))
.map((reply, index, arr) => (
<CommentCard
closeFeedEditor={closeFeedEditor}
feed={feed}
isLastReply={index === arr.length - 1}
key={reply.id}
post={reply}
/>
))}
</Col>
)}
</div> </div>
)} )}
</Card> </Card>

View File

@ -134,6 +134,7 @@ const CommentCard = ({
className={classNames('d-flex justify-start relative reply-card', { className={classNames('d-flex justify-start relative reply-card', {
'reply-card-border-bottom': !isLastReply, 'reply-card-border-bottom': !isLastReply,
})} })}
data-testid="feed-reply-card"
onMouseEnter={() => setIsHovered(true)} onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}> onMouseLeave={() => setIsHovered(false)}>
<div className="profile-picture m-r-xs"> <div className="profile-picture m-r-xs">

View File

@ -14,7 +14,7 @@
import { Col, Drawer, Row } from 'antd'; import { Col, Drawer, Row } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { FC } from 'react'; import React, { FC } from 'react';
import { Thread, ThreadType } from '../../../generated/entity/feed/thread'; import { ThreadType } from '../../../generated/entity/feed/thread';
import FeedPanelBodyV1 from '../ActivityFeedPanel/FeedPanelBodyV1'; import FeedPanelBodyV1 from '../ActivityFeedPanel/FeedPanelBodyV1';
import FeedPanelHeader from '../ActivityFeedPanel/FeedPanelHeader'; import FeedPanelHeader from '../ActivityFeedPanel/FeedPanelHeader';
import { useActivityFeedProvider } from '../ActivityFeedProvider/ActivityFeedProvider'; import { useActivityFeedProvider } from '../ActivityFeedProvider/ActivityFeedProvider';
@ -31,6 +31,10 @@ const ActivityFeedDrawer: FC<ActivityFeedDrawerProps> = ({
}) => { }) => {
const { hideDrawer, selectedThread } = useActivityFeedProvider(); const { hideDrawer, selectedThread } = useActivityFeedProvider();
if (!selectedThread) {
return null;
}
return ( return (
<Drawer <Drawer
className={classNames('activity-feed-drawer', className)} className={classNames('activity-feed-drawer', className)}
@ -57,7 +61,7 @@ const ActivityFeedDrawer: FC<ActivityFeedDrawerProps> = ({
showThreadIcon: false, showThreadIcon: false,
showRepliesContainer: false, showRepliesContainer: false,
}} }}
feed={selectedThread as Thread} feed={selectedThread}
hidePopover={false} hidePopover={false}
/> />
</Col> </Col>

View File

@ -12,7 +12,7 @@
*/ */
import { Typography } from 'antd'; import { Typography } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { isEmpty } from 'lodash'; import { isEmpty, isUndefined } from 'lodash';
import React, { ReactNode, useEffect, useMemo, useState } from 'react'; import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import { ReactComponent as FeedEmptyIcon } from '../../../assets/svg/ic-task-empty.svg'; import { ReactComponent as FeedEmptyIcon } from '../../../assets/svg/ic-task-empty.svg';
import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum'; import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum';
@ -69,11 +69,10 @@ const ActivityFeedListV1New = ({
}, [feedList]); }, [feedList]);
useEffect(() => { useEffect(() => {
if (onFeedClick) { const thread = entityThread.find((feed) => feed.id === selectedThread?.id);
onFeedClick(
entityThread.find((feed) => feed.id === selectedThread?.id) ?? if (onFeedClick && (isUndefined(selectedThread) || isUndefined(thread))) {
entityThread[0] onFeedClick(entityThread[0]);
);
} }
}, [entityThread, selectedThread, onFeedClick]); }, [entityThread, selectedThread, onFeedClick]);

View File

@ -24,6 +24,7 @@ import React, {
} from 'react'; } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PAGE_SIZE_LARGE } from '../../../constants/constants'; import { PAGE_SIZE_LARGE } from '../../../constants/constants';
import { POST_FEED_PAGE_COUNT } from '../../../constants/Feeds.constants';
import { EntityType } from '../../../enums/entity.enum'; import { EntityType } from '../../../enums/entity.enum';
import { FeedFilter } from '../../../enums/mydata.enum'; import { FeedFilter } from '../../../enums/mydata.enum';
import { ReactionOperation } from '../../../enums/reactions.enum'; import { ReactionOperation } from '../../../enums/reactions.enum';
@ -43,6 +44,7 @@ import {
deleteThread, deleteThread,
getAllFeeds, getAllFeeds,
getFeedById, getFeedById,
getPostsFeedById,
postFeedById, postFeedById,
updatePost, updatePost,
updateThread, updateThread,
@ -71,6 +73,9 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
const [entityPaging, setEntityPaging] = useState<Paging>({} as Paging); const [entityPaging, setEntityPaging] = useState<Paging>({} as Paging);
const [focusReplyEditor, setFocusReplyEditor] = useState<boolean>(false); const [focusReplyEditor, setFocusReplyEditor] = useState<boolean>(false);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isPostsLoading, setIsPostsLoading] = useState(false);
const [isTestCaseResolutionLoading, setIsTestCaseResolutionLoading] =
useState(false);
const [isDrawerOpen, setIsDrawerOpen] = useState(false); const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const [selectedThread, setSelectedThread] = useState<Thread>(); const [selectedThread, setSelectedThread] = useState<Thread>();
const [testCaseResolutionStatus, setTestCaseResolutionStatus] = useState< const [testCaseResolutionStatus, setTestCaseResolutionStatus] = useState<
@ -80,6 +85,7 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
const { currentUser } = useApplicationStore(); const { currentUser } = useApplicationStore();
const fetchTestCaseResolution = useCallback(async (id: string) => { const fetchTestCaseResolution = useCallback(async (id: string) => {
setIsTestCaseResolutionLoading(true);
try { try {
const { data } = await getListTestCaseIncidentByStateId(id, { const { data } = await getListTestCaseIncidentByStateId(id, {
limit: PAGE_SIZE_LARGE, limit: PAGE_SIZE_LARGE,
@ -90,22 +96,40 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
); );
} catch (error) { } catch (error) {
setTestCaseResolutionStatus([]); setTestCaseResolutionStatus([]);
} finally {
setIsTestCaseResolutionLoading(false);
}
}, []);
const fetchPostsFeed = useCallback(async (active: Thread) => {
// If the posts count is greater than the page count, fetch the posts
if (
active?.postsCount &&
active?.postsCount > POST_FEED_PAGE_COUNT &&
active?.posts?.length !== active?.postsCount
) {
setIsPostsLoading(true);
try {
const { data } = await getPostsFeedById(active.id);
setSelectedThread((pre) =>
pre?.id === active?.id ? { ...active, posts: data } : pre
);
} finally {
setIsPostsLoading(false);
}
} }
}, []); }, []);
const setActiveThread = useCallback((active?: Thread) => { const setActiveThread = useCallback((active?: Thread) => {
setSelectedThread(active); setSelectedThread(active);
active && fetchPostsFeed(active);
if ( if (
active && active &&
active.task?.type === TaskType.RequestTestCaseFailureResolution && active.task?.type === TaskType.RequestTestCaseFailureResolution &&
active.task?.testCaseResolutionStatusId active.task?.testCaseResolutionStatusId
) { ) {
setLoading(true); fetchTestCaseResolution(active.task.testCaseResolutionStatusId);
fetchTestCaseResolution(active.task.testCaseResolutionStatusId).finally(
() => {
setLoading(false);
}
);
} }
}, []); }, []);
@ -408,6 +432,8 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
selectedThread, selectedThread,
isDrawerOpen, isDrawerOpen,
loading, loading,
isPostsLoading,
isTestCaseResolutionLoading,
focusReplyEditor, focusReplyEditor,
refreshActivityFeed, refreshActivityFeed,
deleteFeed, deleteFeed,
@ -431,6 +457,8 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
selectedThread, selectedThread,
isDrawerOpen, isDrawerOpen,
loading, loading,
isPostsLoading,
isTestCaseResolutionLoading,
focusReplyEditor, focusReplyEditor,
refreshActivityFeed, refreshActivityFeed,
deleteFeed, deleteFeed,

View File

@ -26,6 +26,8 @@ import { Paging } from '../../../generated/type/paging';
export interface ActivityFeedProviderContextType { export interface ActivityFeedProviderContextType {
loading: boolean; loading: boolean;
isPostsLoading?: boolean;
isTestCaseResolutionLoading?: boolean;
entityThread: Thread[]; entityThread: Thread[];
selectedThread: Thread | undefined; selectedThread: Thread | undefined;
isDrawerOpen: boolean; isDrawerOpen: boolean;

View File

@ -294,9 +294,11 @@ export const ActivityFeedTab = ({
if (!feed && (isTaskActiveTab || isMentionTabSelected)) { if (!feed && (isTaskActiveTab || isMentionTabSelected)) {
setIsFullWidth(false); setIsFullWidth(false);
} }
setActiveThread(feed); if (selectedThread?.id !== feed?.id) {
setActiveThread(feed);
}
}, },
[setActiveThread, isTaskActiveTab, isMentionTabSelected] [setActiveThread, isTaskActiveTab, isMentionTabSelected, selectedThread]
); );
useEffect(() => { useEffect(() => {

View File

@ -336,17 +336,17 @@ const TaskFeedCard = ({
width={20} width={20}
onClick={isForFeedTab ? showReplies : undefined} onClick={isForFeedTab ? showReplies : undefined}
/> />
{feed.posts && feed.posts?.length > 0 && ( {feed?.postsCount && feed?.postsCount > 0 && (
<Button <Button
className="posts-length m-r-xss p-0 remove-button-default-styling" className="posts-length m-r-xss p-0 remove-button-default-styling"
data-testid="replies-count" data-testid="replies-count"
type="link" type="link"
onClick={isForFeedTab ? showReplies : undefined}> onClick={isForFeedTab ? showReplies : undefined}>
{t( {t(
feed.posts.length === 1 feed.postsCount === 1
? 'label.one-reply' ? 'label.one-reply'
: 'label.number-reply-plural', : 'label.number-reply-plural',
{ number: feed.posts.length } { number: feed.postsCount }
)} )}
</Button> </Button>
)} )}

View File

@ -33,11 +33,11 @@ import {
import { useElementInView } from '../../../../hooks/useElementInView'; import { useElementInView } from '../../../../hooks/useElementInView';
import { useFqn } from '../../../../hooks/useFqn'; import { useFqn } from '../../../../hooks/useFqn';
import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store'; import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store';
import ActivityFeedListV1 from '../../../ActivityFeed/ActivityFeedList/ActivityFeedListV1.component'; import ActivityFeedListV1New from '../../../ActivityFeed/ActivityFeedList/ActivityFeedListV1New.component';
import { useActivityFeedProvider } from '../../../ActivityFeed/ActivityFeedProvider/ActivityFeedProvider'; import { useActivityFeedProvider } from '../../../ActivityFeed/ActivityFeedProvider/ActivityFeedProvider';
import { TaskFilter } from '../../../ActivityFeed/ActivityFeedTab/ActivityFeedTab.interface'; import { TaskFilter } from '../../../ActivityFeed/ActivityFeedTab/ActivityFeedTab.interface';
import Loader from '../../../common/Loader/Loader'; import Loader from '../../../common/Loader/Loader';
import { TaskTab } from '../../../Entity/Task/TaskTab/TaskTab.component'; import { TaskTabNew } from '../../../Entity/Task/TaskTab/TaskTabNew.component';
import './test-case-incident-tab.style.less'; import './test-case-incident-tab.style.less';
const TestCaseIncidentTab = () => { const TestCaseIncidentTab = () => {
@ -83,9 +83,11 @@ const TestCaseIncidentTab = () => {
const handleFeedClick = useCallback( const handleFeedClick = useCallback(
(feed: Thread) => { (feed: Thread) => {
setActiveThread(feed); if (selectedThread?.id !== feed?.id) {
setActiveThread(feed);
}
}, },
[setActiveThread] [setActiveThread, selectedThread]
); );
const loader = useMemo(() => (loading ? <Loader /> : null), [loading]); const loader = useMemo(() => (loading ? <Loader /> : null), [loading]);
@ -140,7 +142,7 @@ const TestCaseIncidentTab = () => {
className="left-container" className="left-container"
data-testid="left-container" data-testid="left-container"
id="left-container"> id="left-container">
<div className="d-flex gap-4 p-sm p-x-lg activity-feed-task"> <div className="d-flex gap-4 p-sm p-x-lg">
<Typography.Text <Typography.Text
className={classNames( className={classNames(
'cursor-pointer p-l-xss d-flex items-center', 'cursor-pointer p-l-xss d-flex items-center',
@ -164,13 +166,14 @@ const TestCaseIncidentTab = () => {
</Typography.Text> </Typography.Text>
</div> </div>
<ActivityFeedListV1 <ActivityFeedListV1New
hidePopover hidePopover
activeFeedId={selectedThread?.id} activeFeedId={selectedThread?.id}
emptyPlaceholderText={t('message.no-tasks-assigned')} emptyPlaceholderText={t('message.no-tasks-assigned')}
feedList={threads} feedList={threads}
isForFeedTab={false} isForFeedTab={false}
isLoading={false} isLoading={false}
selectedThread={selectedThread}
showThread={false} showThread={false}
onFeedClick={handleFeedClick} onFeedClick={handleFeedClick}
/> />
@ -187,7 +190,7 @@ const TestCaseIncidentTab = () => {
{loader} {loader}
{selectedThread && !loading && ( {selectedThread && !loading && (
<div id="task-panel"> <div id="task-panel">
<TaskTab <TaskTabNew
entityType={EntityType.TEST_CASE} entityType={EntityType.TEST_CASE}
isForFeedTab={false} isForFeedTab={false}
owners={owners} owners={owners}

View File

@ -41,9 +41,9 @@ jest.mock(
}) })
); );
jest.mock('../../../Entity/Task/TaskTab/TaskTab.component', () => { jest.mock('../../../Entity/Task/TaskTab/TaskTabNew.component', () => {
return { return {
TaskTab: jest.fn().mockImplementation(({ onAfterClose }) => ( TaskTabNew: jest.fn().mockImplementation(({ onAfterClose }) => (
<div> <div>
TaskTab TaskTab
<button data-testid="close-btn" onClick={onAfterClose}> <button data-testid="close-btn" onClick={onAfterClose}>
@ -57,7 +57,7 @@ jest.mock('../../../common/Loader/Loader', () => {
return jest.fn().mockImplementation(() => <div>Loader</div>); return jest.fn().mockImplementation(() => <div>Loader</div>);
}); });
jest.mock( jest.mock(
'../../../ActivityFeed/ActivityFeedList/ActivityFeedListV1.component', '../../../ActivityFeed/ActivityFeedList/ActivityFeedListV1New.component',
() => { () => {
return jest.fn().mockImplementation(({ onFeedClick }) => ( return jest.fn().mockImplementation(({ onFeedClick }) => (
<div> <div>

View File

@ -21,6 +21,7 @@ import {
MenuProps, MenuProps,
Row, Row,
Select, Select,
Skeleton,
Space, Space,
Tooltip, Tooltip,
Typography, Typography,
@ -35,6 +36,7 @@ import {
isEqual, isEqual,
isUndefined, isUndefined,
last, last,
orderBy,
startCase, startCase,
unionBy, unionBy,
} from 'lodash'; } from 'lodash';
@ -163,6 +165,7 @@ export const TaskTabNew = ({
fetchUpdatedThread, fetchUpdatedThread,
updateTestCaseIncidentStatus, updateTestCaseIncidentStatus,
testCaseResolutionStatus, testCaseResolutionStatus,
isPostsLoading,
} = useActivityFeedProvider(); } = useActivityFeedProvider();
const isTaskDescription = isDescriptionTask(taskDetails?.type as TaskType); const isTaskDescription = isDescriptionTask(taskDetails?.type as TaskType);
@ -1047,6 +1050,34 @@ export const TaskTabNew = ({
setShowFeedEditor(false); setShowFeedEditor(false);
}; };
const posts = useMemo(() => {
if (isPostsLoading) {
return (
<Space className="m-y-md" direction="vertical" size={16}>
<Skeleton active />
<Skeleton active />
<Skeleton active />
</Space>
);
}
const posts = orderBy(taskThread.posts, ['postTs'], ['desc']);
return (
<Col className="p-l-0 p-r-0" data-testid="feed-replies">
{posts.map((reply, index, arr) => (
<CommentCard
closeFeedEditor={closeFeedEditor}
feed={taskThread}
isLastReply={index === arr.length - 1}
key={reply.id}
post={reply}
/>
))}
</Col>
);
}, [taskThread, closeFeedEditor, isPostsLoading]);
useEffect(() => { useEffect(() => {
closeFeedEditor(); closeFeedEditor();
}, [taskThread.id]); }, [taskThread.id]);
@ -1149,22 +1180,7 @@ export const TaskTabNew = ({
) )
)} )}
{taskThread?.posts && taskThread?.posts?.length > 0 && ( {posts}
<Col className="p-l-0 p-r-0" data-testid="feed-replies">
{taskThread?.posts
?.slice()
.sort((a, b) => (b.postTs as number) - (a.postTs as number))
.map((reply, index, arr) => (
<CommentCard
closeFeedEditor={closeFeedEditor}
feed={taskThread}
isLastReply={index === arr.length - 1}
key={reply.id}
post={reply}
/>
))}
</Col>
)}
</div> </div>
</Col> </Col>
</Col> </Col>

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Col, Row, Steps, Typography } from 'antd'; import { Col, Row, Skeleton, Steps, Typography } from 'antd';
import { last, toLower } from 'lodash'; import { last, toLower } from 'lodash';
import React, { ReactNode, useMemo } from 'react'; import React, { ReactNode, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -36,7 +36,8 @@ import './task-tab-incident-manager-header.style.less';
const TaskTabIncidentManagerHeaderNew = ({ thread }: { thread: Thread }) => { const TaskTabIncidentManagerHeaderNew = ({ thread }: { thread: Thread }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { testCaseResolutionStatus } = useActivityFeedProvider(); const { testCaseResolutionStatus, isTestCaseResolutionLoading } =
useActivityFeedProvider();
const testCaseResolutionStepper = useMemo(() => { const testCaseResolutionStepper = useMemo(() => {
const updatedData = [...testCaseResolutionStatus]; const updatedData = [...testCaseResolutionStatus];
const lastStatusType = last( const lastStatusType = last(
@ -215,14 +216,18 @@ const TaskTabIncidentManagerHeaderNew = ({ thread }: { thread: Thread }) => {
)} )}
<Col className="p-l-0" span={24}> <Col className="p-l-0" span={24}>
<div className="task-resolution-steps-container-new"> <div className="task-resolution-steps-container-new">
<Steps {isTestCaseResolutionLoading ? (
className="task-resolution-steps w-full" <Skeleton active />
current={testCaseResolutionStatus.length} ) : (
data-testid="task-resolution-steps" <Steps
items={testCaseResolutionStepper} className="task-resolution-steps w-full"
labelPlacement="vertical" current={testCaseResolutionStatus.length}
size="small" data-testid="task-resolution-steps"
/> items={testCaseResolutionStepper}
labelPlacement="vertical"
size="small"
/>
)}
</div> </div>
</Col> </Col>
</Row> </Row>

View File

@ -24,6 +24,9 @@ export const teamsLinkRegEx = /\((.+?\/\/.+?)\/(.+?\/.+?\/.+?)\/(.+?)\)/;
export const entityLinkRegEx = /<#E::([^<>]+?)::([^<>]+?)>/g; export const entityLinkRegEx = /<#E::([^<>]+?)::([^<>]+?)>/g;
export const entityRegex = /<#E::([^<>]+?)::([^<>]+?)\|(\[(.+?)?\]\((.+?)?\))>/; export const entityRegex = /<#E::([^<>]+?)::([^<>]+?)\|(\[(.+?)?\]\((.+?)?\))>/;
// 3 is the default page count for the post feed in list API
export const POST_FEED_PAGE_COUNT = 3;
export const ENTITY_URL_MAP = { export const ENTITY_URL_MAP = {
team: 'settings/members/teams', team: 'settings/members/teams',
user: 'users', user: 'users',

View File

@ -126,6 +126,12 @@ export const postFeedById = async (id: string, data: Post) => {
return response.data; return response.data;
}; };
export const getPostsFeedById = async (id: string) => {
const response = await APIClient.get<{ data: Post[] }>(`/feed/${id}/posts`);
return response.data;
};
export const deletePostById = (threadId: string, postId: string) => { export const deletePostById = (threadId: string, postId: string) => {
return APIClient.delete<Post>(`/feed/${threadId}/posts/${postId}`); return APIClient.delete<Post>(`/feed/${threadId}/posts/${postId}`);
}; };