2022-01-19 17:02:17 -08:00
|
|
|
import React, { useState } from 'react';
|
2022-04-22 16:46:09 -04:00
|
|
|
import {
|
|
|
|
CheckOutlined,
|
|
|
|
CopyOutlined,
|
2022-05-05 22:46:45 +02:00
|
|
|
ExclamationCircleOutlined,
|
2022-04-22 16:46:09 -04:00
|
|
|
InfoCircleOutlined,
|
2022-05-05 22:46:45 +02:00
|
|
|
LinkOutlined,
|
2022-04-22 16:46:09 -04:00
|
|
|
MoreOutlined,
|
|
|
|
RightOutlined,
|
|
|
|
} from '@ant-design/icons';
|
2022-05-13 00:17:19 -04:00
|
|
|
import { Typography, Button, Tooltip, Menu, Dropdown, message, Popover } from 'antd';
|
2021-08-31 22:00:56 -07:00
|
|
|
import styled from 'styled-components';
|
2022-04-16 03:40:44 +05:30
|
|
|
import moment from 'moment';
|
|
|
|
|
2022-02-02 13:51:39 -08:00
|
|
|
import { capitalizeFirstLetterOnly } from '../../../../../shared/textUtil';
|
2021-08-31 22:00:56 -07:00
|
|
|
import { ANTD_GRAY } from '../../../constants';
|
2022-04-16 03:40:44 +05:30
|
|
|
import { useEntityData, useRefetch } from '../../../EntityContext';
|
2022-02-07 22:52:59 +05:30
|
|
|
import analytics, { EventType, EntityActionType } from '../../../../../analytics';
|
2022-03-04 11:51:31 -08:00
|
|
|
import { EntityHealthStatus } from './EntityHealthStatus';
|
2022-04-16 03:40:44 +05:30
|
|
|
import { useUpdateDeprecationMutation } from '../../../../../../graphql/mutations.generated';
|
|
|
|
import { getLocaleTimezone } from '../../../../../shared/time/timeUtils';
|
|
|
|
import { AddDeprecationDetailsModal } from './AddDeprecationDetailsModal';
|
2022-05-13 00:17:19 -04:00
|
|
|
import PlatformContent from './PlatformContent';
|
|
|
|
import { getPlatformName } from '../../../utils';
|
|
|
|
import EntityCount from './EntityCount';
|
2021-08-31 22:00:56 -07:00
|
|
|
|
|
|
|
const EntityTitle = styled(Typography.Title)`
|
|
|
|
&&& {
|
|
|
|
margin-bottom: 0;
|
2022-01-07 17:29:15 -08:00
|
|
|
word-break: break-all;
|
2021-08-31 22:00:56 -07:00
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
const HeaderContainer = styled.div`
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
align-items: space-between;
|
|
|
|
margin-bottom: 4px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const MainHeaderContent = styled.div`
|
|
|
|
flex: 1;
|
2022-05-13 00:17:19 -04:00
|
|
|
width: 85%;
|
2022-02-02 13:51:39 -08:00
|
|
|
|
2022-05-13 00:17:19 -04:00
|
|
|
.entityCount {
|
|
|
|
margin: 5px 0 -4px 0;
|
2022-02-02 13:51:39 -08:00
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
2022-04-16 03:40:44 +05:30
|
|
|
const DeprecatedContainer = styled.div`
|
|
|
|
width: 110px;
|
|
|
|
height: 18px;
|
|
|
|
border: 1px solid #ef5b5b;
|
|
|
|
border-radius: 15px;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
color: #ef5b5b;
|
|
|
|
margin-left: 15px;
|
|
|
|
padding-top: 12px;
|
|
|
|
padding-bottom: 12px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const DeprecatedText = styled.div`
|
|
|
|
color: #ef5b5b;
|
|
|
|
margin-left: 5px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const MenuIcon = styled(MoreOutlined)`
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
font-size: 25px;
|
|
|
|
height: 32px;
|
|
|
|
margin-left: 5px;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const MenuItem = styled.div`
|
|
|
|
font-size: 12px;
|
|
|
|
padding-left: 12px;
|
|
|
|
padding-right: 12px;
|
|
|
|
color: rgba(0, 0, 0, 0.85);
|
|
|
|
`;
|
|
|
|
|
|
|
|
const LastEvaluatedAtLabel = styled.div`
|
|
|
|
padding: 0;
|
|
|
|
margin: 0;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
color: ${ANTD_GRAY[7]};
|
|
|
|
`;
|
|
|
|
|
|
|
|
const Divider = styled.div`
|
|
|
|
border-top: 1px solid #f0f0f0;
|
|
|
|
padding-top: 5px;
|
|
|
|
`;
|
|
|
|
|
2022-04-22 16:46:09 -04:00
|
|
|
const SideHeaderContent = styled.div`
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const TopButtonsWrapper = styled.div`
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
margin-bottom: 8px;
|
|
|
|
`;
|
|
|
|
|
2022-04-21 09:51:47 -07:00
|
|
|
type Props = {
|
|
|
|
showDeprecateOption?: boolean;
|
|
|
|
};
|
|
|
|
|
|
|
|
export const EntityHeader = ({ showDeprecateOption }: Props) => {
|
2021-08-31 22:00:56 -07:00
|
|
|
const { urn, entityType, entityData } = useEntityData();
|
2022-04-16 03:40:44 +05:30
|
|
|
const [updateDeprecation] = useUpdateDeprecationMutation();
|
|
|
|
const [showAddDeprecationDetailsModal, setShowAddDeprecationDetailsModal] = useState(false);
|
|
|
|
const refetch = useRefetch();
|
2022-01-19 17:02:17 -08:00
|
|
|
const [copiedUrn, setCopiedUrn] = useState(false);
|
2022-05-13 00:17:19 -04:00
|
|
|
const basePlatformName = getPlatformName(entityData);
|
2022-02-02 13:51:39 -08:00
|
|
|
const platformName = capitalizeFirstLetterOnly(basePlatformName);
|
2021-08-31 22:00:56 -07:00
|
|
|
const externalUrl = entityData?.externalUrl || undefined;
|
2022-05-13 00:17:19 -04:00
|
|
|
const entityCount = entityData?.entityCount;
|
2021-08-31 22:00:56 -07:00
|
|
|
const hasExternalUrl = !!externalUrl;
|
2022-02-07 22:52:59 +05:30
|
|
|
|
|
|
|
const sendAnalytics = () => {
|
|
|
|
analytics.event({
|
|
|
|
type: EventType.EntityActionEvent,
|
|
|
|
actionType: EntityActionType.ClickExternalUrl,
|
|
|
|
entityType,
|
|
|
|
entityUrn: urn,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2022-04-16 03:40:44 +05:30
|
|
|
// Update the Deprecation
|
|
|
|
const handleUpdateDeprecation = async (deprecatedStatus: boolean) => {
|
|
|
|
message.loading({ content: 'Updating...' });
|
|
|
|
try {
|
|
|
|
await updateDeprecation({
|
|
|
|
variables: {
|
|
|
|
input: {
|
|
|
|
urn,
|
|
|
|
deprecated: deprecatedStatus,
|
|
|
|
note: '',
|
|
|
|
decommissionTime: null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
message.destroy();
|
|
|
|
message.success({ content: 'Deprecation Updated', duration: 2 });
|
|
|
|
} catch (e: unknown) {
|
|
|
|
message.destroy();
|
|
|
|
if (e instanceof Error) {
|
|
|
|
message.error({ content: `Failed to update Deprecation: \n ${e.message || ''}`, duration: 2 });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
refetch?.();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deprecation Decommission Timestamp
|
|
|
|
*/
|
|
|
|
const localeTimezone = getLocaleTimezone();
|
|
|
|
const decommissionTimeLocal =
|
|
|
|
(entityData?.deprecation?.decommissionTime &&
|
|
|
|
`Scheduled to be decommissioned on ${moment
|
|
|
|
.unix(entityData?.deprecation?.decommissionTime)
|
|
|
|
.format('DD/MMM/YYYY')} at ${moment
|
|
|
|
.unix(entityData?.deprecation?.decommissionTime)
|
|
|
|
.format('HH:mm:ss')} (${localeTimezone})`) ||
|
|
|
|
undefined;
|
|
|
|
const decommissionTimeGMT =
|
|
|
|
entityData?.deprecation?.decommissionTime &&
|
|
|
|
moment.unix(entityData?.deprecation?.decommissionTime).utc().format('dddd, DD/MMM/YYYY HH:mm:ss z');
|
|
|
|
|
|
|
|
const hasDetails = entityData?.deprecation?.note !== '' || entityData?.deprecation?.decommissionTime !== null;
|
|
|
|
const isDividerNeeded = entityData?.deprecation?.note !== '' && entityData?.deprecation?.decommissionTime !== null;
|
2022-04-21 09:51:47 -07:00
|
|
|
const showAdditionalOptions = showDeprecateOption;
|
2022-05-05 22:46:45 +02:00
|
|
|
const pageUrl = window.location.href;
|
2022-04-16 03:40:44 +05:30
|
|
|
|
2021-08-31 22:00:56 -07:00
|
|
|
return (
|
2022-04-16 03:40:44 +05:30
|
|
|
<>
|
|
|
|
<HeaderContainer>
|
|
|
|
<MainHeaderContent>
|
2022-05-13 00:17:19 -04:00
|
|
|
<PlatformContent />
|
2022-04-16 03:40:44 +05:30
|
|
|
<div style={{ display: 'flex', justifyContent: 'left', alignItems: 'center' }}>
|
2022-04-22 16:46:09 -04:00
|
|
|
<EntityTitle level={3}>{entityData?.name || ' '}</EntityTitle>
|
2022-04-16 03:40:44 +05:30
|
|
|
{entityData?.deprecation?.deprecated && (
|
|
|
|
<Popover
|
|
|
|
overlayStyle={{ maxWidth: 240 }}
|
|
|
|
placement="right"
|
|
|
|
content={
|
|
|
|
hasDetails ? (
|
|
|
|
<>
|
|
|
|
{entityData?.deprecation?.note !== '' && (
|
|
|
|
<Typography.Text>{entityData?.deprecation?.note}</Typography.Text>
|
|
|
|
)}
|
|
|
|
{isDividerNeeded && <Divider />}
|
|
|
|
{entityData?.deprecation?.decommissionTime !== null && (
|
|
|
|
<Typography.Text type="secondary">
|
|
|
|
<Tooltip placement="right" title={decommissionTimeGMT}>
|
|
|
|
<LastEvaluatedAtLabel>
|
|
|
|
{decommissionTimeLocal}
|
|
|
|
</LastEvaluatedAtLabel>
|
|
|
|
</Tooltip>
|
|
|
|
</Typography.Text>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
'No additional details'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
>
|
|
|
|
<DeprecatedContainer>
|
|
|
|
<InfoCircleOutlined />
|
|
|
|
<DeprecatedText>Deprecated</DeprecatedText>
|
|
|
|
</DeprecatedContainer>
|
|
|
|
</Popover>
|
|
|
|
)}
|
|
|
|
{entityData?.health && (
|
|
|
|
<EntityHealthStatus
|
|
|
|
status={entityData?.health.status}
|
|
|
|
message={entityData?.health?.message || undefined}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</div>
|
2022-05-13 00:17:19 -04:00
|
|
|
<EntityCount entityCount={entityCount} />
|
2022-04-16 03:40:44 +05:30
|
|
|
</MainHeaderContent>
|
2022-04-22 16:46:09 -04:00
|
|
|
<SideHeaderContent>
|
|
|
|
<TopButtonsWrapper>
|
2022-05-20 05:48:09 +02:00
|
|
|
{navigator.clipboard && (
|
|
|
|
<Tooltip title="Copy URN. An URN uniquely identifies an entity on DataHub.">
|
|
|
|
<Button
|
|
|
|
icon={copiedUrn ? <CheckOutlined /> : <CopyOutlined />}
|
|
|
|
onClick={() => {
|
|
|
|
navigator.clipboard.writeText(urn);
|
|
|
|
setCopiedUrn(true);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</Tooltip>
|
|
|
|
)}
|
2022-04-22 16:46:09 -04:00
|
|
|
{showAdditionalOptions && (
|
|
|
|
<Dropdown
|
|
|
|
overlay={
|
|
|
|
<Menu>
|
|
|
|
<Menu.Item key="0">
|
2022-05-05 22:46:45 +02:00
|
|
|
<MenuItem
|
|
|
|
onClick={() => {
|
|
|
|
navigator.clipboard.writeText(pageUrl);
|
|
|
|
message.info('Copied URL!', 1.2);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<LinkOutlined /> Copy Url
|
|
|
|
</MenuItem>
|
|
|
|
</Menu.Item>
|
|
|
|
<Menu.Item key="1">
|
2022-04-22 16:46:09 -04:00
|
|
|
{!entityData?.deprecation?.deprecated ? (
|
|
|
|
<MenuItem onClick={() => setShowAddDeprecationDetailsModal(true)}>
|
2022-05-05 22:46:45 +02:00
|
|
|
<ExclamationCircleOutlined /> Mark as deprecated
|
2022-04-22 16:46:09 -04:00
|
|
|
</MenuItem>
|
|
|
|
) : (
|
|
|
|
<MenuItem onClick={() => handleUpdateDeprecation(false)}>
|
2022-05-05 22:46:45 +02:00
|
|
|
<ExclamationCircleOutlined /> Mark as un-deprecated
|
2022-04-22 16:46:09 -04:00
|
|
|
</MenuItem>
|
|
|
|
)}
|
|
|
|
</Menu.Item>
|
|
|
|
</Menu>
|
|
|
|
}
|
|
|
|
trigger={['click']}
|
|
|
|
>
|
|
|
|
<MenuIcon />
|
|
|
|
</Dropdown>
|
|
|
|
)}
|
|
|
|
</TopButtonsWrapper>
|
|
|
|
{hasExternalUrl && (
|
|
|
|
<Button href={externalUrl} onClick={sendAnalytics}>
|
|
|
|
View in {platformName}
|
|
|
|
<RightOutlined style={{ fontSize: 12 }} />
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</SideHeaderContent>
|
2022-04-16 03:40:44 +05:30
|
|
|
</HeaderContainer>
|
|
|
|
<AddDeprecationDetailsModal
|
|
|
|
visible={showAddDeprecationDetailsModal}
|
|
|
|
urn={urn}
|
|
|
|
onClose={() => {
|
|
|
|
setShowAddDeprecationDetailsModal(false);
|
|
|
|
}}
|
|
|
|
refetch={refetch}
|
|
|
|
/>
|
|
|
|
</>
|
2021-08-31 22:00:56 -07:00
|
|
|
);
|
|
|
|
};
|