From 6c50f946618acc6d9b7d321c0d32fcd16469cd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Silva?= Date: Mon, 17 Apr 2023 01:23:03 +0100 Subject: [PATCH 1/3] PMM-11400 disable notifications for advisors (#646) * PMM-11400 disable notifications for advisors * PMM-11400 disable notifs for failed checks * PMM-11400 fix bad link --- .../features/dashboard/components/ShareModal/ShareLink.tsx | 2 +- .../add-instance/components/AddInstance/AddInstance.tsx | 1 + public/app/percona/check/Check.service.ts | 4 ++-- .../components/PerconaBootstrapper/PerconaBootstrapper.tsx | 2 +- public/app/percona/shared/core/reducers/advisors/advisors.ts | 5 +++-- public/app/percona/shared/core/reducers/services/services.ts | 2 +- .../app/percona/shared/services/services/Services.service.ts | 4 ++-- .../app/plugins/panel/pmm-check/components/Failed/Failed.tsx | 2 +- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx index f3242a589011f..5298c62c72d40 100644 --- a/public/app/features/dashboard/components/ShareModal/ShareLink.tsx +++ b/public/app/features/dashboard/components/ShareModal/ShareLink.tsx @@ -188,7 +188,7 @@ export class ShareLink extends PureComponent { {/* We modified this text and link */} To render a panel image, you must install the  = ({ onSelectInstanceType, showAz type, }) ); + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions */ onSelectInstanceType({ type: type as InstanceAvailableType }); }; diff --git a/public/app/percona/check/Check.service.ts b/public/app/percona/check/Check.service.ts index e93ef31cfb29b..71a8e20b4a4bd 100644 --- a/public/app/percona/check/Check.service.ts +++ b/public/app/percona/check/Check.service.ts @@ -30,11 +30,11 @@ const BASE_URL = '/v1/management/SecurityChecks'; * A service-like object to store the API methods */ export const CheckService = { - async getAllFailedChecks(token?: CancelToken): Promise { + async getAllFailedChecks(token?: CancelToken, disableNotifications?: boolean): Promise { const { result = [] } = await api.post( `${BASE_URL}/ListFailedServices`, {}, - false, + disableNotifications, token ); diff --git a/public/app/percona/shared/components/PerconaBootstrapper/PerconaBootstrapper.tsx b/public/app/percona/shared/components/PerconaBootstrapper/PerconaBootstrapper.tsx index b01c7d52f5651..bc7e362c8c01a 100644 --- a/public/app/percona/shared/components/PerconaBootstrapper/PerconaBootstrapper.tsx +++ b/public/app/percona/shared/components/PerconaBootstrapper/PerconaBootstrapper.tsx @@ -78,7 +78,7 @@ export const PerconaBootstrapper = ({ onReady }: PerconaBootstrapperProps) => { await dispatch(fetchUserStatusAction()); await dispatch(fetchServerInfoAction()); await dispatch(fetchServerSaasHostAction()); - await dispatch(fetchAdvisors()); + await dispatch(fetchAdvisors({ disableNotifications: true })); onReady(); }; diff --git a/public/app/percona/shared/core/reducers/advisors/advisors.ts b/public/app/percona/shared/core/reducers/advisors/advisors.ts index fdadc0f729b0a..3a81c9f5cb59d 100644 --- a/public/app/percona/shared/core/reducers/advisors/advisors.ts +++ b/public/app/percona/shared/core/reducers/advisors/advisors.ts @@ -1,4 +1,5 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; +import { CancelToken } from 'axios'; import { createAsyncSlice, withSerializedError } from 'app/features/alerting/unified/utils/redux'; import { AdvisorsService } from 'app/percona/shared/services/advisors/Advisors.service'; @@ -6,10 +7,10 @@ import { Advisor } from 'app/percona/shared/services/advisors/Advisors.types'; export const fetchAdvisors = createAsyncThunk( 'percona/fetchAdvisors', - (): Promise => + (args?: { token?: CancelToken; disableNotifications?: boolean }): Promise => withSerializedError( (async () => { - const { advisors } = await AdvisorsService.list(); + const { advisors } = await AdvisorsService.list(args?.token, args?.disableNotifications); return advisors; })() ) diff --git a/public/app/percona/shared/core/reducers/services/services.ts b/public/app/percona/shared/core/reducers/services/services.ts index 666368d93456e..b5e9f74adcad0 100644 --- a/public/app/percona/shared/core/reducers/services/services.ts +++ b/public/app/percona/shared/core/reducers/services/services.ts @@ -54,7 +54,7 @@ export const { setServices, setLoading } = servicesSlice.actions; export const fetchActiveServiceTypesAction = createAsyncThunk( 'percona/fetchActiveServiceTypes', async () => { - const response = await ServicesService.getActive(); + const response = await ServicesService.getActive(undefined, true); return response.service_types || []; } ); diff --git a/public/app/percona/shared/services/services/Services.service.ts b/public/app/percona/shared/services/services/Services.service.ts index 778e647a3b35a..0805b7404c5fd 100644 --- a/public/app/percona/shared/services/services/Services.service.ts +++ b/public/app/percona/shared/services/services/Services.service.ts @@ -5,8 +5,8 @@ import { api } from 'app/percona/shared/helpers/api'; import { ListServicesBody, ListTypesPayload, RemoveServiceBody, ServiceListPayload } from './Services.types'; export const ServicesService = { - getActive(token?: CancelToken) { - return api.post('/v1/inventory/Services/ListTypes', {}, false, token); + getActive(token?: CancelToken, disableNotifications?: boolean) { + return api.post('/v1/inventory/Services/ListTypes', {}, disableNotifications, token); }, getServices(body: Partial = {}, token?: CancelToken) { return api.post>('/v1/management/Service/List', body, false, token); diff --git a/public/app/plugins/panel/pmm-check/components/Failed/Failed.tsx b/public/app/plugins/panel/pmm-check/components/Failed/Failed.tsx index a870b3635e684..9ef94fcc74c19 100644 --- a/public/app/plugins/panel/pmm-check/components/Failed/Failed.tsx +++ b/public/app/plugins/panel/pmm-check/components/Failed/Failed.tsx @@ -26,7 +26,7 @@ export const Failed: FC = () => { const fetchAlerts = useCallback(async (): Promise => { try { - const checks = await CheckService.getAllFailedChecks(); + const checks = await CheckService.getAllFailedChecks(undefined, true); setFailedChecks(checks); } catch (e) { logger.error(e); From 6b1198b82d06de104f188143d3a65c57e4f1ea51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Silva?= Date: Mon, 17 Apr 2023 16:27:32 +0100 Subject: [PATCH 2/3] PMM-12005 show only text if db icon unavailable (#654) --- .../ServiceIconWithText.test.tsx | 20 +++++++++++++++++++ .../ServiceIconWithText.tsx | 6 +++--- 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.test.tsx diff --git a/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.test.tsx b/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.test.tsx new file mode 100644 index 0000000000000..7f7bad64174d9 --- /dev/null +++ b/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.test.tsx @@ -0,0 +1,20 @@ +import { render, screen } from '@testing-library/react'; +import React from 'react'; + +import { Databases } from 'app/percona/shared/core'; + +import { ServiceIconWithText } from './ServiceIconWithText'; + +describe('ServiceIconWithText', () => { + it('should show icon and text', () => { + render(); + expect(screen.getByText('service 1')).toBeInTheDocument(); + expect(screen.getByTestId('service-icon')).toBeInTheDocument(); + }); + + it('should show only text if icon not available', () => { + render(); + expect(screen.getByText('service 1')).toBeInTheDocument(); + expect(screen.queryByTestId('service-icon')).not.toBeInTheDocument(); + }); +}); diff --git a/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.tsx b/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.tsx index 1e38041e44178..89740a5dbf021 100644 --- a/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.tsx +++ b/public/app/percona/shared/components/Elements/ServiceIconWithText/ServiceIconWithText.tsx @@ -11,10 +11,10 @@ export const ServiceIconWithText: FC = ({ dbType, text const icon: IconName = DATABASE_ICONS[dbType]; const styles = useStyles2(getStyles); - return icon ? ( + return (
- + {!!icon && } {text}
- ) : null; + ); }; From 96502ac895984f73cc69d9389b73c06da87fd1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Silva?= Date: Mon, 17 Apr 2023 17:05:17 +0100 Subject: [PATCH 3/3] PMM-12015 add prop to control text overflow on tables (#655) --- .../grafana-ui/src/types/react-table-config.d.ts | 3 +++ .../components/AllChecksTab/AllChecksTab.tsx | 1 + .../components/ServiceChecks/ServiceChecks.tsx | 8 +++++--- .../components/Table/Table.styles.ts | 14 +++++++++++--- .../components/Table/Table.tsx | 16 +++++++++++----- .../components/Table/Table.types.ts | 1 + 6 files changed, 32 insertions(+), 11 deletions(-) diff --git a/packages/grafana-ui/src/types/react-table-config.d.ts b/packages/grafana-ui/src/types/react-table-config.d.ts index afc224f2b783d..f960a8eda19a0 100644 --- a/packages/grafana-ui/src/types/react-table-config.d.ts +++ b/packages/grafana-ui/src/types/react-table-config.d.ts @@ -106,6 +106,9 @@ declare module 'react-table' { UseSortByColumnProps { className?: string; style?: CSSProperties; + // @PERCONA + // By default, cells with too much text get their content hidden using ellipsis. This allows to override that config. + noHiddenOverflow?: boolean; } export interface Cell = Record, V = any> diff --git a/public/app/percona/check/components/AllChecksTab/AllChecksTab.tsx b/public/app/percona/check/components/AllChecksTab/AllChecksTab.tsx index a42b171efe22c..345d643f8d787 100644 --- a/public/app/percona/check/components/AllChecksTab/AllChecksTab.tsx +++ b/public/app/percona/check/components/AllChecksTab/AllChecksTab.tsx @@ -110,6 +110,7 @@ export const AllChecksTab: FC> Header: Messages.table.columns.description, accessor: 'description', type: FilterFieldTypes.TEXT, + noHiddenOverflow: true, }, { Header: Messages.table.columns.status, diff --git a/public/app/percona/check/components/ServiceChecks/ServiceChecks.tsx b/public/app/percona/check/components/ServiceChecks/ServiceChecks.tsx index d357caec7af9b..019d7cc6784c4 100644 --- a/public/app/percona/check/components/ServiceChecks/ServiceChecks.tsx +++ b/public/app/percona/check/components/ServiceChecks/ServiceChecks.tsx @@ -1,13 +1,13 @@ /* eslint-disable react/display-name */ import { Chip, logger } from '@percona/platform-core'; import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; -import { Cell, Column, Row } from 'react-table'; +import { Cell, Row } from 'react-table'; import { useStyles2 } from '@grafana/ui'; import { OldPage } from 'app/core/components/Page/Page'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { Severity } from 'app/percona/integrated-alerting/components/Severity'; -import { Table } from 'app/percona/integrated-alerting/components/Table'; +import { ExtendedColumn, Table } from 'app/percona/integrated-alerting/components/Table'; import { useStoredTablePageSize } from 'app/percona/integrated-alerting/components/Table/Pagination'; import { ExpandableCell } from 'app/percona/shared/components/Elements/ExpandableCell'; import { SilenceBell } from 'app/percona/shared/components/Elements/SilenceBell'; @@ -71,7 +71,7 @@ export const ServiceChecks: FC> ); const columns = useMemo( - (): Array> => [ + (): Array> => [ { Header: 'Check Name', accessor: 'checkName', @@ -80,10 +80,12 @@ export const ServiceChecks: FC> { Header: 'Summary', accessor: 'summary', + noHiddenOverflow: true, }, { Header: 'Description', accessor: 'description', + noHiddenOverflow: true, }, { Header: 'Severity', diff --git a/public/app/percona/integrated-alerting/components/Table/Table.styles.ts b/public/app/percona/integrated-alerting/components/Table/Table.styles.ts index 2bd62c41538de..1e08c00f13694 100644 --- a/public/app/percona/integrated-alerting/components/Table/Table.styles.ts +++ b/public/app/percona/integrated-alerting/components/Table/Table.styles.ts @@ -55,9 +55,6 @@ export const getStyles = (theme: GrafanaTheme) => { border-bottom: 1px solid ${borderColor}; border-right: 1px solid ${borderColor}; max-width: 200px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; :last-child { border-right: 0; @@ -73,5 +70,16 @@ export const getStyles = (theme: GrafanaTheme) => { padding: 0.5rem; } `, + tableHeader: (width?: string | number) => css` + width: ${width}; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + `, + tableCell: (noHiddenOverflow: boolean) => css` + overflow: ${noHiddenOverflow ? 'visible' : 'hidden'}; + text-overflow: ${noHiddenOverflow ? 'clip' : 'ellipsis'}; + white-space: ${noHiddenOverflow ? 'normal' : 'nowrap'}; + `, }; }; diff --git a/public/app/percona/integrated-alerting/components/Table/Table.tsx b/public/app/percona/integrated-alerting/components/Table/Table.tsx index 7787a32d96ca5..62da1d2384a3a 100644 --- a/public/app/percona/integrated-alerting/components/Table/Table.tsx +++ b/public/app/percona/integrated-alerting/components/Table/Table.tsx @@ -1,4 +1,4 @@ -import { css } from '@emotion/css'; +import { cx } from '@emotion/css'; import React, { FC, useEffect, useMemo, useState } from 'react'; import { useTable, @@ -173,9 +173,7 @@ export const Table: FC = ({ {headerGroup.headers.map((column) => ( /* eslint-disable-next-line react/jsx-key */ = ({ {row.cells.map((cell) => { return ( = Column & { type?: FilterFieldTypes; options?: Array>; label?: string; + noHiddenOverflow?: boolean; }; export enum FilterFieldTypes {