Fix misc UI (#9912)

* fix(ui): show displayName instead name for entities

* fix ui improvements #9879

* fix alert details destination title rendering

* fixed failing cy test

Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
This commit is contained in:
Chirag Madlani 2023-01-27 10:13:18 +05:30 committed by GitHub
parent ed062c62d6
commit 788f5ff776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 352 additions and 298 deletions

View File

@ -256,9 +256,10 @@ describe('Alerts page should work properly', () => {
.contains(TEST_CASE.testCaseAlert) .contains(TEST_CASE.testCaseAlert)
.click(); .click();
// Check data asset // Check data asset
cy.get( cy.get('[data-testid="display-name-entities"]').should(
'.ant-row-middle > :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(3)' 'contain',
).should('contain', TEST_CASE.dataAsset); TEST_CASE.dataAsset
);
cy.get('div.ant-typography').should('contain', TEST_CASE.filters); cy.get('div.ant-typography').should('contain', TEST_CASE.filters);
}); });

View File

@ -14,6 +14,10 @@
import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'; import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons';
import Icon from '@ant-design/icons/lib/components/Icon'; import Icon from '@ant-design/icons/lib/components/Icon';
import { Button, Card, Col, Divider, Row, Space, Tag, Typography } from 'antd'; import { Button, Card, Col, Divider, Row, Space, Tag, Typography } from 'antd';
import TitleBreadcrumb from 'components/common/title-breadcrumb/title-breadcrumb.component';
import { TitleBreadcrumbProps } from 'components/common/title-breadcrumb/title-breadcrumb.interface';
import PageHeader from 'components/header/PageHeader.component';
import { HeaderProps } from 'components/header/PageHeader.interface';
import { isArray } from 'lodash'; import { isArray } from 'lodash';
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -38,15 +42,13 @@ import {
getFunctionDisplayName, getFunctionDisplayName,
} from '../../../utils/Alerts/AlertsUtil'; } from '../../../utils/Alerts/AlertsUtil';
import { getHostNameFromURL } from '../../../utils/CommonUtils'; import { getHostNameFromURL } from '../../../utils/CommonUtils';
import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer';
import TitleBreadcrumb from '../../common/title-breadcrumb/title-breadcrumb.component';
import { TitleBreadcrumbProps } from '../../common/title-breadcrumb/title-breadcrumb.interface';
interface AlertDetailsComponentProps { interface AlertDetailsComponentProps {
alerts: Alerts; alerts: Alerts;
alertActions: AlertAction[]; alertActions: AlertAction[];
onDelete: () => void; onDelete: () => void;
breadcrumb: TitleBreadcrumbProps['titleLinks']; pageHeaderData?: HeaderProps['data'];
breadcrumb?: TitleBreadcrumbProps['titleLinks'];
allowDelete?: boolean; allowDelete?: boolean;
allowEdit?: boolean; allowEdit?: boolean;
} }
@ -55,8 +57,9 @@ export const AlertDetailsComponent = ({
alerts, alerts,
alertActions, alertActions,
onDelete, onDelete,
breadcrumb, pageHeaderData,
allowDelete = true, allowDelete = true,
breadcrumb,
allowEdit = true, allowEdit = true,
}: AlertDetailsComponentProps) => { }: AlertDetailsComponentProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -65,7 +68,9 @@ export const AlertDetailsComponent = ({
<Row align="middle" gutter={[16, 16]}> <Row align="middle" gutter={[16, 16]}>
<Col span={24}> <Col span={24}>
<div className="d-flex items-center justify-between"> <div className="d-flex items-center justify-between">
<TitleBreadcrumb titleLinks={breadcrumb} /> {breadcrumb ? <TitleBreadcrumb titleLinks={breadcrumb} /> : null}
{pageHeaderData ? <PageHeader data={pageHeaderData} /> : null}
<Space size={16}> <Space size={16}>
{allowEdit && ( {allowEdit && (
<Link to={`${EDIT_LINK_PATH}/${alerts?.id}`}> <Link to={`${EDIT_LINK_PATH}/${alerts?.id}`}>
@ -86,13 +91,6 @@ export const AlertDetailsComponent = ({
</Col> </Col>
<Col span={24}> <Col span={24}>
<Card> <Card>
{alerts.description && (
<>
<RichTextEditorPreviewer markdown={alerts?.description ?? ''} />
<Divider />
</>
)}
<Space direction="vertical" size={8}> <Space direction="vertical" size={8}>
<Typography.Title className="m-0" level={5}> <Typography.Title className="m-0" level={5}>
{t('label.trigger')} {t('label.trigger')}
@ -103,7 +101,7 @@ export const AlertDetailsComponent = ({
)} )}
: :
</Typography.Text> </Typography.Text>
<Typography.Text> <Typography.Text data-testid="display-name-entities">
{alerts?.triggerConfig.entities {alerts?.triggerConfig.entities
?.map(getDisplayNameForEntities) ?.map(getDisplayNameForEntities)
?.join(', ')} ?.join(', ')}
@ -149,7 +147,18 @@ export const AlertDetailsComponent = ({
)} )}
</Space> </Space>
) : ( ) : (
<Card className="h-full" title={<Space size={8} />}> <Card
className="h-full"
title={
<Space size={16}>
{getAlertsActionTypeIcon(action.alertActionType)}
{getAlertActionTypeDisplayName(
action.alertActionType ??
AlertActionType.GenericWebhook
)}
</Space>
}>
<Space direction="vertical" size={8}> <Space direction="vertical" size={8}>
{action.alertActionType === AlertActionType.Email && ( {action.alertActionType === AlertActionType.Email && (
<> <>

View File

@ -12,6 +12,7 @@
*/ */
import { Button, Typography } from 'antd'; import { Button, Typography } from 'antd';
import { toString } from 'lodash';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { ROUTES } from '../../../constants/constants'; import { ROUTES } from '../../../constants/constants';
@ -43,23 +44,24 @@ const TableDataCardTitle = ({
}: TableDataCardTitleProps) => { }: TableDataCardTitleProps) => {
const isTourRoute = location.pathname.includes(ROUTES.TOUR); const isTourRoute = location.pathname.includes(ROUTES.TOUR);
const testId = useMemo( const { testId, displayName } = useMemo(
() => () => ({
dataTestId testId: dataTestId
? dataTestId ? dataTestId
: `${getPartialNameFromTableFQN(source.fullyQualifiedName ?? '', [ : `${getPartialNameFromTableFQN(source.fullyQualifiedName ?? '', [
FqnPart.Service, FqnPart.Service,
])}-${getNameFromFQN(source.fullyQualifiedName ?? '')}`, ])}-${getNameFromFQN(source.fullyQualifiedName ?? '')}`,
displayName: toString(source.displayName),
}),
[dataTestId, source] [dataTestId, source]
); );
const title = ( const title = (
<Button <Button
data-testid={testId} data-testid={testId}
id={`${id ?? testId}-title`} id={`${id ?? testId}-title`}
type="link" type="link"
onClick={isTourRoute ? handleLinkClick : undefined}> onClick={isTourRoute ? handleLinkClick : undefined}>
{stringToHTML(source.name)} {stringToHTML(displayName)}
</Button> </Button>
); );
@ -72,7 +74,7 @@ const TableDataCardTitle = ({
ellipsis ellipsis
className="m-b-0 text-base" className="m-b-0 text-base"
level={5} level={5}
title={source.name}> title={displayName}>
<Link <Link
className="table-data-card-title-container w-fit-content w-max-90" className="table-data-card-title-container w-fit-content w-max-90"
to={getEntityLink(searchIndex, source.fullyQualifiedName ?? '')}> to={getEntityLink(searchIndex, source.fullyQualifiedName ?? '')}>

View File

@ -13,15 +13,9 @@
import { Typography } from 'antd'; import { Typography } from 'antd';
import React from 'react'; import React from 'react';
import { HeaderProps } from './PageHeader.interface';
import './PageHeader.style.less'; import './PageHeader.style.less';
interface HeaderProps {
data: {
header: string;
subHeader: string;
};
}
const PageHeader = ({ data: { header, subHeader } }: HeaderProps) => { const PageHeader = ({ data: { header, subHeader } }: HeaderProps) => {
return ( return (
<div className="page-header-container"> <div className="page-header-container">

View File

@ -0,0 +1,19 @@
/*
* 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.
*/
export interface HeaderProps {
data: {
header: string;
subHeader: string;
};
}

View File

@ -31,6 +31,7 @@ type Fields =
| 'fullyQualifiedName' | 'fullyQualifiedName'
| 'description' | 'description'
| 'serviceType' | 'serviceType'
| 'displayName'
| 'deleted'; | 'deleted';
export type SourceType = ( export type SourceType = (

View File

@ -12,7 +12,7 @@
*/ */
import classNames from 'classnames'; import classNames from 'classnames';
import { isUndefined } from 'lodash'; import { isUndefined, toString } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import { PAGE_SIZE } from '../../constants/constants'; import { PAGE_SIZE } from '../../constants/constants';
@ -64,7 +64,7 @@ const SearchedData: React.FC<SearchedDataProps> = ({
}); });
} }
let name = table.name; let name = toString(table.displayName);
if (!isUndefined(highlight)) { if (!isUndefined(highlight)) {
name = highlight?.name?.join(' ') || name; name = highlight?.name?.join(' ') || name;
} }

View File

@ -188,6 +188,7 @@
"edit-workflow-ingestion": "Edit {{workflow}} Ingestion", "edit-workflow-ingestion": "Edit {{workflow}} Ingestion",
"edited": "Edited", "edited": "Edited",
"effect": "Effect", "effect": "Effect",
"elastic-search": "Elasticsearch",
"elastic-search-re-index": "ElasticsearchReindex", "elastic-search-re-index": "ElasticsearchReindex",
"email": "Email", "email": "Email",
"email-plural": "Emails", "email-plural": "Emails",
@ -658,6 +659,7 @@
"delete-team-message": "Any teams under \"{{teamName}}\" will be {{deleteType}} deleted as well.", "delete-team-message": "Any teams under \"{{teamName}}\" will be {{deleteType}} deleted as well.",
"delete-webhook-permanently": "You want to delete webhook {{webhookName}} permanently? This action cannot be reverted.", "delete-webhook-permanently": "You want to delete webhook {{webhookName}} permanently? This action cannot be reverted.",
"discover-your-data-and-unlock-the-value-of-data-assets": "Discover your data and unlock the value of data assets.", "discover-your-data-and-unlock-the-value-of-data-assets": "Discover your data and unlock the value of data assets.",
"elastic-search-message": "Manage Elastisearch related works here. You can trigger re-create indexes or check the status of re-creating indexes",
"email-is-invalid": "Invalid Email.", "email-is-invalid": "Invalid Email.",
"enable-column-profile": "Enable column profile", "enable-column-profile": "Enable column profile",
"enable-debug-logging": "Enable debug logging", "enable-debug-logging": "Enable debug logging",

View File

@ -67,13 +67,11 @@ const AlertsActivityFeedPage = () => {
fetchActivityFeedAlert(); fetchActivityFeedAlert();
}, []); }, []);
const breadcrumb = useMemo( const pageHeaderData = useMemo(
() => [ () => ({
{ header: getEntityName(alert),
name: getEntityName(alert), subHeader: alert?.description || '',
url: '', }),
},
],
[alert] [alert]
); );
@ -86,7 +84,7 @@ const AlertsActivityFeedPage = () => {
alertActions={alertActions} alertActions={alertActions}
alerts={alert} alerts={alert}
allowDelete={false} allowDelete={false}
breadcrumb={breadcrumb} pageHeaderData={pageHeaderData}
onDelete={noop} onDelete={noop}
/> />
) : ( ) : (

View File

@ -10,9 +10,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Button, Col, Row, Table, Tooltip, Typography } from 'antd'; import { Button, Col, Row, Table, Tooltip } from 'antd';
import DeleteWidgetModal from 'components/common/DeleteWidget/DeleteWidgetModal'; import DeleteWidgetModal from 'components/common/DeleteWidget/DeleteWidgetModal';
import NextPrevious from 'components/common/next-previous/NextPrevious'; import NextPrevious from 'components/common/next-previous/NextPrevious';
import PageHeader from 'components/header/PageHeader.component';
import Loader from 'components/Loader/Loader'; import Loader from 'components/Loader/Loader';
import { isNil } from 'lodash'; import { isNil } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
@ -131,19 +132,20 @@ const AlertsPage = () => {
[handleAlertDelete] [handleAlertDelete]
); );
const pageHeaderData = useMemo(
() => ({
header: t('label.alert-plural'),
subHeader: t('message.alerts-description'),
}),
[]
);
return ( return (
<> <>
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col span={24}> <Col span={24}>
<div className="d-flex justify-between"> <div className="d-flex justify-between">
<div> <PageHeader data={pageHeaderData} />
<Typography.Title level={5}>
{t('label.alert-plural')}
</Typography.Title>
<Typography.Text>
{t('message.alerts-description')}
</Typography.Text>
</div>
<Link <Link
to={getSettingPath( to={getSettingPath(
GlobalSettingsMenuCategory.NOTIFICATIONS, GlobalSettingsMenuCategory.NOTIFICATIONS,

View File

@ -15,9 +15,11 @@ import { ReloadOutlined } from '@ant-design/icons';
import { Badge, Button, Card, Col, Divider, Row, Space } from 'antd'; import { Badge, Button, Card, Col, Divider, Row, Space } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer'; import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer';
import PageHeader from 'components/header/PageHeader.component';
import { useWebSocketConnector } from 'components/web-scoket/web-scoket.provider'; import { useWebSocketConnector } from 'components/web-scoket/web-scoket.provider';
import { isEmpty, startCase } from 'lodash'; import { isEmpty, startCase } from 'lodash';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { import {
getAllReIndexStatus, getAllReIndexStatus,
reIndexByPublisher, reIndexByPublisher,
@ -41,6 +43,7 @@ import './ElasticSearchReIndex.style.less';
import ReIndexAllModal from './ElasticSearchReIndexModal.component'; import ReIndexAllModal from './ElasticSearchReIndexModal.component';
const ElasticSearchIndexPage = () => { const ElasticSearchIndexPage = () => {
const { t } = useTranslation();
const [batchJobData, setBatchJobData] = useState<EventPublisherJob>(); const [batchJobData, setBatchJobData] = useState<EventPublisherJob>();
const [streamJobData, setStreamJobData] = useState<EventPublisherJob>(); const [streamJobData, setStreamJobData] = useState<EventPublisherJob>();
@ -128,253 +131,271 @@ const ElasticSearchIndexPage = () => {
}, []); }, []);
return ( return (
<div> <Row align="middle" gutter={[16, 16]}>
<Row gutter={[16, 16]}> <Col span={24}>
<Col span={24}> <PageHeader
<Card data={{
extra={ header: t('label.elastic-search'),
<Space> subHeader: t('message.elastic-search-message'),
<Button }}
data-testid="elastic-search-re-fetch-data" />
disabled={batchLoading} </Col>
icon={<ReloadOutlined />} <Col span={24}>
size="small" <div>
title="Refresh log" <Row gutter={[16, 16]}>
onClick={fetchBatchReIndexedData} <Col span={24}>
/> <Card
<Button extra={
data-testid="elastic-search-re-index-all" <Space>
disabled={!isAdminUser} <Button
size="small" data-testid="elastic-search-re-fetch-data"
type="primary" disabled={batchLoading}
onClick={() => setModalOpen(true)}> icon={<ReloadOutlined />}
Re Index All size="small"
</Button> title="Refresh log"
</Space> onClick={fetchBatchReIndexedData}
} />
loading={batchLoading} <Button
size="small" data-testid="elastic-search-re-index-all"
title="ElasticSearch"> disabled={!isAdminUser}
<Row gutter={[16, 8]}> size="small"
<Col span={24}> type="primary"
<Space wrap direction="horizontal" size={0}> onClick={() => setModalOpen(true)}>
<div className="flex"> Re Index All
<span className="text-grey-muted">Mode</span> : </Button>
<span className="m-l-xs"> </Space>
{startCase(batchJobData?.runMode) || '--'} }
</span> loading={batchLoading}
</div> size="small"
<Divider type="vertical" /> title="ElasticSearch">
<div className="flex"> <Row gutter={[16, 8]}>
<span className="text-grey-muted">Status</span> : <Col span={24}>
<span className="m-l-xs"> <Space wrap direction="horizontal" size={0}>
<Space size={8}> <div className="flex">
{batchJobData?.status && ( <span className="text-grey-muted">Mode</span> :
<SVGIcons <span className="m-l-xs">
alt="result" {startCase(batchJobData?.runMode) || '--'}
className="w-4"
icon={getStatusResultBadgeIcon(
batchJobData?.status
)}
/>
)}
<span>
{getEventPublisherStatusText(batchJobData?.status) ||
'--'}
</span> </span>
</Space> </div>
</span> <Divider type="vertical" />
</div> <div className="flex">
<Divider type="vertical" /> <span className="text-grey-muted">Status</span> :
<div className="flex"> <span className="m-l-xs">
<span className="text-grey-muted">Index stats</span> : <Space size={8}>
{batchJobData?.status && (
<SVGIcons
alt="result"
className="w-4"
icon={getStatusResultBadgeIcon(
batchJobData?.status
)}
/>
)}
<span>
{getEventPublisherStatusText(
batchJobData?.status
) || '--'}
</span>
</Space>
</span>
</div>
<Divider type="vertical" />
<div className="flex">
<span className="text-grey-muted">Index stats</span> :
<span className="m-l-xs">
{!isEmpty(batchJobData) ? (
<Space size={8}>
<Badge
className="request-badge running"
count={batchJobData?.stats?.total}
overflowCount={99999999}
title={`Total index sent: ${batchJobData?.stats?.total}`}
/>
<Badge
className="request-badge success"
count={batchJobData?.stats?.success}
overflowCount={99999999}
title={`Success index: ${batchJobData?.stats?.success}`}
/>
<Badge
showZero
className="request-badge failed"
count={batchJobData?.stats?.failed}
overflowCount={99999999}
title={`Failed index: ${batchJobData?.stats?.failed}`}
/>
</Space>
) : (
'--'
)}
</span>
</div>
<Divider type="vertical" />
<div className="flex">
<span className="text-grey-muted">Last Updated</span> :
<span className="m-l-xs">
{batchJobData?.timestamp
? getDateTimeByTimeStampWithZone(
batchJobData?.timestamp
)
: '--'}
</span>
</div>
<Divider type="vertical" />
<div className="flex">
<span className="text-grey-muted">Last Failed At:</span>
<p className="m-l-xs">
{batchJobData?.failureDetails?.lastFailedAt
? getDateTimeByTimeStampWithZone(
batchJobData?.failureDetails?.lastFailedAt
)
: '--'}
</p>
</div>
</Space>
</Col>
<Col span={24}>
<span className="text-grey-muted">Failure Context:</span>
<span className="m-l-xs"> <span className="m-l-xs">
{!isEmpty(batchJobData) ? ( {batchJobData?.failureDetails?.context ? (
<Space size={8}> <RichTextEditorPreviewer
<Badge enableSeeMoreVariant={Boolean(batchJobData)}
className="request-badge running" markdown={batchJobData?.failureDetails?.context}
count={batchJobData?.stats?.total} />
overflowCount={99999999}
title={`Total index sent: ${batchJobData?.stats?.total}`}
/>
<Badge
className="request-badge success"
count={batchJobData?.stats?.success}
overflowCount={99999999}
title={`Success index: ${batchJobData?.stats?.success}`}
/>
<Badge
showZero
className="request-badge failed"
count={batchJobData?.stats?.failed}
overflowCount={99999999}
title={`Failed index: ${batchJobData?.stats?.failed}`}
/>
</Space>
) : ( ) : (
'--' '--'
)} )}
</span> </span>
</div> </Col>
<Divider type="vertical" /> <Col span={24}>
<div className="flex"> <span className="text-grey-muted">Last error:</span>
<span className="text-grey-muted">Last Updated</span> :
<span className="m-l-xs"> <span className="m-l-xs">
{batchJobData?.timestamp {batchJobData?.failureDetails?.lastFailedReason ? (
? getDateTimeByTimeStampWithZone( <RichTextEditorPreviewer
batchJobData?.timestamp enableSeeMoreVariant={Boolean(batchJobData)}
) markdown={
: '--'} batchJobData?.failureDetails?.lastFailedReason
}
/>
) : (
'--'
)}
</span> </span>
</div> </Col>
<Divider type="vertical" /> </Row>
<div className="flex"> </Card>
<span className="text-grey-muted">Last Failed At:</span> </Col>
<p className="m-l-xs"> <Col span={24}>
{batchJobData?.failureDetails?.lastFailedAt <Card
? getDateTimeByTimeStampWithZone( extra={
batchJobData?.failureDetails?.lastFailedAt <Button
) data-testid="elastic-search-re-fetch-data"
: '--'} disabled={streamLoading}
</p> icon={<ReloadOutlined />}
</div> size="small"
</Space> title="Refresh log"
</Col> onClick={fetchStreamReIndexedData}
<Col span={24}> />
<span className="text-grey-muted">Failure Context:</span> }
<span className="m-l-xs"> loading={streamLoading}
{batchJobData?.failureDetails?.context ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={Boolean(batchJobData)}
markdown={batchJobData?.failureDetails?.context}
/>
) : (
'--'
)}
</span>
</Col>
<Col span={24}>
<span className="text-grey-muted">Last error:</span>
<span className="m-l-xs">
{batchJobData?.failureDetails?.lastFailedReason ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={Boolean(batchJobData)}
markdown={batchJobData?.failureDetails?.lastFailedReason}
/>
) : (
'--'
)}
</span>
</Col>
</Row>
</Card>
</Col>
<Col span={24}>
<Card
extra={
<Button
data-testid="elastic-search-re-fetch-data"
disabled={streamLoading}
icon={<ReloadOutlined />}
size="small" size="small"
title="Refresh log" title="ElasticSearch">
onClick={fetchStreamReIndexedData} <Row gutter={[16, 8]}>
/> <Col span={24}>
} <Space direction="horizontal" size={16}>
loading={streamLoading} <div className="flex">
size="small" <span className="text-grey-muted">Mode</span> :
title="ElasticSearch"> <span className="m-l-xs">
<Row gutter={[16, 8]}> {startCase(streamJobData?.runMode) || '--'}
<Col span={24}>
<Space direction="horizontal" size={16}>
<div className="flex">
<span className="text-grey-muted">Mode</span> :
<span className="m-l-xs">
{startCase(streamJobData?.runMode) || '--'}
</span>
</div>
<div className="flex">
<span className="text-grey-muted">Status</span> :
<span className="m-l-xs">
<Space size={8}>
{streamJobData?.status && (
<SVGIcons
alt="result"
className="w-4"
icon={getStatusResultBadgeIcon(
streamJobData?.status
)}
/>
)}
<span>
{getEventPublisherStatusText(streamJobData?.status) ||
'--'}
</span> </span>
</Space> </div>
</span> <div className="flex">
</div> <span className="text-grey-muted">Status</span> :
<span className="m-l-xs">
<Space size={8}>
{streamJobData?.status && (
<SVGIcons
alt="result"
className="w-4"
icon={getStatusResultBadgeIcon(
streamJobData?.status
)}
/>
)}
<span>
{getEventPublisherStatusText(
streamJobData?.status
) || '--'}
</span>
</Space>
</span>
</div>
<div className="flex"> <div className="flex">
<span className="text-grey-muted">Last Updated</span> : <span className="text-grey-muted">Last Updated</span> :
<span className="m-l-xs">
{streamJobData?.timestamp
? getDateTimeByTimeStampWithZone(
streamJobData?.timestamp
)
: '--'}
</span>
</div>
<div className="flex">
<span className="text-grey-muted">Last Failed At:</span>
<p className="m-l-xs">
{streamJobData?.failureDetails?.lastFailedAt
? getDateTimeByTimeStampWithZone(
streamJobData?.failureDetails?.lastFailedAt
)
: '--'}
</p>
</div>
</Space>
</Col>
<Col span={24}>
<span className="text-grey-muted">Failure Context:</span>
<span className="m-l-xs"> <span className="m-l-xs">
{streamJobData?.timestamp {streamJobData?.failureDetails?.context ? (
? getDateTimeByTimeStampWithZone( <RichTextEditorPreviewer
streamJobData?.timestamp enableSeeMoreVariant={Boolean(streamJobData)}
) markdown={streamJobData?.failureDetails?.context}
: '--'} />
) : (
'--'
)}
</span> </span>
</div> </Col>
<div className="flex"> <Col span={24}>
<span className="text-grey-muted">Last Failed At:</span> <span className="text-grey-muted">Last error:</span>
<p className="m-l-xs"> <span className="m-l-xs">
{streamJobData?.failureDetails?.lastFailedAt {streamJobData?.failureDetails?.lastFailedReason ? (
? getDateTimeByTimeStampWithZone( <RichTextEditorPreviewer
streamJobData?.failureDetails?.lastFailedAt enableSeeMoreVariant={Boolean(streamJobData)}
) markdown={
: '--'} streamJobData?.failureDetails?.lastFailedReason
</p> }
</div> />
</Space> ) : (
</Col> '--'
<Col span={24}> )}
<span className="text-grey-muted">Failure Context:</span> </span>
<span className="m-l-xs"> </Col>
{streamJobData?.failureDetails?.context ? ( </Row>
<RichTextEditorPreviewer </Card>
enableSeeMoreVariant={Boolean(streamJobData)} </Col>
markdown={streamJobData?.failureDetails?.context} </Row>
/> <ReIndexAllModal
) : ( confirmLoading={confirmLoading}
'--' visible={isModalOpen}
)} onCancel={() => setModalOpen(false)}
</span> onSave={performReIndexAll}
</Col> />
<Col span={24}> </div>
<span className="text-grey-muted">Last error:</span> </Col>
<span className="m-l-xs"> </Row>
{streamJobData?.failureDetails?.lastFailedReason ? (
<RichTextEditorPreviewer
enableSeeMoreVariant={Boolean(streamJobData)}
markdown={streamJobData?.failureDetails?.lastFailedReason}
/>
) : (
'--'
)}
</span>
</Col>
</Row>
</Card>
</Col>
</Row>
<ReIndexAllModal
confirmLoading={confirmLoading}
visible={isModalOpen}
onCancel={() => setModalOpen(false)}
onSave={performReIndexAll}
/>
</div>
); );
}; };

View File

@ -87,11 +87,11 @@ const GlossaryLeftPanel = ({ glossaries }: GlossaryLeftPanelProps) => {
return ( return (
<LeftPanelCard id="glossary"> <LeftPanelCard id="glossary">
<GlossaryV1Skeleton loading={glossaries.length === 0}> <GlossaryV1Skeleton loading={glossaries.length === 0}>
<Row className="m-t-sm" gutter={[0, 16]}> <Row className="p-y-xs" gutter={[0, 16]}>
<Col className="p-x-sm" span={24}> <Col className="p-x-sm" span={24}>
<Typography.Paragraph className="m-b-0"> <Typography.Text strong className="m-b-0">
{t('label.glossary')} {t('label.glossary')}
</Typography.Paragraph> </Typography.Text>
</Col> </Col>
<Col className="p-x-sm" span={24}> <Col className="p-x-sm" span={24}>
<Searchbar <Searchbar
@ -113,12 +113,10 @@ const GlossaryLeftPanel = ({ glossaries }: GlossaryLeftPanelProps) => {
: t('message.no-permission-for-action') : t('message.no-permission-for-action')
}> }>
<Button <Button
ghost className="w-full flex-center gap-2 text-primary"
className="w-full flex-center gap-2"
data-testid="add-glossary" data-testid="add-glossary"
disabled={!createGlossaryPermission} disabled={!createGlossaryPermission}
icon={<PlusIcon />} icon={<PlusIcon />}
type="primary"
onClick={handleAddGlossaryClick}> onClick={handleAddGlossaryClick}>
{t('label.add-glossary')} {t('label.add-glossary')}
</Button> </Button>

View File

@ -804,12 +804,11 @@ const TagsPage = () => {
</Row> </Row>
) : ( ) : (
<Space> <Space>
<Typography.Title <Typography.Text
className="m-b-0" className="m-b-0 font-bold text-lg"
data-testid="classification-name" data-testid="classification-name">
level={5}>
{getEntityName(currentClassification)} {getEntityName(currentClassification)}
</Typography.Title> </Typography.Text>
{currentClassification.provider === ProviderType.User && ( {currentClassification.provider === ProviderType.User && (
<Tooltip <Tooltip
title={ title={
@ -886,7 +885,7 @@ const TagsPage = () => {
</div> </div>
</Space> </Space>
)} )}
<div className="m-b-sm" data-testid="description-container"> <div className="m-b-sm m-t-xs" data-testid="description-container">
<Description <Description
description={currentClassification?.description || ''} description={currentClassification?.description || ''}
entityName={ entityName={

View File

@ -14,3 +14,6 @@
.overflow-y-auto { .overflow-y-auto {
overflow-y: auto; overflow-y: auto;
} }
.min-h-24 {
min-height: 6rem;
}

View File

@ -71,7 +71,7 @@ export const StyledCard = ({
subHeading: string; subHeading: string;
}) => { }) => {
return ( return (
<div className="bg-grey p-sm rounded-4"> <div className="bg-grey p-sm rounded-4 min-h-24">
<Typography.Text>{heading}</Typography.Text> <Typography.Text>{heading}</Typography.Text>
<br /> <br />
<Typography.Text className="text-xs text-grey-muted"> <Typography.Text className="text-xs text-grey-muted">

View File

@ -278,7 +278,12 @@ export const getGlobalSettingMenuItem = (
icon, icon,
children: subItems, children: subItems,
label: isBeta ? ( label: isBeta ? (
<Badge color="#7147e8" count="beta" offset={[30, 8]} size="small"> <Badge
className="text-xs text-grey-muted"
color="#7147e8"
count="beta"
offset={[30, 8]}
size="small">
{label} {label}
</Badge> </Badge>
) : ( ) : (