fix: store user details in localstorage for welcome screen (#11259)

* Change the description of Welcome screen

* localization key change

* feat: store username in cookie for welcome screen

* fix: use username instead of email

* fix: show welcome screen on initial load

* changes placeholder for entity table tags search

* fix: use localstorage instead of cookie

* fix unit test

* change global search placeholder

* fix: placeholder label of glossary terms

---------

Co-authored-by: Ashish Gupta <ashish@getcollate.io>
This commit is contained in:
karanh37 2023-04-25 21:20:57 +05:30 committed by GitHub
parent e2eaddf1bb
commit 2344ab016b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 62 additions and 25 deletions

View File

@ -543,6 +543,9 @@ const EntityTable = ({
index={index} index={index}
isReadOnly={isReadOnly} isReadOnly={isReadOnly}
isTagLoading={isTagLoading} isTagLoading={isTagLoading}
placeholder={t('label.search-entity', {
entity: t('label.tag-plural'),
})}
record={record} record={record}
tagFetchFailed={tagFetchFailed} tagFetchFailed={tagFetchFailed}
tagList={classificationTags} tagList={classificationTags}
@ -574,6 +577,9 @@ const EntityTable = ({
index={index} index={index}
isReadOnly={isReadOnly} isReadOnly={isReadOnly}
isTagLoading={isTagLoading} isTagLoading={isTagLoading}
placeholder={t('label.search-entity', {
entity: t('label.glossary-term-plural'),
})}
record={record} record={record}
tagFetchFailed={tagFetchFailed} tagFetchFailed={tagFetchFailed}
tagList={glossaryTags} tagList={glossaryTags}

View File

@ -15,13 +15,13 @@ import {
SortAscendingOutlined, SortAscendingOutlined,
SortDescendingOutlined, SortDescendingOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Button, Card, Col, Row, Space, Tabs, Typography } from 'antd'; import { Button, Card, Col, Row, Space, Tabs } from 'antd';
import { ReactComponent as SearchNotFound } from 'assets/svg/nothing_here.svg'; import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
import FacetFilter from 'components/common/facetfilter/FacetFilter'; import FacetFilter from 'components/common/facetfilter/FacetFilter';
import { useGlobalSearchProvider } from 'components/GlobalSearchProvider/GlobalSearchProvider'; import { useGlobalSearchProvider } from 'components/GlobalSearchProvider/GlobalSearchProvider';
import SearchedData from 'components/searched-data/SearchedData'; import SearchedData from 'components/searched-data/SearchedData';
import { SearchedDataProps } from 'components/searched-data/SearchedData.interface'; import { SearchedDataProps } from 'components/searched-data/SearchedData.interface';
import { SORT_ORDER } from 'enums/common.enum'; import { ERROR_PLACEHOLDER_TYPE, SORT_ORDER } from 'enums/common.enum';
import { EntityType } from 'enums/entity.enum'; import { EntityType } from 'enums/entity.enum';
import unique from 'fork-ts-checker-webpack-plugin/lib/utils/array/unique'; import unique from 'fork-ts-checker-webpack-plugin/lib/utils/array/unique';
import { import {
@ -427,15 +427,13 @@ const Explore: React.FC<ExploreProps> = ({
<Space <Space
align="center" align="center"
className="w-full h-full flex-center" className="w-full h-full flex-center"
data-testid="no-search-results"
direction="vertical" direction="vertical"
size={48}> size={48}>
<SearchNotFound height={180} /> <ErrorPlaceHolder
<div className="tw-text-center" data-testid="no-search-results"> className="mt-0-important"
<Typography.Text className="error-placeholder-text"> type={ERROR_PLACEHOLDER_TYPE.FILTER}
{`${t('label.no-data-asset-found-for')} `} />
<span className="text-primary"> {searchQueryParam}</span>
</Typography.Text>
</div>
</Space> </Space>
)} )}
</PageLayoutV1> </PageLayoutV1>

View File

@ -26,7 +26,10 @@ import React, {
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import AppState from '../../AppState'; import AppState from '../../AppState';
import { getUserPath } from '../../constants/constants'; import {
getUserPath,
LOGGED_IN_USER_STORAGE_KEY,
} from '../../constants/constants';
import { observerOptions } from '../../constants/Mydata.constants'; import { observerOptions } from '../../constants/Mydata.constants';
import { FeedFilter } from '../../enums/mydata.enum'; import { FeedFilter } from '../../enums/mydata.enum';
import { ThreadType } from '../../generated/entity/feed/thread'; import { ThreadType } from '../../generated/entity/feed/thread';
@ -67,7 +70,29 @@ const MyData: React.FC<MyDataProps> = ({
const [elementRef, isInView] = useInfiniteScroll(observerOptions); const [elementRef, isInView] = useInfiniteScroll(observerOptions);
const [feedFilter, setFeedFilter] = useState(FeedFilter.OWNER); const [feedFilter, setFeedFilter] = useState(FeedFilter.OWNER);
const [threadType, setThreadType] = useState<ThreadType>(); const [threadType, setThreadType] = useState<ThreadType>();
const [showWelcomeScreen, setShowWelcomeScreen] = useState(true); const [showWelcomeScreen, setShowWelcomeScreen] = useState(false);
const storageData = localStorage.getItem(LOGGED_IN_USER_STORAGE_KEY);
const loggedInUserName = useMemo(() => {
return AppState.getCurrentUserDetails()?.name || '';
}, [AppState]);
const usernameExistsInCookie = useMemo(() => {
return storageData
? storageData.split(',').includes(loggedInUserName)
: false;
}, [storageData, loggedInUserName]);
const updateWelcomeScreen = (show: boolean) => {
if (loggedInUserName) {
const arr = storageData ? storageData.split(',') : [];
if (!arr.includes(loggedInUserName)) {
arr.push(loggedInUserName);
localStorage.setItem(LOGGED_IN_USER_STORAGE_KEY, arr.join(','));
}
}
setShowWelcomeScreen(show);
};
const getLeftPanel = () => { const getLeftPanel = () => {
return ( return (
@ -215,6 +240,9 @@ const MyData: React.FC<MyDataProps> = ({
useEffect(() => { useEffect(() => {
isMounted.current = true; isMounted.current = true;
updateWelcomeScreen(!usernameExistsInCookie);
return () => updateWelcomeScreen(false);
}, []); }, []);
const handleFeedFilterChange = useCallback( const handleFeedFilterChange = useCallback(
@ -229,14 +257,8 @@ const MyData: React.FC<MyDataProps> = ({
const newFeedsLength = activityFeeds && activityFeeds.length; const newFeedsLength = activityFeeds && activityFeeds.length;
const showActivityFeedList = useMemo( const showActivityFeedList = useMemo(
() => () => !(!isFeedLoading && showWelcomeScreen),
!( [isFeedLoading, showWelcomeScreen]
feedFilter === FeedFilter.OWNER &&
feedData.length === 0 &&
!isFeedLoading &&
showWelcomeScreen
),
[feedFilter, feedData, isFeedLoading, showWelcomeScreen]
); );
return ( return (
@ -267,7 +289,7 @@ const MyData: React.FC<MyDataProps> = ({
/> />
) : ( ) : (
!isFeedLoading && ( !isFeedLoading && (
<WelcomeScreen onClose={() => setShowWelcomeScreen(false)} /> <WelcomeScreen onClose={() => updateWelcomeScreen(false)} />
) )
)} )}
{isFeedLoading ? <Loader /> : null} {isFeedLoading ? <Loader /> : null}

View File

@ -50,6 +50,7 @@ const TableTags = ({
fetchTags, fetchTags,
tagFetchFailed, tagFetchFailed,
dataTestId, dataTestId,
placeholder,
}: TableTagsComponentProps) => { }: TableTagsComponentProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [editColumnTag, setEditColumnTag] = useState<{ const [editColumnTag, setEditColumnTag] = useState<{
@ -135,6 +136,7 @@ const TableTags = ({
className="w-min-13 w-max-13" className="w-min-13 w-max-13"
editable={editColumnTag?.index === index} editable={editColumnTag?.index === index}
isLoading={isTagLoading && editColumnTag?.index === index} isLoading={isTagLoading && editColumnTag?.index === index}
placeholder={placeholder}
selectedTags={tags[type] || []} selectedTags={tags[type] || []}
showAddTagButton={hasTagEditAccess && isEmpty(tags[type])} showAddTagButton={hasTagEditAccess && isEmpty(tags[type])}
size="small" size="small"

View File

@ -43,6 +43,7 @@ export interface TableTagsComponentProps {
type: TagSource; type: TagSource;
fetchTags: () => void; fetchTags: () => void;
dataTestId: string; dataTestId: string;
placeholder: string;
} }
export interface TagsCollection { export interface TagsCollection {

View File

@ -61,6 +61,7 @@ const classificationTags = [
]; ];
const mockProp = { const mockProp = {
placeholder: 'Search Tags',
dataTestId: 'tag-container', dataTestId: 'tag-container',
tags: { tags: {
Classification: [], Classification: [],

View File

@ -31,4 +31,5 @@ export type TagsContainerProps = {
onSelectionChange?: (selectedTags: Array<EntityTags>) => void; onSelectionChange?: (selectedTags: Array<EntityTags>) => void;
onCancel?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void; onCancel?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
onAddButtonClick?: () => void; onAddButtonClick?: () => void;
placeholder?: string;
}; };

View File

@ -47,6 +47,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
showTags = true, showTags = true,
showAddTagButton = false, showAddTagButton = false,
showEditTagButton = false, showEditTagButton = false,
placeholder,
showNoTagPlaceholder = true, showNoTagPlaceholder = true,
}: TagsContainerProps) => { }: TagsContainerProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -227,9 +228,13 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
defaultValue={selectedTagsInternal} defaultValue={selectedTagsInternal}
mode="multiple" mode="multiple"
optionLabelProp="label" optionLabelProp="label"
placeholder={t('label.select-field', { placeholder={
field: t('label.tag-plural'), placeholder
})} ? placeholder
: t('label.select-field', {
field: t('label.tag-plural'),
})
}
removeIcon={ removeIcon={
<CloseOutlined data-testid="remove-tags" height={8} width={8} /> <CloseOutlined data-testid="remove-tags" height={8} width={8} />
} }

View File

@ -223,7 +223,7 @@ export const SERVICE_CATEGORY_TYPE = {
pipelineServices: 'pipelines', pipelineServices: 'pipelines',
mlmodelServices: 'mlModels', mlmodelServices: 'mlModels',
metadataServices: 'metadata', metadataServices: 'metadata',
storageServices: 'storage', storageServices: 'storages',
}; };
export const servicesDisplayName: { [key: string]: string } = { export const servicesDisplayName: { [key: string]: string } = {

View File

@ -39,6 +39,7 @@ export const DEFAULT_CHART_OPACITY = 1;
export const HOVER_CHART_OPACITY = 0.3; export const HOVER_CHART_OPACITY = 0.3;
export const SUPPORTED_FIELD_TYPES = ['string', 'markdown', 'integer']; export const SUPPORTED_FIELD_TYPES = ['string', 'markdown', 'integer'];
export const LOGGED_IN_USER_STORAGE_KEY = 'loggedInUsers';
export const TAG_VIEW_CAP = 33; export const TAG_VIEW_CAP = 33;
export const FOLLOWERS_VIEW_CAP = 20; export const FOLLOWERS_VIEW_CAP = 20;