mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 08:50:18 +00:00
* supported entity stats table in searchindex application history logs * localization keys * changes due to total records * added test around appLogsViewer and fix sonar issue
This commit is contained in:
parent
7eeb0e45d2
commit
7d24cb5164
@ -11,16 +11,33 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Badge, Button, Card, Col, Divider, Row, Space } from 'antd';
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
Divider,
|
||||
Row,
|
||||
Space,
|
||||
Table,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { isNil } from 'lodash';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LazyLog } from 'react-lazylog';
|
||||
import { ReactComponent as IconSuccessBadge } from '../../../../assets/svg/success-badge.svg';
|
||||
import { getEntityStatsData } from '../../../../utils/ApplicationUtils';
|
||||
import { formatDateTimeWithTimezone } from '../../../../utils/date-time/DateTimeUtils';
|
||||
import { formatJsonString } from '../../../../utils/StringsUtils';
|
||||
import AppBadge from '../../../common/Badge/Badge.component';
|
||||
import CopyToClipboardButton from '../../../common/CopyToClipboardButton/CopyToClipboardButton';
|
||||
import { AppLogsViewerProps, JobStats } from './AppLogsViewer.interface';
|
||||
import './app-logs-viewer.less';
|
||||
import {
|
||||
AppLogsViewerProps,
|
||||
EntityStats,
|
||||
JobStats,
|
||||
} from './AppLogsViewer.interface';
|
||||
|
||||
const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
||||
const { t } = useTranslation();
|
||||
@ -96,6 +113,7 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
||||
<span className="m-l-xs">
|
||||
<Space size={8}>
|
||||
<Badge
|
||||
showZero
|
||||
className="request-badge running"
|
||||
count={jobStats.totalRecords}
|
||||
overflowCount={99999999}
|
||||
@ -105,6 +123,7 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
||||
/>
|
||||
|
||||
<Badge
|
||||
showZero
|
||||
className="request-badge success"
|
||||
count={jobStats.successRecords}
|
||||
overflowCount={99999999}
|
||||
@ -142,10 +161,108 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
||||
[timestamp, formatDateTimeWithTimezone]
|
||||
);
|
||||
|
||||
const tableColumn = useMemo(() => {
|
||||
const entityTotalJobStatsData =
|
||||
successContext?.stats.jobStats || failureContext?.stats.jobStats;
|
||||
|
||||
return [
|
||||
{
|
||||
title: t('label.name'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<div className="d-flex items-center">
|
||||
<Typography.Text>
|
||||
{t('label.entity-record-plural', {
|
||||
entity: t('label.total'),
|
||||
})}{' '}
|
||||
</Typography.Text>
|
||||
<AppBadge
|
||||
className="entity-stats total m-l-sm"
|
||||
label={entityTotalJobStatsData.totalRecords}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
dataIndex: 'totalRecords',
|
||||
key: 'totalRecords',
|
||||
render: (text: string) => (
|
||||
<Typography.Text className="text-primary">{text}</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<div className="d-flex items-center">
|
||||
<Typography.Text>
|
||||
{t('label.entity-record-plural', {
|
||||
entity: t('label.success'),
|
||||
})}{' '}
|
||||
</Typography.Text>
|
||||
<AppBadge
|
||||
className="entity-stats success m-l-sm"
|
||||
label={entityTotalJobStatsData.successRecords}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
dataIndex: 'successRecords',
|
||||
key: 'successRecords',
|
||||
render: (text: string) => (
|
||||
<Typography.Text className="text-success">{text}</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<div className="d-flex items-center">
|
||||
<Typography.Text>
|
||||
{t('label.entity-record-plural', {
|
||||
entity: t('label.failed'),
|
||||
})}{' '}
|
||||
</Typography.Text>
|
||||
<AppBadge
|
||||
className="entity-stats failure m-l-sm"
|
||||
label={entityTotalJobStatsData.failedRecords}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
dataIndex: 'failedRecords',
|
||||
key: 'failedRecords',
|
||||
render: (text: string) => (
|
||||
<Typography.Text className="text-failure">{text}</Typography.Text>
|
||||
),
|
||||
},
|
||||
];
|
||||
}, [successContext, failureContext]);
|
||||
|
||||
const entityStatsRenderer = useCallback(
|
||||
(entityStats: EntityStats) => {
|
||||
return (
|
||||
<Table
|
||||
bordered
|
||||
className="m-t-md"
|
||||
columns={tableColumn}
|
||||
data-testid="app-entity-stats-history-table"
|
||||
dataSource={getEntityStatsData(entityStats)}
|
||||
pagination={false}
|
||||
rowKey="name"
|
||||
scroll={{ y: 200 }}
|
||||
size="small"
|
||||
/>
|
||||
);
|
||||
},
|
||||
[tableColumn]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{successContext?.stats && statsRender(successContext?.stats.jobStats)}
|
||||
{failureContext?.stats && statsRender(failureContext?.stats.jobStats)}
|
||||
|
||||
{successContext?.stats?.entityStats &&
|
||||
entityStatsRenderer(successContext.stats.entityStats)}
|
||||
{failureContext?.stats?.entityStats &&
|
||||
entityStatsRenderer(failureContext.stats.entityStats)}
|
||||
|
||||
{logsRender(
|
||||
formatJsonString(
|
||||
JSON.stringify(
|
||||
|
@ -11,15 +11,52 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EntityType } from '../../../../enums/entity.enum';
|
||||
import { AppRunRecord } from '../../../../generated/entity/applications/appRunRecord';
|
||||
|
||||
export interface AppLogsViewerProps {
|
||||
data: AppRunRecord;
|
||||
}
|
||||
|
||||
export interface JobStats {
|
||||
totalRecords: string;
|
||||
successRecords: string;
|
||||
failedRecords: string;
|
||||
export interface TotalRecords {
|
||||
totalRecords: number;
|
||||
successRecords: number;
|
||||
failedRecords: number;
|
||||
}
|
||||
export interface JobStats extends TotalRecords {
|
||||
processedRecords: string;
|
||||
}
|
||||
|
||||
export type EntityTypeSearchIndex = Exclude<
|
||||
EntityType,
|
||||
| EntityType.BOT
|
||||
| EntityType.ALERT
|
||||
| EntityType.knowledgePanels
|
||||
| EntityType.WEBHOOK
|
||||
| EntityType.USER
|
||||
| EntityType.ROLE
|
||||
| EntityType.TEAM
|
||||
| EntityType.SUBSCRIPTION
|
||||
| EntityType.POLICY
|
||||
| EntityType.DATA_INSIGHT_CHART
|
||||
| EntityType.KPI
|
||||
| EntityType.TYPE
|
||||
| EntityType.APP_MARKET_PLACE_DEFINITION
|
||||
| EntityType.APPLICATION
|
||||
| EntityType.PERSONA
|
||||
| EntityType.DOC_STORE
|
||||
| EntityType.PAGE
|
||||
| EntityType.SAMPLE_DATA
|
||||
| EntityType.GOVERN
|
||||
| EntityType.CUSTOM_METRIC
|
||||
| EntityType.ALL
|
||||
>;
|
||||
|
||||
export type EntityStats = Record<EntityTypeSearchIndex, TotalRecords>;
|
||||
|
||||
export interface EntityStatsData {
|
||||
name: string;
|
||||
totalRecords: number;
|
||||
successRecords: number;
|
||||
failedRecords: number;
|
||||
}
|
||||
|
@ -39,6 +39,23 @@ jest.mock('antd', () => ({
|
||||
Badge: jest.fn().mockReturnValue(<div>Badge</div>),
|
||||
}));
|
||||
|
||||
jest.mock('../../../../utils/ApplicationUtils', () => ({
|
||||
getEntityStatsData: jest.fn().mockReturnValue([
|
||||
{
|
||||
name: 'chart',
|
||||
totalRecords: 100,
|
||||
failedRecords: 10,
|
||||
successRecords: 90,
|
||||
},
|
||||
]),
|
||||
}));
|
||||
|
||||
jest.mock('../../../common/Badge/Badge.component', () =>
|
||||
jest.fn().mockImplementation(({ label }) => {
|
||||
return <div data-testid="app-badge">{`${label}-AppBadge`}</div>;
|
||||
})
|
||||
);
|
||||
|
||||
const mockProps1 = {
|
||||
data: {
|
||||
appId: '6e4d3dcf-238d-4874-b4e4-dd863ede6544',
|
||||
@ -54,7 +71,6 @@ const mockProps1 = {
|
||||
failedRecords: 0,
|
||||
successRecords: 274,
|
||||
},
|
||||
entityStats: {},
|
||||
},
|
||||
},
|
||||
scheduleInfo: {
|
||||
@ -77,7 +93,51 @@ const mockProps2 = {
|
||||
failedRecords: 0,
|
||||
successRecords: 274,
|
||||
},
|
||||
entityStats: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockProps3 = {
|
||||
data: {
|
||||
...mockProps1.data,
|
||||
successContext: {
|
||||
stats: {
|
||||
jobStats: {
|
||||
totalRecords: 274,
|
||||
failedRecords: 4,
|
||||
successRecords: 270,
|
||||
},
|
||||
entityStats: {
|
||||
chart: {
|
||||
totalRecords: 100,
|
||||
failedRecords: 10,
|
||||
successRecords: 90,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockProps4 = {
|
||||
data: {
|
||||
...mockProps1.data,
|
||||
successContext: undefined,
|
||||
failureContext: {
|
||||
stats: {
|
||||
jobStats: {
|
||||
totalRecords: 274,
|
||||
failedRecords: 4,
|
||||
successRecords: 270,
|
||||
},
|
||||
entityStats: {
|
||||
chart: {
|
||||
totalRecords: 100,
|
||||
failedRecords: 10,
|
||||
successRecords: 90,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -105,4 +165,50 @@ describe('AppLogsViewer component', () => {
|
||||
expect(screen.getByText('--')).toBeInTheDocument();
|
||||
// Note: not asserting other elements as for failure also same elements will render
|
||||
});
|
||||
|
||||
it("should not render entity stats table based if successContext doesn't have data", () => {
|
||||
render(<AppLogsViewer {...mockProps1} />);
|
||||
|
||||
expect(
|
||||
screen.queryByTestId('app-entity-stats-history-table')
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render entity stats table based if SuccessContext has data', () => {
|
||||
render(<AppLogsViewer {...mockProps3} />);
|
||||
|
||||
expect(
|
||||
screen.getByTestId('app-entity-stats-history-table')
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('label.name')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getAllByTestId('app-badge')).toHaveLength(3);
|
||||
expect(screen.getByText('274-AppBadge')).toBeInTheDocument();
|
||||
expect(screen.getByText('270-AppBadge')).toBeInTheDocument();
|
||||
expect(screen.getByText('4-AppBadge')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should not render entity stats table based if failedContext doesn't have data", () => {
|
||||
render(<AppLogsViewer {...mockProps2} />);
|
||||
|
||||
expect(
|
||||
screen.queryByTestId('app-entity-stats-history-table')
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render entity stats table based if failedContext has data', () => {
|
||||
render(<AppLogsViewer {...mockProps4} />);
|
||||
|
||||
expect(
|
||||
screen.getByTestId('app-entity-stats-history-table')
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('label.name')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getAllByTestId('app-badge')).toHaveLength(3);
|
||||
expect(screen.getByText('274-AppBadge')).toBeInTheDocument();
|
||||
expect(screen.getByText('270-AppBadge')).toBeInTheDocument();
|
||||
expect(screen.getByText('4-AppBadge')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
@import (reference) url('../../../../styles/variables.less');
|
||||
|
||||
.entity-stats {
|
||||
width: max-content;
|
||||
|
||||
.ant-typography {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&.total {
|
||||
background-color: @primary-color-hover;
|
||||
border: 1px solid @primary-color;
|
||||
.ant-typography {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
&.success {
|
||||
background-color: @green-2;
|
||||
border: 1px solid @success-color;
|
||||
.ant-typography {
|
||||
color: @success-color;
|
||||
}
|
||||
}
|
||||
&.failure {
|
||||
background-color: @error-light-color;
|
||||
border: 1px solid @failed-color;
|
||||
.ant-typography {
|
||||
color: @failed-color;
|
||||
}
|
||||
}
|
||||
}
|
@ -152,7 +152,7 @@ const AppRunsHistory = forwardRef(
|
||||
return NO_DATA_PLACEHOLDER;
|
||||
}
|
||||
},
|
||||
[showLogAction, appData, isExternalApp]
|
||||
[showLogAction, appData, isExternalApp, handleRowExpandable]
|
||||
);
|
||||
|
||||
const tableColumn: ColumnsType<AppRunRecordWithId> = useMemo(
|
||||
|
@ -63,6 +63,9 @@ export enum EntityType {
|
||||
CUSTOM_METRIC = 'customMetric',
|
||||
INGESTION_PIPELINE = 'ingestionPipeline',
|
||||
QUERY = 'query',
|
||||
ENTITY_REPORT_DATA = 'entityReportData',
|
||||
WEB_ANALYTIC_ENTITY_VIEW_REPORT_DATA = 'webAnalyticEntityViewReportData',
|
||||
WEB_ANALYTIC_USER_ACTIVITY_REPORT_DATA = 'webAnalyticUserActivityReportData',
|
||||
}
|
||||
|
||||
export enum AssetsType {
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}}-Name",
|
||||
"entity-plural": "Entitäten",
|
||||
"entity-proportion": "{{entity}}-Anteil",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "{{entity}}-Dienst",
|
||||
"entity-type-plural": "{{entity}}-Typen",
|
||||
"entity-version-detail-plural": "Details zu {{entity}}-Versionen",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "themen",
|
||||
"topic-name": "Themenname",
|
||||
"topic-plural": "Themen",
|
||||
"total": "Total",
|
||||
"total-entity": "Gesamte {{entity}}",
|
||||
"total-index-sent": "Gesamtindex gesendet",
|
||||
"tour": "Tour",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}} Name",
|
||||
"entity-plural": "Entities",
|
||||
"entity-proportion": "{{entity}} Proportion",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "{{entity}} Service",
|
||||
"entity-type-plural": "{{entity}} Type",
|
||||
"entity-version-detail-plural": "{{entity}} Version Details",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "topics",
|
||||
"topic-name": "Topic Name",
|
||||
"topic-plural": "Topics",
|
||||
"total": "Total",
|
||||
"total-entity": "Total {{entity}}",
|
||||
"total-index-sent": " Total index sent",
|
||||
"tour": "Tour",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "Nombre de {{entity}}",
|
||||
"entity-plural": "Entidades",
|
||||
"entity-proportion": "Proporción de {{entity}}",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "Servicio de {{entity}}",
|
||||
"entity-type-plural": "Tipo de {{entity}}",
|
||||
"entity-version-detail-plural": "Detalles de versión de {{entity}}",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "topics",
|
||||
"topic-name": "Nombre del Topic",
|
||||
"topic-plural": "Topics",
|
||||
"total": "Total",
|
||||
"total-entity": "Total de {{entity}}",
|
||||
"total-index-sent": "Total de índices enviados",
|
||||
"tour": "Recorrido",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "Nom de {{entity}}",
|
||||
"entity-plural": "Entités",
|
||||
"entity-proportion": "Proportion de {{entity}}",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "Service de {{entity}}",
|
||||
"entity-type-plural": "{{entity}} Types",
|
||||
"entity-version-detail-plural": "Détails des Versions de {{entity}}",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "sujets",
|
||||
"topic-name": "Nom du Sujet",
|
||||
"topic-plural": "Sujets",
|
||||
"total": "Total",
|
||||
"total-entity": "Total {{entity}}",
|
||||
"total-index-sent": "Total d'Index Envoyés",
|
||||
"tour": "Visite",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "שם {{entity}}",
|
||||
"entity-plural": "ישויות",
|
||||
"entity-proportion": "יחס {{entity}}",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "שירות {{entity}}",
|
||||
"entity-type-plural": "סוגי {{entity}}",
|
||||
"entity-version-detail-plural": "גרסאות פרטי {{entity}}",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "שירותי סטרים",
|
||||
"topic-name": "שם הסטרים",
|
||||
"topic-plural": "שירותי סטרים",
|
||||
"total": "Total",
|
||||
"total-entity": "סך הכל {{entity}}",
|
||||
"total-index-sent": "סך הכל שלח אינדקס",
|
||||
"tour": "סיור",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}} 名",
|
||||
"entity-plural": "エンティティ",
|
||||
"entity-proportion": "{{entity}} Proportion",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "{{entity}}サービス",
|
||||
"entity-type-plural": "{{entity}} Type",
|
||||
"entity-version-detail-plural": "{{entity}} Version Details",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "topics",
|
||||
"topic-name": "トピック名",
|
||||
"topic-plural": "トピック",
|
||||
"total": "Total",
|
||||
"total-entity": "合計 {{entity}}",
|
||||
"total-index-sent": " Total index sent",
|
||||
"tour": "ツアー",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}}-naam",
|
||||
"entity-plural": "Entiteiten",
|
||||
"entity-proportion": "{{entity}}-verhouding",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "{{entity}}-service",
|
||||
"entity-type-plural": "{{entity}}-type",
|
||||
"entity-version-detail-plural": "{{entity}}-versie-details",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "onderwerpen",
|
||||
"topic-name": "Onderwerpnaam",
|
||||
"topic-plural": "Onderwerpen",
|
||||
"total": "Total",
|
||||
"total-entity": "{{entity}} totaal",
|
||||
"total-index-sent": "Index verzonden totaal",
|
||||
"tour": "Rondleiding",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "Nome de {{entity}}",
|
||||
"entity-plural": "Entidades",
|
||||
"entity-proportion": "Proporção de {{entity}}",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "Serviço de {{entity}}",
|
||||
"entity-type-plural": "Tipo de {{entity}}",
|
||||
"entity-version-detail-plural": "Detalhes da Versão de {{entity}}",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "tópicos",
|
||||
"topic-name": "Nome do Tópico",
|
||||
"topic-plural": "Tópicos",
|
||||
"total": "Total",
|
||||
"total-entity": "Total de {{entity}}",
|
||||
"total-index-sent": " Total de índice enviado",
|
||||
"tour": "Tour",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}} Имя",
|
||||
"entity-plural": "Сущности",
|
||||
"entity-proportion": "Доля \"{{entity}}\"",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "Сервис {{entity}}",
|
||||
"entity-type-plural": "Тип {{entity}}",
|
||||
"entity-version-detail-plural": "{{entity}} Version Details",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "топики",
|
||||
"topic-name": "Наименование темы",
|
||||
"topic-plural": "Топики",
|
||||
"total": "Total",
|
||||
"total-entity": "Все {{entity}}",
|
||||
"total-index-sent": "Все индексы отправлены",
|
||||
"tour": "Руководство пользователя",
|
||||
|
@ -412,6 +412,7 @@
|
||||
"entity-name": "{{entity}}名称",
|
||||
"entity-plural": "实体",
|
||||
"entity-proportion": "{{entity}}比例",
|
||||
"entity-record-plural": "{{entity}} Records",
|
||||
"entity-service": "{{entity}}服务",
|
||||
"entity-type-plural": "{{entity}}类型",
|
||||
"entity-version-detail-plural": "{{entity}}版本详情",
|
||||
@ -1148,6 +1149,7 @@
|
||||
"topic-lowercase-plural": "消息主题",
|
||||
"topic-name": "消息主题名称",
|
||||
"topic-plural": "消息主题",
|
||||
"total": "Total",
|
||||
"total-entity": "所有{{entity}}",
|
||||
"total-index-sent": "已发送的索引",
|
||||
"tour": "导览",
|
||||
|
@ -68,6 +68,10 @@
|
||||
|
||||
&:last-child td {
|
||||
border-bottom: none;
|
||||
|
||||
td {
|
||||
border-bottom: 1px solid @border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
thead > tr {
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
|
||||
import { getEntityStatsData } from './ApplicationUtils';
|
||||
import {
|
||||
MOCK_APPLICATION_ENTITY_STATS,
|
||||
MOCK_APPLICATION_ENTITY_STATS_DATA,
|
||||
} from './mocks/ApplicationUtils.mock';
|
||||
|
||||
describe('ApplicationUtils tests', () => {
|
||||
it('getEntityStatsData should return stats data in array', () => {
|
||||
const resultData = getEntityStatsData(MOCK_APPLICATION_ENTITY_STATS);
|
||||
|
||||
expect(resultData).toEqual(MOCK_APPLICATION_ENTITY_STATS_DATA);
|
||||
});
|
||||
});
|
@ -11,6 +11,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { StatusType } from '../components/common/StatusBadge/StatusBadge.interface';
|
||||
import {
|
||||
EntityStats,
|
||||
EntityStatsData,
|
||||
EntityTypeSearchIndex,
|
||||
} from '../components/Settings/Applications/AppLogsViewer/AppLogsViewer.interface';
|
||||
import { Status } from '../generated/entity/applications/appRunRecord';
|
||||
import { PipelineState } from '../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||
|
||||
@ -46,3 +51,10 @@ export const getStatusFromPipelineState = (status: PipelineState) => {
|
||||
|
||||
return Status.Failed;
|
||||
};
|
||||
|
||||
export const getEntityStatsData = (data: EntityStats): EntityStatsData[] => {
|
||||
return Object.keys(data).map((key) => ({
|
||||
name: key,
|
||||
...data[key as EntityTypeSearchIndex],
|
||||
}));
|
||||
};
|
||||
|
@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright 2024 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.
|
||||
*/
|
||||
import { EntityType } from '../../enums/entity.enum';
|
||||
|
||||
export const MOCK_APPLICATION_ENTITY_STATS = {
|
||||
[EntityType.TAG]: {
|
||||
totalRecords: 10,
|
||||
failedRecords: 0,
|
||||
successRecords: 10,
|
||||
},
|
||||
[EntityType.TEAM]: {
|
||||
totalRecords: 17,
|
||||
failedRecords: 0,
|
||||
successRecords: 17,
|
||||
},
|
||||
[EntityType.USER]: {
|
||||
totalRecords: 105,
|
||||
failedRecords: 0,
|
||||
successRecords: 105,
|
||||
},
|
||||
[EntityType.CHART]: {
|
||||
totalRecords: 16,
|
||||
failedRecords: 0,
|
||||
successRecords: 16,
|
||||
},
|
||||
[EntityType.QUERY]: {
|
||||
totalRecords: 8,
|
||||
failedRecords: 0,
|
||||
successRecords: 8,
|
||||
},
|
||||
[EntityType.TABLE]: {
|
||||
totalRecords: 180,
|
||||
failedRecords: 0,
|
||||
successRecords: 180,
|
||||
},
|
||||
[EntityType.TOPIC]: {
|
||||
totalRecords: 10,
|
||||
failedRecords: 0,
|
||||
successRecords: 10,
|
||||
},
|
||||
[EntityType.DOMAIN]: {
|
||||
totalRecords: 0,
|
||||
failedRecords: 0,
|
||||
successRecords: 0,
|
||||
},
|
||||
[EntityType.MLMODEL]: {
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
[EntityType.DATABASE]: {
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
[EntityType.GLOSSARY]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.PIPELINE]: {
|
||||
totalRecords: 8,
|
||||
failedRecords: 0,
|
||||
successRecords: 8,
|
||||
},
|
||||
[EntityType.TEST_CASE]: {
|
||||
totalRecords: 7,
|
||||
failedRecords: 0,
|
||||
successRecords: 7,
|
||||
},
|
||||
[EntityType.CONTAINER]: {
|
||||
totalRecords: 17,
|
||||
failedRecords: 0,
|
||||
successRecords: 17,
|
||||
},
|
||||
[EntityType.DASHBOARD]: {
|
||||
totalRecords: 14,
|
||||
failedRecords: 0,
|
||||
successRecords: 14,
|
||||
},
|
||||
[EntityType.TEST_SUITE]: {
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
[EntityType.DATA_PRODUCT]: {
|
||||
totalRecords: 0,
|
||||
failedRecords: 0,
|
||||
successRecords: 0,
|
||||
},
|
||||
[EntityType.SEARCH_INDEX]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.GLOSSARY_TERM]: {
|
||||
totalRecords: 0,
|
||||
failedRecords: 0,
|
||||
successRecords: 0,
|
||||
},
|
||||
[EntityType.SEARCH_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.CLASSIFICATION]: {
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
[EntityType.DATABASE_SCHEMA]: {
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
[EntityType.MLMODEL_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.STORAGE_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.DATABASE_SERVICE]: {
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
[EntityType.METADATA_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.PIPELINE_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.STORED_PROCEDURE]: {
|
||||
totalRecords: 12,
|
||||
failedRecords: 0,
|
||||
successRecords: 12,
|
||||
},
|
||||
[EntityType.DASHBOARD_SERVICE]: {
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
[EntityType.ENTITY_REPORT_DATA]: {
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
[EntityType.MESSAGING_SERVICE]: {
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
[EntityType.INGESTION_PIPELINE]: {
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
[EntityType.DASHBOARD_DATA_MODEL]: {
|
||||
totalRecords: 6,
|
||||
failedRecords: 0,
|
||||
successRecords: 6,
|
||||
},
|
||||
[EntityType.WEB_ANALYTIC_ENTITY_VIEW_REPORT_DATA]: {
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
[EntityType.WEB_ANALYTIC_USER_ACTIVITY_REPORT_DATA]: {
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
};
|
||||
|
||||
export const MOCK_APPLICATION_ENTITY_STATS_DATA = [
|
||||
{
|
||||
name: EntityType.TAG,
|
||||
totalRecords: 10,
|
||||
successRecords: 10,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.TEAM,
|
||||
totalRecords: 17,
|
||||
successRecords: 17,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.USER,
|
||||
totalRecords: 105,
|
||||
successRecords: 105,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.CHART,
|
||||
totalRecords: 16,
|
||||
successRecords: 16,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.QUERY,
|
||||
totalRecords: 8,
|
||||
successRecords: 8,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.TABLE,
|
||||
totalRecords: 180,
|
||||
successRecords: 180,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.TOPIC,
|
||||
totalRecords: 10,
|
||||
successRecords: 10,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.DOMAIN,
|
||||
totalRecords: 0,
|
||||
successRecords: 0,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.MLMODEL,
|
||||
totalRecords: 2,
|
||||
successRecords: 2,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.DATABASE,
|
||||
totalRecords: 2,
|
||||
successRecords: 2,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.GLOSSARY,
|
||||
totalRecords: 1,
|
||||
successRecords: 1,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.PIPELINE,
|
||||
totalRecords: 8,
|
||||
successRecords: 8,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.TEST_CASE,
|
||||
totalRecords: 7,
|
||||
failedRecords: 0,
|
||||
successRecords: 7,
|
||||
},
|
||||
{
|
||||
name: EntityType.CONTAINER,
|
||||
totalRecords: 17,
|
||||
failedRecords: 0,
|
||||
successRecords: 17,
|
||||
},
|
||||
{
|
||||
name: EntityType.DASHBOARD,
|
||||
totalRecords: 14,
|
||||
failedRecords: 0,
|
||||
successRecords: 14,
|
||||
},
|
||||
{
|
||||
name: EntityType.TEST_SUITE,
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
{
|
||||
name: EntityType.DATA_PRODUCT,
|
||||
totalRecords: 0,
|
||||
successRecords: 0,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.SEARCH_INDEX,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.GLOSSARY_TERM,
|
||||
totalRecords: 0,
|
||||
successRecords: 0,
|
||||
failedRecords: 0,
|
||||
},
|
||||
{
|
||||
name: EntityType.SEARCH_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.CLASSIFICATION,
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
{
|
||||
name: EntityType.DATABASE_SCHEMA,
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
{
|
||||
name: EntityType.MLMODEL_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.STORAGE_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.DATABASE_SERVICE,
|
||||
totalRecords: 3,
|
||||
failedRecords: 0,
|
||||
successRecords: 3,
|
||||
},
|
||||
{
|
||||
name: EntityType.METADATA_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.PIPELINE_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.STORED_PROCEDURE,
|
||||
totalRecords: 12,
|
||||
failedRecords: 0,
|
||||
successRecords: 12,
|
||||
},
|
||||
{
|
||||
name: EntityType.DASHBOARD_SERVICE,
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
{
|
||||
name: EntityType.ENTITY_REPORT_DATA,
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
{
|
||||
name: EntityType.MESSAGING_SERVICE,
|
||||
totalRecords: 1,
|
||||
failedRecords: 0,
|
||||
successRecords: 1,
|
||||
},
|
||||
{
|
||||
name: EntityType.INGESTION_PIPELINE,
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
{
|
||||
name: EntityType.DASHBOARD_DATA_MODEL,
|
||||
totalRecords: 6,
|
||||
failedRecords: 0,
|
||||
successRecords: 6,
|
||||
},
|
||||
{
|
||||
name: EntityType.WEB_ANALYTIC_ENTITY_VIEW_REPORT_DATA,
|
||||
totalRecords: 2,
|
||||
failedRecords: 0,
|
||||
successRecords: 2,
|
||||
},
|
||||
{
|
||||
name: EntityType.WEB_ANALYTIC_USER_ACTIVITY_REPORT_DATA,
|
||||
totalRecords: 4,
|
||||
failedRecords: 0,
|
||||
successRecords: 4,
|
||||
},
|
||||
];
|
Loading…
x
Reference in New Issue
Block a user