Skip to content

Commit

Permalink
Merge branch 'datahub-project:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
shirshanka authored Jul 30, 2024
2 parents 4b664ef + 7d4b645 commit b338c7b
Show file tree
Hide file tree
Showing 15 changed files with 688 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.InputField;
import com.linkedin.datahub.graphql.types.dataset.mappers.SchemaFieldMapper;
import java.net.URISyntaxException;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class InputFieldsMapper {

public static final InputFieldsMapper INSTANCE = new InputFieldsMapper();
Expand All @@ -31,13 +35,19 @@ public com.linkedin.datahub.graphql.generated.InputFields apply(
.map(
field -> {
InputField fieldResult = new InputField();
Urn parentUrn = entityUrn;

if (field.hasSchemaField()) {
fieldResult.setSchemaField(
SchemaFieldMapper.map(context, field.getSchemaField(), entityUrn));
}
if (field.hasSchemaFieldUrn()) {
fieldResult.setSchemaFieldUrn(field.getSchemaFieldUrn().toString());
try {
parentUrn = Urn.createFromString(field.getSchemaFieldUrn().getEntityKey().get(0));
} catch (URISyntaxException e) {
log.error("Field urn resolution: failed to extract parentUrn successfully from {}. Falling back to {}", field.getSchemaFieldUrn(), entityUrn, e);
}
}
if (field.hasSchemaField()) {
fieldResult.setSchemaField(
SchemaFieldMapper.map(context, field.getSchemaField(), parentUrn));
}
return fieldResult;
})
Expand Down
28 changes: 28 additions & 0 deletions datahub-web-react/src/app/settings/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
FilterOutlined,
TeamOutlined,
PushpinOutlined,
ControlOutlined,
} from '@ant-design/icons';
import { Redirect, Route, useHistory, useLocation, useRouteMatch, Switch } from 'react-router';
import styled from 'styled-components';
Expand All @@ -17,11 +18,17 @@ import { ManagePermissions } from '../permissions/ManagePermissions';
import { useAppConfig } from '../useAppConfig';
import { AccessTokens } from './AccessTokens';
import { Preferences } from './Preferences';
import { Features } from './features/Features';
import { ManageViews } from '../entity/view/ManageViews';
import { useUserContext } from '../context/useUserContext';
import { ManageOwnership } from '../entity/ownership/ManageOwnership';
import ManagePosts from './posts/ManagePosts';

const MenuItem = styled(Menu.Item)`
display: flex;
align-items: center;
`;

const PageContainer = styled.div`
display: flex;
overflow: auto;
Expand Down Expand Up @@ -59,6 +66,17 @@ const ItemTitle = styled.span`

const menuStyle = { width: 256, 'margin-top': 8, overflow: 'hidden auto' };

const NewTag = styled.span`
padding: 4px 8px;
margin-left: 8px;
border-radius: 24px;
background: #f1fbfe;
color: #09739a;
font-size: 12px;
`;

/**
* URL Paths for each settings page.
*/
Expand All @@ -70,6 +88,7 @@ const PATHS = [
{ path: 'views', content: <ManageViews /> },
{ path: 'ownership', content: <ManageOwnership /> },
{ path: 'posts', content: <ManagePosts /> },
{ path: 'features', content: <Features /> },
];

/**
Expand All @@ -80,6 +99,7 @@ const DEFAULT_PATH = PATHS[0];
export const SettingsPage = () => {
const { path, url } = useRouteMatch();
const { pathname } = useLocation();

const history = useHistory();
const subRoutes = PATHS.map((p) => p.path.replace('/', ''));
const currPathName = pathname.replace(path, '');
Expand All @@ -101,6 +121,7 @@ export const SettingsPage = () => {
const showViews = isViewsEnabled || false;
const showOwnershipTypes = me && me?.platformPrivileges?.manageOwnershipTypes;
const showHomePagePosts = me && me?.platformPrivileges?.manageGlobalAnnouncements && !readOnlyModeEnabled;
const showFeatures = true; // TODO: Add feature flag for this

return (
<PageContainer>
Expand Down Expand Up @@ -143,6 +164,13 @@ export const SettingsPage = () => {
)}
{(showViews || showOwnershipTypes || showHomePagePosts) && (
<Menu.ItemGroup title="Manage">
{showFeatures && (
<MenuItem key="features">
<ControlOutlined />
<ItemTitle>Features</ItemTitle>
<NewTag>New!</NewTag>
</MenuItem>
)}
{showViews && (
<Menu.Item key="views">
<FilterOutlined /> <ItemTitle>My Views</ItemTitle>
Expand Down
179 changes: 179 additions & 0 deletions datahub-web-react/src/app/settings/features/Feature.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import React from 'react';

import styled from 'styled-components';

import { Divider, Typography, Switch, Card, Button, Tooltip } from 'antd';
import { ArrowRightOutlined } from '@ant-design/icons';
import { ANTD_GRAY } from '../../entity/shared/constants';

const Title = styled(Typography.Title)`
&& {
margin-bottom: 8px;
}
`;

const FeatureRow = styled.div`
display: flex;
align-items: flex-start;
justify-content: space-between;
`;

const FeatureOptionRow = styled.div`
display: flex;
justify-content: space-between;
&:not(:last-child) {
margin-bottom: 8px;
}
`;

const SettingsOptionRow = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 16px;
&:not(:last-child) {
margin-bottom: 8px;
}
`;

const DescriptionText = styled(Typography.Text)`
color: ${ANTD_GRAY[7]};
font-size: 11px;
`;

const SettingTitle = styled.div`
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
margin-bottom: 4px;
`;

const OptionTitle = styled(Typography.Text)`
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
`;

const learnMoreLinkStyle = {
flex: 1,
display: 'flex',
alignItems: 'center',
gap: '8px',
color: '#1890FF',
fontSize: '12px',
cursor: 'pointer',
};

const NewTag = styled.div`
padding: 4px 8px;
border-radius: 24px;
background: #f1fbfe;
color: #09739a;
font-size: 12px;
`;

const DataHubOnlyTag = styled.div`
padding: 2px 8px;
border-radius: 24px;
background: #c9fff2;
color: #50a494;
font-size: 12px;
`;

export interface FeatureType {
key: string;
title: string;
description: string;
settings: Array<{
key: string;
title: string;
isAvailable: boolean;
buttonText: string;
onClick?: () => void;
}>;
options: Array<{
key: string;
title: string;
description: string;
isAvailable: boolean;
checked: boolean;
onChange?: (checked: boolean) => void;
}>;
isNew: boolean;
learnMoreLink?: string;
}

export const Feature = ({ key, title, description, settings, options, isNew, learnMoreLink }: FeatureType) => (
<Card style={{ marginBottom: '1rem' }} key={key}>
<FeatureRow>
<div style={{ flex: 1 }}>
<SettingTitle>
<Title level={5} style={{ marginBottom: 0 }}>
{title}
</Title>
{isNew && <NewTag>New!</NewTag>}
</SettingTitle>
<div>
<Typography.Paragraph type="secondary">{description}</Typography.Paragraph>
</div>
</div>
<div>
{learnMoreLink && (
<a href={learnMoreLink} target="_blank" style={learnMoreLinkStyle} rel="noreferrer">
Learn more <ArrowRightOutlined />
</a>
)}
</div>
</FeatureRow>
<Divider style={{ margin: `8px 0 24px 0` }} />
{settings.map((option) => (
<>
<SettingsOptionRow key={option.key}>
<span>
<OptionTitle>
<span>{option.title}</span>
</OptionTitle>
</span>
<Tooltip title={option.isAvailable ? '' : 'Only available on DataHub Cloud'}>
<Button onClick={option.onClick} disabled={!option.isAvailable}>
{option.buttonText}
</Button>
</Tooltip>
</SettingsOptionRow>
</>
))}
<Card style={{ margin: `16px auto` }}>
{options.map((option, index) => (
<>
<FeatureOptionRow key={option.key}>
<span>
<OptionTitle>
<span>{option.title}</span>
{!option.isAvailable && (
<DataHubOnlyTag>Only available on DataHub Cloud</DataHubOnlyTag>
)}
</OptionTitle>
<div>
<DescriptionText>{option.description}</DescriptionText>
</div>
</span>
<Switch
checked={option.checked}
onChange={(checked) => (option.onChange ? option.onChange(checked) : null)}
disabled={!option.isAvailable}
/>
</FeatureOptionRow>
{index !== options.length - 1 && <Divider />}
</>
))}
</Card>
</Card>
);
Loading

0 comments on commit b338c7b

Please sign in to comment.