Skip to content

Commit

Permalink
feat(ui) Add structured properties support in the UI (datahub-project…
Browse files Browse the repository at this point in the history
  • Loading branch information
chriscollins3456 authored Jan 25, 2024
1 parent f83a2fa commit a78c689
Show file tree
Hide file tree
Showing 45 changed files with 1,772 additions and 140 deletions.
5 changes: 5 additions & 0 deletions datahub-web-react/src/Mocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ export const dataset1 = {
embed: null,
browsePathV2: { path: [{ name: 'test', entity: null }], __typename: 'BrowsePathV2' },
autoRenderAspects: [],
structuredProperties: null,
};

export const dataset2 = {
Expand Down Expand Up @@ -393,6 +394,7 @@ export const dataset2 = {
embed: null,
browsePathV2: { path: [{ name: 'test', entity: null }], __typename: 'BrowsePathV2' },
autoRenderAspects: [],
structuredProperties: null,
};

export const dataset3 = {
Expand Down Expand Up @@ -626,6 +628,7 @@ export const dataset3 = {
dataProduct: null,
lastProfile: null,
lastOperation: null,
structuredProperties: null,
} as Dataset;

export const dataset3WithSchema = {
Expand All @@ -650,6 +653,7 @@ export const dataset3WithSchema = {
globalTags: null,
glossaryTerms: null,
label: 'hi',
schemaFieldEntity: null,
},
{
__typename: 'SchemaField',
Expand All @@ -665,6 +669,7 @@ export const dataset3WithSchema = {
globalTags: null,
glossaryTerms: null,
label: 'hi',
schemaFieldEntity: null,
},
],
hash: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type Props = {
description: string,
) => Promise<FetchResult<UpdateDatasetMutation, Record<string, any>, Record<string, any>> | void>;
isEdited?: boolean;
isReadOnly?: boolean;
};

const ABBREVIATED_LIMIT = 80;
Expand All @@ -97,10 +98,11 @@ export default function DescriptionField({
onUpdate,
isEdited = false,
original,
isReadOnly,
}: Props) {
const [showAddModal, setShowAddModal] = useState(false);
const overLimit = removeMarkdown(description).length > 80;
const isSchemaEditable = React.useContext(SchemaEditableContext);
const isSchemaEditable = React.useContext(SchemaEditableContext) && !isReadOnly;
const onCloseModal = () => setShowAddModal(false);
const { urn, entityType } = useEntityData();

Expand Down Expand Up @@ -140,11 +142,12 @@ export default function DescriptionField({
{expanded || !overLimit ? (
<>
{!!description && <StyledViewer content={description} readOnly />}
{!!description && (
{!!description && (EditButton || overLimit) && (
<ExpandedActions>
{overLimit && (
<ReadLessText
onClick={() => {
onClick={(e) => {
e.stopPropagation();
handleExpanded(false);
}}
>
Expand All @@ -162,7 +165,8 @@ export default function DescriptionField({
readMore={
<>
<Typography.Link
onClick={() => {
onClick={(e) => {
e.stopPropagation();
handleExpanded(true);
}}
>
Expand All @@ -177,7 +181,7 @@ export default function DescriptionField({
</StripMarkdownText>
</>
)}
{isSchemaEditable && isEdited && <EditedLabel>(edited)</EditedLabel>}
{isEdited && <EditedLabel>(edited)</EditedLabel>}
{showAddModal && (
<div>
<UpdateDescriptionModal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function UpdateDescriptionModal({ title, description, original, o
>
<Form layout="vertical">
<Form.Item>
<StyledEditor content={updatedDesc} onChange={setDesc} />
<StyledEditor content={updatedDesc} onChange={setDesc} dataTestId="description-editor" />
</Form.Item>
{!isAddDesc && description && original && (
<Form.Item label={<FormLabel>Original:</FormLabel>}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { useEntityRegistry } from '../../../../useEntityRegistry';
import { PlatformIcon } from '../../../../search/filters/utils';
import { Entity } from '../../../../../types.generated';
import { IconStyleType } from '../../../Entity';
import { ANTD_GRAY } from '../../constants';

interface Props {
entity: Entity;
size?: number;
}

export default function EntityIcon({ entity, size = 14 }: Props) {
const entityRegistry = useEntityRegistry();
const genericEntityProps = entityRegistry.getGenericEntityProperties(entity.type, entity);
const logoUrl = genericEntityProps?.platform?.properties?.logoUrl;
const icon = logoUrl ? (
<PlatformIcon src={logoUrl} size={size} />
) : (
entityRegistry.getIcon(entity.type, size, IconStyleType.ACCENT, ANTD_GRAY[9])
);

return <>{icon}</>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import LineageExplorer from '../../../../lineage/LineageExplorer';
import CompactContext from '../../../../shared/CompactContext';
import DynamicTab from '../../tabs/Entity/weaklyTypedAspects/DynamicTab';
import analytics, { EventType } from '../../../../analytics';
import { ProfileSidebarResizer } from './sidebar/ProfileSidebarResizer';
import { EntityMenuItems } from '../../EntityDropdown/EntityDropdown';
import { useIsSeparateSiblingsMode } from '../../siblingUtils';
import { EntityActionItem } from '../../entity/EntityActions';
Expand All @@ -45,6 +44,7 @@ import {
} from '../../../../onboarding/config/LineageGraphOnboardingConfig';
import { useAppConfig } from '../../../../useAppConfig';
import { useUpdateDomainEntityDataOnChange } from '../../../../domain/utils';
import ProfileSidebar from './sidebar/ProfileSidebar';

type Props<T, U> = {
urn: string;
Expand Down Expand Up @@ -75,8 +75,6 @@ type Props<T, U> = {
isNameEditable?: boolean;
};

const MAX_SIDEBAR_WIDTH = 800;
const MIN_SIDEBAR_WIDTH = 200;
const MAX_COMPACT_WIDTH = 490 - 24 * 2;

const ContentContainer = styled.div`
Expand All @@ -85,6 +83,7 @@ const ContentContainer = styled.div`
min-height: 100%;
flex: 1;
min-width: 0;
overflow: hidden;
`;

const HeaderAndTabs = styled.div`
Expand Down Expand Up @@ -113,15 +112,6 @@ const HeaderAndTabsFlex = styled.div`
-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75);
}
`;
const Sidebar = styled.div<{ $width: number }>`
max-height: 100%;
overflow: auto;
width: ${(props) => props.$width}px;
min-width: ${(props) => props.$width}px;
padding-left: 20px;
padding-right: 20px;
padding-bottom: 20px;
`;

const Header = styled.div`
border-bottom: 1px solid ${ANTD_GRAY[4.5]};
Expand All @@ -145,7 +135,7 @@ const defaultTabDisplayConfig = {
enabled: (_, _1) => true,
};

const defaultSidebarSection = {
export const DEFAULT_SIDEBAR_SECTION = {
visible: (_, _1) => true,
};

Expand Down Expand Up @@ -176,11 +166,10 @@ export const EntityProfile = <T, U>({
const sortedTabs = sortEntityProfileTabs(appConfig.config, entityType, tabsWithDefaults);
const sideBarSectionsWithDefaults = sidebarSections.map((sidebarSection) => ({
...sidebarSection,
display: { ...defaultSidebarSection, ...sidebarSection.display },
display: { ...DEFAULT_SIDEBAR_SECTION, ...sidebarSection.display },
}));

const [shouldRefetchEmbeddedListSearch, setShouldRefetchEmbeddedListSearch] = useState(false);
const [sidebarWidth, setSidebarWidth] = useState(window.innerWidth * 0.25);
const entityStepIds: string[] = getOnboardingStepIdsForEntityType(entityType);
const lineageGraphStepIds: string[] = [LINEAGE_GRAPH_INTRO_ID, LINEAGE_GRAPH_TIME_FILTER_ID];
const stepIds = isLineageMode ? lineageGraphStepIds : entityStepIds;
Expand Down Expand Up @@ -344,15 +333,7 @@ export const EntityProfile = <T, U>({
</TabContent>
</HeaderAndTabsFlex>
</HeaderAndTabs>
<ProfileSidebarResizer
setSidePanelWidth={(width) =>
setSidebarWidth(Math.min(Math.max(width, MIN_SIDEBAR_WIDTH), MAX_SIDEBAR_WIDTH))
}
initialSize={sidebarWidth}
/>
<Sidebar $width={sidebarWidth}>
<EntitySidebar sidebarSections={sideBarSectionsWithDefaults} />
</Sidebar>
<ProfileSidebar sidebarSections={sidebarSections} />
</>
)}
</ContentContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ const LastIngestedSection = styled.div`

type Props = {
sidebarSections: EntitySidebarSection[];
topSection?: EntitySidebarSection;
};

export const EntitySidebar = <T,>({ sidebarSections }: Props) => {
export const EntitySidebar = <T,>({ sidebarSections, topSection }: Props) => {
const { entityData } = useEntityData();
const baseEntity = useBaseEntity<T>();

return (
<>
{topSection && <topSection.component key={`${topSection.component}`} properties={topSection.properties} />}
{entityData?.lastIngested && (
<LastIngestedSection>
<LastIngested lastIngested={entityData.lastIngested} />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useState } from 'react';
import styled from 'styled-components';
import { ProfileSidebarResizer } from './ProfileSidebarResizer';
import { EntitySidebar } from './EntitySidebar';
import { EntitySidebarSection } from '../../../types';

export const MAX_SIDEBAR_WIDTH = 800;
export const MIN_SIDEBAR_WIDTH = 200;

const Sidebar = styled.div<{ $width: number; backgroundColor?: string }>`
max-height: 100%;
position: relative;
width: ${(props) => props.$width}px;
min-width: ${(props) => props.$width}px;
${(props) => props.backgroundColor && `background-color: ${props.backgroundColor};`}
`;

const ScrollWrapper = styled.div`
overflow: auto;
max-height: 100%;
padding: 0 20px 20px 20px;
`;

const DEFAULT_SIDEBAR_SECTION = {
visible: (_, _1) => true,
};

interface Props {
sidebarSections: EntitySidebarSection[];
backgroundColor?: string;
topSection?: EntitySidebarSection;
alignLeft?: boolean;
}

export default function ProfileSidebar({ sidebarSections, backgroundColor, topSection, alignLeft }: Props) {
const sideBarSectionsWithDefaults = sidebarSections.map((sidebarSection) => ({
...sidebarSection,
display: { ...DEFAULT_SIDEBAR_SECTION, ...sidebarSection.display },
}));

const [sidebarWidth, setSidebarWidth] = useState(window.innerWidth * 0.25);

if (alignLeft) {
return (
<>
<Sidebar $width={sidebarWidth} backgroundColor={backgroundColor} id="entity-profile-sidebar">
<ScrollWrapper>
<EntitySidebar sidebarSections={sideBarSectionsWithDefaults} topSection={topSection} />
</ScrollWrapper>
</Sidebar>
<ProfileSidebarResizer
setSidePanelWidth={(width) =>
setSidebarWidth(Math.min(Math.max(width, MIN_SIDEBAR_WIDTH), MAX_SIDEBAR_WIDTH))
}
initialSize={sidebarWidth}
isSidebarOnLeft
/>
</>
);
}

return (
<>
<ProfileSidebarResizer
setSidePanelWidth={(width) =>
setSidebarWidth(Math.min(Math.max(width, MIN_SIDEBAR_WIDTH), MAX_SIDEBAR_WIDTH))
}
initialSize={sidebarWidth}
/>
<Sidebar $width={sidebarWidth} backgroundColor={backgroundColor} id="entity-profile-sidebar">
<ScrollWrapper>
<EntitySidebar sidebarSections={sideBarSectionsWithDefaults} topSection={topSection} />
</ScrollWrapper>
</Sidebar>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ export const SchemaTab = ({ properties }: { properties?: any }) => {
[schemaMetadata],
);

const hasProperties = useMemo(
() =>
entityWithSchema?.schemaMetadata?.fields.some(
(schemaField) => !!schemaField.schemaFieldEntity?.structuredProperties?.properties?.length,
),
[entityWithSchema],
);

const [showKeySchema, setShowKeySchema] = useState(false);
const [showSchemaAuditView, setShowSchemaAuditView] = useState(false);

Expand Down Expand Up @@ -190,13 +198,13 @@ export const SchemaTab = ({ properties }: { properties?: any }) => {
<SchemaTable
schemaMetadata={schemaMetadata}
rows={rows}
editMode={editMode}
editableSchemaMetadata={editableSchemaMetadata}
usageStats={usageStats}
schemaFieldBlameList={schemaFieldBlameList}
showSchemaAuditView={showSchemaAuditView}
expandedRowsFromFilter={expandedRowsFromFilter as any}
filterText={filterText as any}
hasProperties={hasProperties}
/>
</SchemaEditableContext.Provider>
</>
Expand Down
Loading

0 comments on commit a78c689

Please sign in to comment.