mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 08:50:18 +00:00
fix(ui): tour page (#12122)
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
9c2d21d496
commit
9f148031f5
@ -18,6 +18,7 @@ import ErrorBoundary from 'components/ErrorBoundary/ErrorBoundary';
|
||||
import GlobalSearchProvider from 'components/GlobalSearchProvider/GlobalSearchProvider';
|
||||
import PermissionProvider from 'components/PermissionProvider/PermissionProvider';
|
||||
import AppRouter from 'components/router/AppRouter';
|
||||
import TourProvider from 'components/TourProvider/TourProvider';
|
||||
import WebSocketProvider from 'components/web-scoket/web-scoket.provider';
|
||||
import WebAnalyticsProvider from 'components/WebAnalytics/WebAnalyticsProvider';
|
||||
import { TOAST_OPTIONS } from 'constants/Toasts.constants';
|
||||
@ -38,19 +39,21 @@ const App: FunctionComponent = () => {
|
||||
<ErrorBoundary>
|
||||
<ApplicationConfigProvider>
|
||||
<AuthProvider childComponentType={AppRouter}>
|
||||
<HelmetProvider>
|
||||
<WebAnalyticsProvider>
|
||||
<PermissionProvider>
|
||||
<WebSocketProvider>
|
||||
<GlobalSearchProvider>
|
||||
<EntityExportModalProvider>
|
||||
<AppRouter />
|
||||
</EntityExportModalProvider>
|
||||
</GlobalSearchProvider>
|
||||
</WebSocketProvider>
|
||||
</PermissionProvider>
|
||||
</WebAnalyticsProvider>
|
||||
</HelmetProvider>
|
||||
<TourProvider>
|
||||
<HelmetProvider>
|
||||
<WebAnalyticsProvider>
|
||||
<PermissionProvider>
|
||||
<WebSocketProvider>
|
||||
<GlobalSearchProvider>
|
||||
<EntityExportModalProvider>
|
||||
<AppRouter />
|
||||
</EntityExportModalProvider>
|
||||
</GlobalSearchProvider>
|
||||
</WebSocketProvider>
|
||||
</PermissionProvider>
|
||||
</WebAnalyticsProvider>
|
||||
</HelmetProvider>
|
||||
</TourProvider>
|
||||
</AuthProvider>
|
||||
</ApplicationConfigProvider>
|
||||
</ErrorBoundary>
|
||||
|
@ -12,13 +12,11 @@
|
||||
*/
|
||||
|
||||
import { EntityUnion } from 'components/Explore/explore.interface';
|
||||
import { EntityTabs } from 'enums/entity.enum';
|
||||
import { isEmpty, isNil, isUndefined } from 'lodash';
|
||||
import { action, makeAutoObservable } from 'mobx';
|
||||
import { ClientAuth, NewUser } from 'Models';
|
||||
import { reactLocalStorage } from 'reactjs-localstorage';
|
||||
import { LOCALSTORAGE_USER_PROFILES } from './constants/constants';
|
||||
import { CurrentTourPageType } from './enums/tour.enum';
|
||||
import { ResourcePermission } from './generated/entity/policies/accessControl/resourcePermission';
|
||||
import {
|
||||
EntityReference as UserTeams,
|
||||
@ -55,10 +53,6 @@ class AppState {
|
||||
inPageSearchText = '';
|
||||
explorePageTab = 'tables';
|
||||
|
||||
isTourOpen = false;
|
||||
currentTourPage: CurrentTourPageType = CurrentTourPageType.MY_DATA_PAGE;
|
||||
activeTabforTourDatasetPage = EntityTabs.SCHEMA;
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this, {
|
||||
updateUserDetails: action,
|
||||
@ -100,12 +94,6 @@ class AppState {
|
||||
this.users = data;
|
||||
this.nonSecureUserDetails = data[0];
|
||||
}
|
||||
updateActiveTabForTourDatasetPage(data: EntityTabs) {
|
||||
this.activeTabforTourDatasetPage = data;
|
||||
}
|
||||
updateCurrentTourPage(data: CurrentTourPageType) {
|
||||
this.currentTourPage = data;
|
||||
}
|
||||
updateUserTeam(data: Array<UserTeams>) {
|
||||
this.userTeams = data;
|
||||
}
|
||||
|
@ -14,12 +14,14 @@
|
||||
import { Space, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { useGlobalSearchProvider } from 'components/GlobalSearchProvider/GlobalSearchProvider';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { tabsInfo } from 'constants/explore.constants';
|
||||
import {
|
||||
urlGitbookDocs,
|
||||
urlGithubRepo,
|
||||
urlJoinSlack,
|
||||
} from 'constants/URL.constants';
|
||||
import { CurrentTourPageType } from 'enums/tour.enum';
|
||||
import { isEmpty, isString, max } from 'lodash';
|
||||
import { observer } from 'mobx-react';
|
||||
import Qs from 'qs';
|
||||
@ -43,6 +45,7 @@ import {
|
||||
ROUTES,
|
||||
TERM_ADMIN,
|
||||
TERM_USER,
|
||||
TOUR_SEARCH_TERM,
|
||||
} from '../../constants/constants';
|
||||
import {
|
||||
addToRecentSearched,
|
||||
@ -58,6 +61,8 @@ const Appbar: React.FC = (): JSX.Element => {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const { t } = useTranslation();
|
||||
const { isTourOpen, updateTourPage, updateTourSearch, tourSearchValue } =
|
||||
useTourProvider();
|
||||
|
||||
const {
|
||||
isAuthDisabled,
|
||||
@ -91,7 +96,11 @@ const Appbar: React.FC = (): JSX.Element => {
|
||||
|
||||
const handleSearchChange = (value: string) => {
|
||||
setSearchValue(value);
|
||||
value ? setIsOpen(true) : setIsOpen(false);
|
||||
if (isTourOpen) {
|
||||
updateTourSearch(value);
|
||||
} else {
|
||||
value ? setIsOpen(true) : setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const supportLink = [
|
||||
@ -327,24 +336,31 @@ const Appbar: React.FC = (): JSX.Element => {
|
||||
];
|
||||
|
||||
const searchHandler = (value: string) => {
|
||||
setIsOpen(false);
|
||||
addToRecentSearched(value);
|
||||
if (!isTourOpen) {
|
||||
setIsOpen(false);
|
||||
addToRecentSearched(value);
|
||||
|
||||
const defaultTab: string =
|
||||
searchCriteria !== '' ? tabsInfo[searchCriteria].path : '';
|
||||
const defaultTab: string =
|
||||
searchCriteria !== '' ? tabsInfo[searchCriteria].path : '';
|
||||
|
||||
history.push(
|
||||
getExplorePath({
|
||||
tab: defaultTab,
|
||||
search: value,
|
||||
isPersistFilters: false,
|
||||
})
|
||||
);
|
||||
history.push(
|
||||
getExplorePath({
|
||||
tab: defaultTab,
|
||||
search: value,
|
||||
isPersistFilters: false,
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
const target = e.target as HTMLInputElement;
|
||||
if (e.key === 'Enter') {
|
||||
if (isTourOpen && searchValue === TOUR_SEARCH_TERM) {
|
||||
updateTourPage(CurrentTourPageType.EXPLORE_PAGE);
|
||||
updateTourSearch('');
|
||||
}
|
||||
|
||||
searchHandler(target.value);
|
||||
}
|
||||
};
|
||||
@ -376,6 +392,11 @@ const Appbar: React.FC = (): JSX.Element => {
|
||||
useEffect(() => {
|
||||
setSearchValue(searchQuery);
|
||||
}, [searchQuery]);
|
||||
useEffect(() => {
|
||||
if (isTourOpen) {
|
||||
setSearchValue(tourSearchValue);
|
||||
}
|
||||
}, [tourSearchValue, isTourOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthDisabled) {
|
||||
|
@ -505,6 +505,7 @@ export const DataAssetsHeader = ({
|
||||
</Button>
|
||||
<Button
|
||||
className="w-16 p-0"
|
||||
data-testid="entity-follow-button"
|
||||
icon={
|
||||
<Icon component={isFollowing ? StarFilledIcon : StarIcon} />
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
*/
|
||||
|
||||
import { Modal, Space } from 'antd';
|
||||
import AppState from 'AppState';
|
||||
import { AxiosError } from 'axios';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { mockDatasetData } from 'constants/mockTourData.constants';
|
||||
import {
|
||||
debounce,
|
||||
@ -153,6 +153,7 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
isFullScreen = false,
|
||||
}: EntityLineageProp) => {
|
||||
const { t } = useTranslation();
|
||||
const { isTourOpen } = useTourProvider();
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
const [reactFlowInstance, setReactFlowInstance] =
|
||||
useState<ReactFlowInstance>();
|
||||
@ -222,7 +223,7 @@ const EntityLineageComponent: FunctionComponent<EntityLineageProp> = ({
|
||||
|
||||
const fetchLineageData = useCallback(
|
||||
async (config: LineageConfig) => {
|
||||
if (AppState.isTourOpen) {
|
||||
if (isTourOpen) {
|
||||
setPaginationData({});
|
||||
setEntityLineage(mockDatasetData.entityLineage);
|
||||
setUpdatedLineageData(mockDatasetData.entityLineage);
|
||||
|
@ -10,11 +10,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Checkbox, Col, Row, Typography } from 'antd';
|
||||
import { Button, Checkbox, Col, Row, Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import TitleBreadcrumb from 'components/common/title-breadcrumb/title-breadcrumb.component';
|
||||
import { EntityHeader } from 'components/Entity/EntityHeader/EntityHeader.component';
|
||||
import TableDataCardBody from 'components/TableDataCardBody/TableDataCardBody';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { FQN_SEPARATOR_CHAR } from 'constants/char.constants';
|
||||
import { EntityType } from 'enums/entity.enum';
|
||||
import { OwnerType } from 'enums/user.enum';
|
||||
@ -57,7 +58,7 @@ const ExploreSearchCard: React.FC<ExploreSearchCardProps> = forwardRef<
|
||||
) => {
|
||||
const { t } = useTranslation();
|
||||
const { tab } = useParams<{ tab: string }>();
|
||||
|
||||
const { isTourOpen } = useTourProvider();
|
||||
const otherDetails = useMemo(() => {
|
||||
const tierValue = isString(source.tier)
|
||||
? source.tier
|
||||
@ -148,24 +149,34 @@ const ExploreSearchCard: React.FC<ExploreSearchCardProps> = forwardRef<
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Link
|
||||
className="no-underline"
|
||||
data-testid="entity-link"
|
||||
target={openEntityInNewPage ? '_blank' : '_self'}
|
||||
to={
|
||||
source.fullyQualifiedName && source.entityType
|
||||
? getEntityLinkFromType(
|
||||
getEncodedFqn(source.fullyQualifiedName),
|
||||
source.entityType as EntityType
|
||||
)
|
||||
: ''
|
||||
}>
|
||||
<Typography.Text
|
||||
className="text-lg font-medium text-link-color"
|
||||
data-testid="entity-header-display-name">
|
||||
{stringToHTML(getEntityName(source))}
|
||||
</Typography.Text>
|
||||
</Link>
|
||||
{isTourOpen ? (
|
||||
<Button data-testid={source.fullyQualifiedName} type="link">
|
||||
<Typography.Text
|
||||
className="text-lg font-medium text-link-color"
|
||||
data-testid="entity-header-display-name">
|
||||
{stringToHTML(getEntityName(source))}
|
||||
</Typography.Text>
|
||||
</Button>
|
||||
) : (
|
||||
<Link
|
||||
className="no-underline"
|
||||
data-testid="entity-link"
|
||||
target={openEntityInNewPage ? '_blank' : '_self'}
|
||||
to={
|
||||
source.fullyQualifiedName && source.entityType
|
||||
? getEntityLinkFromType(
|
||||
getEncodedFqn(source.fullyQualifiedName),
|
||||
source.entityType as EntityType
|
||||
)
|
||||
: ''
|
||||
}>
|
||||
<Typography.Text
|
||||
className="text-lg font-medium text-link-color"
|
||||
data-testid="entity-header-display-name">
|
||||
{stringToHTML(getEntityName(source))}
|
||||
</Typography.Text>
|
||||
</Link>
|
||||
)}
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
|
@ -13,12 +13,11 @@
|
||||
|
||||
import { Space, Table as AntdTable, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { ROUTES } from 'constants/constants';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { mockDatasetData } from 'constants/mockTourData.constants';
|
||||
import { t } from 'i18next';
|
||||
import { isEmpty, lowerCase } from 'lodash';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { getSampleDataByTableId } from 'rest/tableAPI';
|
||||
import { WORKFLOWS_PROFILER_DOCS } from '../../constants/docs.constants';
|
||||
import { Table } from '../../generated/entity/data/table';
|
||||
@ -34,17 +33,12 @@ import {
|
||||
SampleDataType,
|
||||
} from './sample.interface';
|
||||
import './SampleDataTable.style.less';
|
||||
|
||||
const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
||||
const location = useLocation();
|
||||
const { isTourOpen } = useTourProvider();
|
||||
|
||||
const [sampleData, setSampleData] = useState<SampleData>();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const isTourActive = useMemo(
|
||||
() => location.pathname.includes(ROUTES.TOUR),
|
||||
[location.pathname]
|
||||
);
|
||||
|
||||
const getSampleDataWithType = (table: Table) => {
|
||||
const { sampleData, columns } = table;
|
||||
const updatedColumns = sampleData?.columns?.map((column) => {
|
||||
@ -96,12 +90,12 @@ const SampleDataTable = ({ isTableDeleted, tableId }: SampleDataProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
if (!isTableDeleted && tableId && !isTourActive) {
|
||||
if (!isTableDeleted && tableId && !isTourOpen) {
|
||||
fetchSampleData();
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
}
|
||||
if (isTourActive) {
|
||||
if (isTourOpen) {
|
||||
setSampleData(
|
||||
getSampleDataWithType({
|
||||
columns: mockDatasetData.tableDetails.columns,
|
||||
|
@ -32,6 +32,7 @@ import { SummaryCard } from 'components/common/SummaryCard/SummaryCard.component
|
||||
import { SummaryCardProps } from 'components/common/SummaryCard/SummaryCard.interface';
|
||||
import DatePickerMenu from 'components/DatePickerMenu/DatePickerMenu.component';
|
||||
import { DateRangeObject } from 'components/ProfilerDashboard/component/TestSummary';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { mockDatasetData } from 'constants/mockTourData.constants';
|
||||
import { Column } from 'generated/entity/data/container';
|
||||
import {
|
||||
@ -55,7 +56,7 @@ import { ReactComponent as DataQualityIcon } from '../../assets/svg/data-quality
|
||||
import { ReactComponent as SettingIcon } from '../../assets/svg/ic-settings-primery.svg';
|
||||
import { ReactComponent as NoDataIcon } from '../../assets/svg/no-data-icon.svg';
|
||||
import { ReactComponent as TableProfileIcon } from '../../assets/svg/table-profile.svg';
|
||||
import { API_RES_MAX_SIZE, ROUTES } from '../../constants/constants';
|
||||
import { API_RES_MAX_SIZE } from '../../constants/constants';
|
||||
import { PAGE_HEADERS } from '../../constants/PageHeaders.constant';
|
||||
import {
|
||||
allowedServiceForOperationGraph,
|
||||
@ -93,20 +94,21 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const { isTourOpen } = useTourProvider();
|
||||
|
||||
const { activeTab = TableProfilerTab.TABLE_PROFILE, activeColumnFqn } =
|
||||
useMemo(() => {
|
||||
const param = location.search;
|
||||
const searchData = Qs.parse(
|
||||
param.startsWith('?') ? param.substring(1) : param
|
||||
);
|
||||
const {
|
||||
activeTab = isTourOpen
|
||||
? TableProfilerTab.COLUMN_PROFILE
|
||||
: TableProfilerTab.TABLE_PROFILE,
|
||||
activeColumnFqn,
|
||||
} = useMemo(() => {
|
||||
const param = location.search;
|
||||
const searchData = Qs.parse(
|
||||
param.startsWith('?') ? param.substring(1) : param
|
||||
);
|
||||
|
||||
return searchData as { activeTab: string; activeColumnFqn: string };
|
||||
}, [location.search]);
|
||||
const isTourPage = useMemo(
|
||||
() => location.pathname.includes(ROUTES.TOUR),
|
||||
[location.pathname]
|
||||
);
|
||||
return searchData as { activeTab: string; activeColumnFqn: string };
|
||||
}, [location.search, isTourOpen]);
|
||||
|
||||
const { datasetFQN } = useParams<{ datasetFQN: string }>();
|
||||
const [table, setTable] = useState<Table>();
|
||||
@ -299,12 +301,12 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
|
||||
useEffect(() => {
|
||||
if (isUndefined(activeTab)) {
|
||||
updateActiveTab(
|
||||
isTourPage
|
||||
isTourOpen
|
||||
? TableProfilerTab.COLUMN_PROFILE
|
||||
: TableProfilerTab.TABLE_PROFILE
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
}, [isTourOpen]);
|
||||
|
||||
const handleResultUpdate = (testCase: TestCase) => {
|
||||
setTableTests((prev) => {
|
||||
@ -432,19 +434,19 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
|
||||
}, [activeColumnFqn, columnTests]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isUndefined(table) && viewTest && !isTourPage) {
|
||||
if (!isUndefined(table) && viewTest && !isTourOpen) {
|
||||
fetchAllTests();
|
||||
}
|
||||
}, [table, viewTest]);
|
||||
}, [table, viewTest, isTourOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isTableDeleted && datasetFQN && !isTourPage) {
|
||||
if (!isTableDeleted && datasetFQN && !isTourOpen) {
|
||||
fetchLatestProfilerData();
|
||||
}
|
||||
if (isTourPage) {
|
||||
if (isTourOpen) {
|
||||
setTable(mockDatasetData.tableDetails as unknown as Table);
|
||||
}
|
||||
}, [datasetFQN]);
|
||||
}, [datasetFQN, isTourOpen]);
|
||||
|
||||
return (
|
||||
<Row
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2023 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 { ROUTES } from 'constants/constants';
|
||||
import { EntityTabs } from 'enums/entity.enum';
|
||||
import { CurrentTourPageType } from 'enums/tour.enum';
|
||||
import React, {
|
||||
createContext,
|
||||
FC,
|
||||
ReactNode,
|
||||
useContext,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export interface TourProviderContextProps {
|
||||
isTourOpen: boolean;
|
||||
isTourPage: boolean;
|
||||
currentTourPage: CurrentTourPageType;
|
||||
activeTabForTourDatasetPage: EntityTabs;
|
||||
tourSearchValue: string;
|
||||
updateIsTourOpen: (value: boolean) => void;
|
||||
updateTourPage: (value: CurrentTourPageType) => void;
|
||||
updateActiveTab: (value: EntityTabs) => void;
|
||||
updateTourSearch: (value: string) => void;
|
||||
}
|
||||
|
||||
export const TourContext = createContext({} as TourProviderContextProps);
|
||||
|
||||
const TourProvider: FC<Props> = ({ children }) => {
|
||||
const location = useLocation();
|
||||
const [isTourOpen, setIsTourOpen] = useState<boolean>(false);
|
||||
const [currentTourPage, setCurrentTourPage] = useState<CurrentTourPageType>(
|
||||
CurrentTourPageType.MY_DATA_PAGE
|
||||
);
|
||||
const [activeTabForTourDatasetPage, setActiveTabForTourDatasetPage] =
|
||||
useState<EntityTabs>(EntityTabs.SCHEMA);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
|
||||
const isTourPage = useMemo(
|
||||
() => location.pathname.includes(ROUTES.TOUR),
|
||||
[location.pathname]
|
||||
);
|
||||
|
||||
const handleIsTourOpen = (value: boolean) => {
|
||||
setIsTourOpen(value);
|
||||
};
|
||||
|
||||
const handleTourPageChange = (value: CurrentTourPageType) =>
|
||||
setCurrentTourPage(value);
|
||||
|
||||
const handleActiveTabChange = (value: EntityTabs) =>
|
||||
setActiveTabForTourDatasetPage(value);
|
||||
|
||||
const handleUpdateTourSearch = (value: string) => setSearchValue(value);
|
||||
|
||||
return (
|
||||
<TourContext.Provider
|
||||
value={{
|
||||
isTourOpen,
|
||||
isTourPage,
|
||||
currentTourPage,
|
||||
tourSearchValue: searchValue,
|
||||
activeTabForTourDatasetPage,
|
||||
updateActiveTab: handleActiveTabChange,
|
||||
updateIsTourOpen: handleIsTourOpen,
|
||||
updateTourPage: handleTourPageChange,
|
||||
updateTourSearch: handleUpdateTourSearch,
|
||||
}}>
|
||||
{children}
|
||||
</TourContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useTourProvider = () => useContext(TourContext);
|
||||
|
||||
export default TourProvider;
|
@ -14,6 +14,8 @@ import { Tabs } from 'antd';
|
||||
import AppState from 'AppState';
|
||||
import ActivityFeedListV1 from 'components/ActivityFeed/ActivityFeedList/ActivityFeedListV1.component';
|
||||
import { useActivityFeedProvider } from 'components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { mockFeedData } from 'constants/mockTourData.constants';
|
||||
import { FeedFilter } from 'enums/mydata.enum';
|
||||
import { ThreadType } from 'generated/entity/feed/thread';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
@ -25,6 +27,7 @@ import './feeds-widget.less';
|
||||
|
||||
const FeedsWidget = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isTourOpen } = useTourProvider();
|
||||
const [activeTab, setActiveTab] = useState('all');
|
||||
const { loading, entityThread, getFeedData } = useActivityFeedProvider();
|
||||
const [taskCount, setTaskCount] = useState(0);
|
||||
@ -86,9 +89,9 @@ const FeedsWidget = () => {
|
||||
key: 'all',
|
||||
children: (
|
||||
<ActivityFeedListV1
|
||||
feedList={entityThread}
|
||||
feedList={isTourOpen ? mockFeedData : entityThread}
|
||||
hidePopover={false}
|
||||
isLoading={loading}
|
||||
isLoading={loading && !isTourOpen}
|
||||
showThread={false}
|
||||
/>
|
||||
),
|
||||
|
@ -54,7 +54,7 @@ export const OwnerLabel = ({
|
||||
}, [owner]);
|
||||
|
||||
return (
|
||||
<Space size={8}>
|
||||
<Space data-testid="owner-label" size={8}>
|
||||
{profilePicture}
|
||||
|
||||
{displayName ? (
|
||||
|
@ -12,15 +12,15 @@
|
||||
*/
|
||||
|
||||
import ReactTutorial, { TourSteps } from '@deuex-solutions/react-tour';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { PRIMERY_COLOR } from 'constants/constants';
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useTour } from '../../hooks/useTour';
|
||||
import TourEndModal from '../Modals/TourEndModal/TourEndModal';
|
||||
|
||||
const Tour = ({ steps }: { steps: TourSteps[] }) => {
|
||||
const { isTourOpen, handleIsTourOpen } = useTour();
|
||||
const { isTourOpen, updateIsTourOpen } = useTourProvider();
|
||||
const [showTourEndModal, setShowTourEndModal] = useState(false);
|
||||
const history = useHistory();
|
||||
|
||||
@ -58,7 +58,7 @@ const Tour = ({ steps }: { steps: TourSteps[] }) => {
|
||||
playTour={isTourOpen}
|
||||
stepWaitTimer={300}
|
||||
steps={steps}
|
||||
onRequestClose={() => handleIsTourOpen(false)}
|
||||
onRequestClose={() => updateIsTourOpen(false)}
|
||||
onRequestSkip={handleModalSubmit}
|
||||
/>
|
||||
) : null}
|
||||
|
@ -427,62 +427,6 @@ export const mockDatasetData = {
|
||||
'Bosnia and Herzegovina',
|
||||
'399.279.7217x2246',
|
||||
],
|
||||
[
|
||||
'2fde1390-9bcd-486e-86e6-b4bb427faa75',
|
||||
'8b8e2b20-020d-4be3-a11d-1408b0f394d6',
|
||||
'Edward',
|
||||
'Tim',
|
||||
'86241 Marsh Fork',
|
||||
'14727 Benjamin Place Suite 747',
|
||||
'Adams, Parker and Gomez',
|
||||
'Sanchezville',
|
||||
'66293 Watson Unions',
|
||||
'50865',
|
||||
'Saint Vincent and the Grenadines',
|
||||
'(631)242-5727',
|
||||
],
|
||||
[
|
||||
'376096fe-2c8f-4e56-9ee2-7bd1dd2f9a88',
|
||||
'1a065321-c6cf-486c-91b1-57f8caab4727',
|
||||
'Joseph',
|
||||
'Brianna',
|
||||
'297 Selena Underpass',
|
||||
'41353 Mcdonald Squares Apt. 397',
|
||||
'Wright Inc',
|
||||
'New Melanie',
|
||||
'6230 Scott Roads Apt. 163',
|
||||
'42639',
|
||||
'Belgium',
|
||||
'001-360-399-2694x145',
|
||||
],
|
||||
[
|
||||
'afdbca76-af4e-4783-867e-e2b92161c40e',
|
||||
'adc24930-9dab-400b-9f46-620c1be9c841',
|
||||
'Beth',
|
||||
'Justin',
|
||||
'06732 Owens Ville Apt. 643',
|
||||
'02881 Tyler Square',
|
||||
'Baker-Coleman',
|
||||
'South Jonathan',
|
||||
'771 Smith Lodge Apt. 619',
|
||||
'12995',
|
||||
'Ecuador',
|
||||
'+1-060-277-3810x438',
|
||||
],
|
||||
[
|
||||
'b3d878b8-8e37-4922-a53a-f4b2295d8bb9',
|
||||
'647a2505-86da-4bdf-b5f3-d67ac8ec7980',
|
||||
'Tiffany',
|
||||
'Justin',
|
||||
'60489 Barbara Course Suite 095',
|
||||
'9328 Ashley Drives',
|
||||
'Schmidt Ltd',
|
||||
'New William',
|
||||
'6354 Johnson Glen',
|
||||
'37229',
|
||||
'Antarctica (the territory South of 60 deg S)',
|
||||
'(544)876-8904x194',
|
||||
],
|
||||
],
|
||||
},
|
||||
entityLineage: {
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 { useEffect, useState } from 'react';
|
||||
import AppState from '../AppState';
|
||||
|
||||
export const useTour = () => {
|
||||
const [isTourOpen, setIsTourOpen] = useState<boolean>();
|
||||
|
||||
useEffect(() => {
|
||||
setIsTourOpen(AppState.isTourOpen);
|
||||
}, [AppState.isTourOpen]);
|
||||
|
||||
const handleIsTourOpen = (value: boolean) => {
|
||||
AppState.isTourOpen = value;
|
||||
};
|
||||
|
||||
return {
|
||||
isTourOpen,
|
||||
handleIsTourOpen,
|
||||
};
|
||||
};
|
@ -38,9 +38,11 @@ import TableProfilerV1 from 'components/TableProfiler/TableProfilerV1';
|
||||
import TableQueries from 'components/TableQueries/TableQueries';
|
||||
import TabsLabel from 'components/TabsLabel/TabsLabel.component';
|
||||
import TagsContainerV1 from 'components/Tag/TagsContainerV1/TagsContainerV1';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { FQN_SEPARATOR_CHAR } from 'constants/char.constants';
|
||||
import { getTableTabPath, getVersionPath, ROUTES } from 'constants/constants';
|
||||
import { EntityField } from 'constants/Feeds.constants';
|
||||
import { mockDatasetData } from 'constants/mockTourData.constants';
|
||||
import { EntityTabs, EntityType, FqnPart } from 'enums/entity.enum';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { CreateThread } from 'generated/api/feed/createThread';
|
||||
@ -80,6 +82,8 @@ import { FrequentlyJoinedTables } from './FrequentlyJoinedTables/FrequentlyJoine
|
||||
import './table-details-page-v1.less';
|
||||
|
||||
const TableDetailsPageV1 = () => {
|
||||
const { isTourOpen, activeTabForTourDatasetPage, isTourPage } =
|
||||
useTourProvider();
|
||||
const [tableDetails, setTableDetails] = useState<Table>();
|
||||
const { datasetFQN, tab: activeTab = EntityTabs.SCHEMA } =
|
||||
useParams<{ datasetFQN: string; tab: string }>();
|
||||
@ -100,7 +104,7 @@ const TableDetailsPageV1 = () => {
|
||||
);
|
||||
const [queryCount, setQueryCount] = useState(0);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loading, setLoading] = useState(!isTourOpen);
|
||||
|
||||
const fetchTableDetails = async () => {
|
||||
setLoading(true);
|
||||
@ -141,7 +145,6 @@ const TableDetailsPageV1 = () => {
|
||||
DEFAULT_ENTITY_PERMISSION
|
||||
);
|
||||
|
||||
const isTourPage = location.pathname.includes(ROUTES.TOUR);
|
||||
const { postFeed, deleteFeed, updateFeed } = useActivityFeedProvider();
|
||||
const {
|
||||
tier,
|
||||
@ -242,7 +245,7 @@ const TableDetailsPageV1 = () => {
|
||||
|
||||
const handleTabChange = (activeKey: string) => {
|
||||
if (activeKey !== activeTab) {
|
||||
if (!isTourPage) {
|
||||
if (!isTourOpen) {
|
||||
history.push(getTableTabPath(datasetFQN, activeKey));
|
||||
}
|
||||
}
|
||||
@ -378,7 +381,7 @@ const TableDetailsPageV1 = () => {
|
||||
|
||||
const schemaTab = useMemo(
|
||||
() => (
|
||||
<Row gutter={[0, 16]} wrap={false}>
|
||||
<Row gutter={[0, 16]} id="schemaDetails" wrap={false}>
|
||||
<Col className="p-t-sm m-l-lg" flex="auto">
|
||||
<div className="d-flex flex-col gap-4">
|
||||
<DescriptionV1
|
||||
@ -754,9 +757,13 @@ const TableDetailsPageV1 = () => {
|
||||
}, [version]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTableDetails();
|
||||
getEntityFeedCount();
|
||||
}, [datasetFQN]);
|
||||
if (isTourOpen || isTourPage) {
|
||||
setTableDetails(mockDatasetData.tableDetails as unknown as Table);
|
||||
} else {
|
||||
fetchTableDetails();
|
||||
getEntityFeedCount();
|
||||
}
|
||||
}, [datasetFQN, isTourOpen, isTourPage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (tableDetails) {
|
||||
@ -798,7 +805,7 @@ const TableDetailsPageV1 = () => {
|
||||
title="Table details">
|
||||
<Row gutter={[0, 12]}>
|
||||
{/* Entity Heading */}
|
||||
<Col className="p-x-lg" span={24}>
|
||||
<Col className="p-x-lg" data-testid="entity-page-header" span={24}>
|
||||
<DataAssetsHeader
|
||||
dataAsset={tableDetails}
|
||||
entityType={EntityType.TABLE}
|
||||
@ -815,7 +822,11 @@ const TableDetailsPageV1 = () => {
|
||||
{/* Entity Tabs */}
|
||||
<Col span={24}>
|
||||
<Tabs
|
||||
activeKey={activeTab ?? EntityTabs.SCHEMA}
|
||||
activeKey={
|
||||
isTourOpen
|
||||
? activeTabForTourDatasetPage
|
||||
: activeTab ?? EntityTabs.SCHEMA
|
||||
}
|
||||
className="table-details-page-tabs"
|
||||
data-testid="tabs"
|
||||
items={tabs}
|
||||
|
@ -23,6 +23,8 @@ import {
|
||||
} from 'components/Explore/explore.interface';
|
||||
import ExploreV1 from 'components/ExploreV1/ExploreV1.component';
|
||||
import { withAdvanceSearch } from 'components/router/withAdvanceSearch';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { mockSearchData } from 'constants/mockTourData.constants';
|
||||
import { SORT_ORDER } from 'enums/common.enum';
|
||||
import { get, isEmpty, isNil, isString, isUndefined } from 'lodash';
|
||||
import Qs from 'qs';
|
||||
@ -63,6 +65,7 @@ import {
|
||||
const ExplorePageV1: FunctionComponent = () => {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
const { isTourOpen } = useTourProvider();
|
||||
|
||||
const { tab } = useParams<UrlParams>();
|
||||
|
||||
@ -438,10 +441,14 @@ const ExplorePageV1: FunctionComponent = () => {
|
||||
<ExploreV1
|
||||
aggregations={updatedAggregations}
|
||||
facetFilters={facetFilters}
|
||||
loading={isLoading}
|
||||
loading={isLoading && !isTourOpen}
|
||||
quickFilters={advancesSearchQuickFilters}
|
||||
searchIndex={searchIndex}
|
||||
searchResults={searchResults}
|
||||
searchResults={
|
||||
isTourOpen
|
||||
? (mockSearchData as unknown as SearchResponse<ExploreSearchIndex>)
|
||||
: searchResults
|
||||
}
|
||||
showDeleted={showDeleted}
|
||||
sortOrder={sortOrder}
|
||||
sortValue={sortValue}
|
||||
|
@ -12,39 +12,33 @@
|
||||
*/
|
||||
|
||||
import Tour from 'components/tour/Tour';
|
||||
import { EntityTabs } from 'enums/entity.enum';
|
||||
import { useTourProvider } from 'components/TourProvider/TourProvider';
|
||||
import { observer } from 'mobx-react';
|
||||
import ExplorePageV1Component from 'pages/explore/ExplorePageV1.component';
|
||||
import MyDataPageV1 from 'pages/MyDataPage/MyDataPageV1.component';
|
||||
import TableDetailsPageV1 from 'pages/TableDetailsPageV1/TableDetailsPageV1';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import AppState from '../../AppState';
|
||||
import React, { useEffect } from 'react';
|
||||
import { TOUR_SEARCH_TERM } from '../../constants/constants';
|
||||
import { CurrentTourPageType } from '../../enums/tour.enum';
|
||||
import { useTour } from '../../hooks/useTour';
|
||||
import { getSteps } from '../../utils/TourUtils';
|
||||
import { getTourSteps } from '../../utils/TourUtils';
|
||||
|
||||
const TourPage = () => {
|
||||
const { handleIsTourOpen } = useTour();
|
||||
const [currentPage, setCurrentPage] = useState<CurrentTourPageType>(
|
||||
AppState.currentTourPage
|
||||
);
|
||||
const [, setSearchValue] = useState('');
|
||||
const {
|
||||
updateIsTourOpen,
|
||||
currentTourPage,
|
||||
updateActiveTab,
|
||||
updateTourPage,
|
||||
updateTourSearch,
|
||||
} = useTourProvider();
|
||||
|
||||
const clearSearchTerm = () => {
|
||||
setSearchValue('');
|
||||
updateTourSearch('');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleIsTourOpen(true);
|
||||
AppState.currentTourPage = CurrentTourPageType.MY_DATA_PAGE;
|
||||
AppState.activeTabforTourDatasetPage = EntityTabs.SCHEMA;
|
||||
updateIsTourOpen(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(AppState.currentTourPage);
|
||||
}, [AppState.currentTourPage]);
|
||||
|
||||
const getCurrentPage = (page: CurrentTourPageType) => {
|
||||
switch (page) {
|
||||
case CurrentTourPageType.MY_DATA_PAGE:
|
||||
@ -63,8 +57,15 @@ const TourPage = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tour steps={getSteps(TOUR_SEARCH_TERM, clearSearchTerm)} />
|
||||
{getCurrentPage(currentPage)}
|
||||
<Tour
|
||||
steps={getTourSteps({
|
||||
searchTerm: TOUR_SEARCH_TERM,
|
||||
clearSearchTerm,
|
||||
updateActiveTab,
|
||||
updateTourPage,
|
||||
})}
|
||||
/>
|
||||
{getCurrentPage(currentTourPage)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -14,29 +14,20 @@
|
||||
import { EntityTabs } from 'enums/entity.enum';
|
||||
import i18next from 'i18next';
|
||||
import React from 'react';
|
||||
import AppState from '../AppState';
|
||||
import { CurrentTourPageType } from '../enums/tour.enum';
|
||||
import { Transi18next } from './CommonUtils';
|
||||
|
||||
export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
const { updateActiveTabForTourDatasetPage, updateCurrentTourPage } = AppState;
|
||||
interface ArgObject {
|
||||
searchTerm: string;
|
||||
updateTourPage: (value: CurrentTourPageType) => void;
|
||||
updateActiveTab: (value: EntityTabs) => void;
|
||||
clearSearchTerm: () => void;
|
||||
}
|
||||
|
||||
export const getTourSteps = (args: ArgObject) => {
|
||||
const { searchTerm, clearSearchTerm, updateActiveTab, updateTourPage } = args;
|
||||
|
||||
return [
|
||||
{
|
||||
content: () => (
|
||||
<p>
|
||||
<Transi18next
|
||||
i18nKey="message.tour-step-discover-all-assets-at-one-place"
|
||||
renderElement={<strong />}
|
||||
values={{
|
||||
text: i18next.t('label.open-metadata'),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
),
|
||||
stepInteraction: false,
|
||||
selector: '#assetStatsCount',
|
||||
},
|
||||
{
|
||||
content: () => (
|
||||
<p>
|
||||
@ -76,23 +67,23 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
i18nKey="message.tour-step-type-search-term"
|
||||
renderElement={<strong />}
|
||||
values={{
|
||||
text: value,
|
||||
text: searchTerm,
|
||||
enterText: i18next.t('label.enter'),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
),
|
||||
actionType: 'enter',
|
||||
userTypeText: value,
|
||||
userTypeText: searchTerm,
|
||||
selector: '#searchBox',
|
||||
beforeNext: () => {
|
||||
clearSearchTerm();
|
||||
updateCurrentTourPage(CurrentTourPageType.EXPLORE_PAGE);
|
||||
updateTourPage(CurrentTourPageType.EXPLORE_PAGE);
|
||||
},
|
||||
},
|
||||
{
|
||||
beforePrev: () => {
|
||||
updateCurrentTourPage(CurrentTourPageType.MY_DATA_PAGE);
|
||||
updateTourPage(CurrentTourPageType.MY_DATA_PAGE);
|
||||
},
|
||||
content: () => (
|
||||
<p>
|
||||
@ -118,14 +109,14 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
</p>
|
||||
),
|
||||
actionType: 'click',
|
||||
selector: '[data-testid="sample_data-dim_address"]',
|
||||
selector: '[data-testid="sample_data.ecommerce_db.shopify.dim_address"]',
|
||||
beforeNext: () => {
|
||||
updateCurrentTourPage(CurrentTourPageType.DATASET_PAGE);
|
||||
updateTourPage(CurrentTourPageType.DATASET_PAGE);
|
||||
},
|
||||
},
|
||||
{
|
||||
beforePrev: () => {
|
||||
updateCurrentTourPage(CurrentTourPageType.EXPLORE_PAGE);
|
||||
updateTourPage(CurrentTourPageType.EXPLORE_PAGE);
|
||||
},
|
||||
content: () => (
|
||||
<p>
|
||||
@ -139,7 +130,7 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
</p>
|
||||
),
|
||||
stepInteraction: false,
|
||||
selector: '[data-testid="entity-page-info"]',
|
||||
selector: '[data-testid="entity-page-header"]',
|
||||
},
|
||||
{
|
||||
content: () => (
|
||||
@ -154,7 +145,7 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
</p>
|
||||
),
|
||||
stepInteraction: false,
|
||||
selector: '[data-testid="owner-link"]',
|
||||
selector: '[data-testid="owner-label"]',
|
||||
},
|
||||
{
|
||||
content: () => (
|
||||
@ -188,7 +179,7 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
},
|
||||
{
|
||||
beforePrev: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.SCHEMA);
|
||||
updateActiveTab(EntityTabs.SCHEMA);
|
||||
},
|
||||
actionType: 'click',
|
||||
content: () => (
|
||||
@ -204,7 +195,7 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
),
|
||||
selector: `[data-testid="${EntityTabs.SAMPLE_DATA}"]`,
|
||||
beforeNext: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.SAMPLE_DATA);
|
||||
updateActiveTab(EntityTabs.SAMPLE_DATA);
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -219,14 +210,14 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
/>
|
||||
</p>
|
||||
),
|
||||
selector: '#tab-details',
|
||||
selector: '[data-testid="sample-data-table"]',
|
||||
},
|
||||
{
|
||||
beforePrev: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.SAMPLE_DATA);
|
||||
updateActiveTab(EntityTabs.SAMPLE_DATA);
|
||||
},
|
||||
beforeNext: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.PROFILER);
|
||||
updateActiveTab(EntityTabs.PROFILER);
|
||||
},
|
||||
actionType: 'click',
|
||||
content: () => (
|
||||
@ -257,14 +248,14 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
</p>
|
||||
),
|
||||
stepInteraction: false,
|
||||
selector: '#tab-details',
|
||||
selector: '#profilerDetails',
|
||||
},
|
||||
{
|
||||
beforePrev: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.PROFILER);
|
||||
updateActiveTab(EntityTabs.PROFILER);
|
||||
},
|
||||
beforeNext: () => {
|
||||
updateActiveTabForTourDatasetPage(EntityTabs.LINEAGE);
|
||||
updateActiveTab(EntityTabs.LINEAGE);
|
||||
},
|
||||
actionType: 'click',
|
||||
content: () => (
|
||||
@ -293,7 +284,7 @@ export const getSteps = (value: string, clearSearchTerm: () => void) => {
|
||||
</p>
|
||||
),
|
||||
stepInteraction: false,
|
||||
selector: '#tab-details',
|
||||
selector: '#lineageDetails',
|
||||
},
|
||||
];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user