fix ui freezing due to images in feed changes (#17703)

* fix ui freezing due to images in feed changes

* minor fixes

* change the method to old as there may be case where only updatedValue will be there and we need to show in prettify way rather the showing default message

* fixes around typography styling

* reduce feed size to 25 to get better performance in case of large image feed in the first 25 feeds

(cherry picked from commit 5201a0dcaf0ff62b3f5c364d7a31fd0228800abd)
This commit is contained in:
Ashish Gupta 2024-09-05 18:16:30 +05:30
parent 892e53ade0
commit 50ebdcbf12
6 changed files with 87 additions and 57 deletions

View File

@ -12,7 +12,7 @@
*/
import { Typography } from 'antd';
import { isEmpty } from 'lodash';
import React, { ReactNode, useEffect, useState } from 'react';
import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import { ReactComponent as FeedEmptyIcon } from '../../../assets/svg/activity-feed-no-data-placeholder.svg';
import ErrorPlaceHolder from '../../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder';
import { ERROR_PLACEHOLDER_TYPE, SIZE } from '../../../enums/common.enum';
@ -68,28 +68,9 @@ const ActivityFeedListV1 = ({
}
}, [entityThread, selectedThread, onFeedClick]);
if (isLoading) {
return <Loader />;
}
return isEmpty(entityThread) ? (
<div
className="h-full p-x-md"
data-testid="no-data-placeholder-container"
id="feedData">
<ErrorPlaceHolder
icon={<FeedEmptyIcon height={SIZE.X_SMALL} width={SIZE.X_SMALL} />}
type={ERROR_PLACEHOLDER_TYPE.CUSTOM}>
<Typography.Paragraph
className="tw-max-w-md"
style={{ marginBottom: '0' }}>
{emptyPlaceholderText}
</Typography.Paragraph>
</ErrorPlaceHolder>
</div>
) : (
<div className="feed-list-container p-md" id="feedData">
{entityThread.map((feed) => (
const feeds = useMemo(
() =>
entityThread.map((feed) => (
<FeedPanelBodyV1
componentsVisibility={componentsVisibility}
feed={feed}
@ -100,7 +81,43 @@ const ActivityFeedListV1 = ({
showThread={showThread}
onFeedClick={onFeedClick}
/>
))}
)),
[
entityThread,
activeFeedId,
componentsVisibility,
hidePopover,
isForFeedTab,
showThread,
]
);
if (isLoading) {
return <Loader />;
}
if (isEmpty(entityThread)) {
return (
<div
className="h-full p-x-md"
data-testid="no-data-placeholder-container"
id="feedData">
<ErrorPlaceHolder
icon={<FeedEmptyIcon height={SIZE.X_SMALL} width={SIZE.X_SMALL} />}
type={ERROR_PLACEHOLDER_TYPE.CUSTOM}>
<Typography.Paragraph
className="tw-max-w-md"
style={{ marginBottom: '0' }}>
{emptyPlaceholderText}
</Typography.Paragraph>
</ErrorPlaceHolder>
</div>
);
}
return (
<div className="feed-list-container p-md" id="feedData">
{feeds}
</div>
);
};

View File

@ -74,6 +74,11 @@ import {
ActivityFeedTabs,
} from './ActivityFeedTab.interface';
const componentsVisibility = {
showThreadIcon: false,
showRepliesContainer: true,
};
export const ActivityFeedTab = ({
fqn,
owners = [],
@ -429,10 +434,7 @@ export const ActivityFeedTab = ({
<ActivityFeedListV1
hidePopover
activeFeedId={selectedThread?.id}
componentsVisibility={{
showThreadIcon: false,
showRepliesContainer: true,
}}
componentsVisibility={componentsVisibility}
emptyPlaceholderText={placeholderText}
feedList={entityThread}
isForFeedTab={isForFeedTab}

View File

@ -17,7 +17,7 @@ import { isUndefined } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link, useHistory } from 'react-router-dom';
import { PAGE_SIZE_LARGE, ROUTES } from '../../../../constants/constants';
import { PAGE_SIZE_MEDIUM, ROUTES } from '../../../../constants/constants';
import { FEED_COUNT_INITIAL_DATA } from '../../../../constants/entity.constants';
import { mockFeedData } from '../../../../constants/mockTourData.constants';
import { useTourProvider } from '../../../../context/TourProvider/TourProvider';
@ -70,7 +70,7 @@ const FeedsWidget = ({
undefined,
undefined,
undefined,
PAGE_SIZE_LARGE
PAGE_SIZE_MEDIUM
);
} else if (activeTab === ActivityFeedTabs.MENTIONS) {
getFeedData(FeedFilter.MENTIONS);
@ -175,6 +175,21 @@ const FeedsWidget = ({
!isUndefined(handleRemoveWidget) && handleRemoveWidget(widgetKey);
}, [widgetKey]);
const emptyPlaceholderText = useMemo(
() => (
<Transi18next
i18nKey="message.no-activity-feed"
renderElement={
<Link rel="noreferrer" to={{ pathname: ROUTES.EXPLORE }} />
}
values={{
explored: t('message.have-not-explored-yet'),
}}
/>
),
[]
);
return (
<div
className="feeds-widget-container h-full"
@ -189,20 +204,7 @@ const FeedsWidget = ({
children: (
<>
<ActivityFeedListV1
emptyPlaceholderText={
<Transi18next
i18nKey="message.no-activity-feed"
renderElement={
<Link
rel="noreferrer"
to={{ pathname: ROUTES.EXPLORE }}
/>
}
values={{
explored: t('message.have-not-explored-yet'),
}}
/>
}
emptyPlaceholderText={emptyPlaceholderText}
feedList={isTourOpen ? mockFeedData : threads}
hidePopover={isEditView}
isLoading={loading && !isTourOpen}

View File

@ -12,7 +12,7 @@
*/
import { act, fireEvent, render, screen } from '@testing-library/react';
import React from 'react';
import { PAGE_SIZE_LARGE } from '../../../../constants/constants';
import { PAGE_SIZE_MEDIUM } from '../../../../constants/constants';
import { useApplicationStore } from '../../../../hooks/useApplicationStore';
import { mockUserData } from '../../../Settings/Users/mocks/User.mocks';
import FeedsWidget from './FeedsWidget.component';
@ -134,7 +134,7 @@ describe('FeedsWidget', () => {
undefined,
undefined,
undefined,
PAGE_SIZE_LARGE
PAGE_SIZE_MEDIUM
);
});
@ -154,7 +154,7 @@ describe('FeedsWidget', () => {
undefined,
undefined,
undefined,
PAGE_SIZE_LARGE
PAGE_SIZE_MEDIUM
);
});

View File

@ -154,6 +154,9 @@ a[href].link-text-grey,
.text-underline {
text-decoration: underline;
}
.text-line-through {
text-decoration: line-through;
}
// image property

View File

@ -137,33 +137,31 @@ export const getDiffValue = (oldValue: string, newValue: string) => {
export const getAddedDiffElement = (text: string) => {
return (
<Typography.Text
underline
className="diff-added"
<span
className="diff-added text-underline"
data-testid="diff-added"
key={uniqueId()}>
{text}
</Typography.Text>
</span>
);
};
export const getRemovedDiffElement = (text: string) => {
return (
<Typography.Text
delete
className="text-grey-muted"
<span
className="text-grey-muted text-line-through"
data-testid="diff-removed"
key={uniqueId()}>
{text}
</Typography.Text>
</span>
);
};
export const getNormalDiffElement = (text: string) => {
return (
<Typography.Text data-testid="diff-normal" key={uniqueId()}>
<span data-testid="diff-normal" key={uniqueId()}>
{text}
</Typography.Text>
</span>
);
};
@ -172,10 +170,18 @@ export const getTextDiff = (
newText: string,
latestText?: string
) => {
const imagePlaceholder = 'data:image';
if (isEmpty(oldText) && isEmpty(newText)) {
return latestText ?? '';
}
if (
newText.includes(imagePlaceholder) ||
oldText.includes(imagePlaceholder)
) {
return newText;
}
const diffArr = diffWords(toString(oldText), toString(newText));
const result = diffArr.map((diff) => {