Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 102 additions & 15 deletions datahub-web-react/src/app/entityV2/view/ManageViews.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,138 @@
import { Typography } from 'antd';
import React from 'react';
import { Button, PageTitle, Tabs, colors } from '@components';
import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';

import { Tab } from '@components/components/Tabs/Tabs';

import { ViewBuilder } from '@app/entity/view/builder/ViewBuilder';
import { ViewBuilderMode } from '@app/entity/view/builder/types';
import { ViewsList } from '@app/entityV2/view/ViewsList';

import { DataHubViewType } from '@types';

const PageContainer = styled.div`
padding-top: 20px;
padding: 16px 20px;
width: 100%;
overflow: hidden;
flex: 1;
gap: 20px;
display: flex;
flex-direction: column;
overflow: auto;
`;

const PageHeaderContainer = styled.div`
&& {
padding-left: 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
`;

const PageTitle = styled(Typography.Title)`
&& {
margin-bottom: 12px;
}
const TitleContainer = styled.div`
flex: 1;
`;

const HeaderActionsContainer = styled.div`
display: flex;
justify-content: flex-end;
`;

const ListContainer = styled.div`
flex: 1;
display: flex;
flex-direction: column;
&&& .ant-tabs-nav {
margin: 0;
}
color: ${colors.gray[600]};
overflow: auto;
`;

enum TabType {
Personal = 'My Views',
Global = 'Public Views',
}

const tabUrlMap = {
[TabType.Personal]: '/settings/views/personal',
[TabType.Global]: '/settings/views/public',
};

/**
* Component used for displaying the 'Manage Views' experience.
*/
export const ManageViews = () => {
const [showViewBuilder, setShowViewBuilder] = useState(false);
const [selectedTab, setSelectedTab] = useState<TabType | undefined | null>();

const onCloseModal = () => {
setShowViewBuilder(false);
};

const tabs: Tab[] = [
{
component: <ViewsList viewType={DataHubViewType.Personal} />,
key: TabType.Personal,
name: TabType.Personal,
},
{
component: <ViewsList viewType={DataHubViewType.Global} />,
key: TabType.Global,
name: TabType.Global,
},
];

useEffect(() => {
if (selectedTab === undefined) {
const currentPath = window.location.pathname;

const currentTab = Object.entries(tabUrlMap).find(([, url]) => url === currentPath)?.[0] as TabType;
if (currentTab) {
setSelectedTab(currentTab);
} else {
setSelectedTab(null);
}
}
}, [selectedTab]);

const getCurrentUrl = useCallback(() => window.location.pathname, []);
Comment on lines +88 to +99
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's always try to use location from useLocation instead of the window object directly - it's generally safer and factors in stuff like if we have a basePath prefixed to our site. which we now support :)


return (
<PageContainer>
<PageHeaderContainer>
<PageTitle level={3}>Manage Views</PageTitle>
<Typography.Paragraph type="secondary">
Create, edit, and remove your Views. Views allow you to save and share sets of filters for reuse
when browsing DataHub.
</Typography.Paragraph>
<TitleContainer>
<PageTitle
title="Views"
subTitle="Create, edit, and remove your Views. Views allow you to save and share sets of filters for reuse when browsing DataHub."
/>
</TitleContainer>
<HeaderActionsContainer>
<Button
variant="filled"
id="create-new-view-button"
onClick={() => setShowViewBuilder(true)}
data-testid="create-new-view-button"
icon={{ icon: 'Plus', source: 'phosphor' }}
disabled={false}
>
Create View
</Button>
</HeaderActionsContainer>
</PageHeaderContainer>
<ListContainer>
<ViewsList />
<Tabs
tabs={tabs}
selectedTab={selectedTab as string}
onChange={(tab) => setSelectedTab(tab as TabType)}
urlMap={tabUrlMap}
defaultTab={TabType.Personal}
getCurrentUrl={getCurrentUrl}
/>
</ListContainer>
{showViewBuilder && (
<ViewBuilder mode={ViewBuilderMode.EDITOR} onSubmit={onCloseModal} onCancel={onCloseModal} />
)}
</PageContainer>
);
};
46 changes: 17 additions & 29 deletions datahub-web-react/src/app/entityV2/view/ViewTypeLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
import { GlobalOutlined, LockOutlined } from '@ant-design/icons';
import { Icon, Tooltip } from '@components';
import { Typography } from 'antd';
import React from 'react';
import styled from 'styled-components';

import { DataHubViewType } from '@types';

const StyledLockOutlined = styled(LockOutlined)<{ color }>`
color: ${(props) => props.color};
margin-right: 4px;
`;

const StyledGlobalOutlined = styled(GlobalOutlined)<{ color }>`
color: ${(props) => props.color};
margin-right: 4px;
`;

const StyledText = styled(Typography.Text)<{ color }>`
&& {
color: ${(props) => props.color};
Expand All @@ -27,31 +17,29 @@ type Props = {
onClick?: () => void;
};

const ViewNameContainer = styled.div`
display: flex;
align-items: center;
gap: 4px;
`;

/**
* Label used to describe View Types
*
* @param param0 the color of the text and iconography
*/
export const ViewTypeLabel = ({ type, color, onClick }: Props) => {
const copy =
type === DataHubViewType.Personal ? (
<>
<b>Private</b> - only visible to you.
</>
) : (
<>
<b>Public</b> - visible to everyone.
</>
);
const Icon = type === DataHubViewType.Global ? StyledGlobalOutlined : StyledLockOutlined;

const isPersonal = type === DataHubViewType.Personal;
return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
<div onClick={onClick}>
<Icon color={color} />
<StyledText color={color} type="secondary">
{copy}
</StyledText>
</div>
<Tooltip title={isPersonal ? 'Only visible to you' : 'Visible to everyone'}>
<ViewNameContainer onClick={onClick}>
{!isPersonal && <Icon source="phosphor" icon="Globe" size="md" />}
{isPersonal && <Icon source="phosphor" icon="Lock" size="md" />}
<StyledText color={color} type="secondary">
{!isPersonal ? 'Public' : 'Private'}
</StyledText>
</ViewNameContainer>
</Tooltip>
);
};
Loading
Loading