From f23ae999982398b26090173de83a674b6b74738f Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Wed, 18 Oct 2023 14:41:14 +0300 Subject: [PATCH] Add truncation for content beyond 2 lines and show tooltip with original value if content was truncated (#3123) # What this PR does - Removed `MAX_LINE_LENGTH` which was used to truncate Integrations Name - Added new component `TextEllipsisTooltip` that determines if its content was truncated, and if so, it will show a tooltip with the original value. Integrations Name and Alert Group Name fields inside tables have been changed so that after filling in 2 lines, the content gets truncated and a tooltip is shown on hover. Before ![image](https://github.com/grafana/oncall/assets/40542072/1bdd29f3-5804-45f1-85b1-69657d26c73f) After ![image](https://github.com/grafana/oncall/assets/40542072/1a68c3ed-5884-431f-8a6f-f8ea1185987c) As you can see this results in more space being taken for the integrations name (but no more than what it should take), and the end result is always truncated after 2 lines. Same applies to the Integrations Before ![image](https://github.com/grafana/oncall/assets/40542072/802e9a4f-89b5-461d-9c04-15d7117cdb8b) After ![image](https://github.com/grafana/oncall/assets/40542072/a0674469-bdcc-4051-9783-9ffc81b8ba31) The `Don't delete` integration wasn't even showing 100% of its full width in the before screen, but it shows in the after because now there's no more limit on the characters. --- CHANGELOG.md | 4 ++ grafana-plugin/src/assets/style/global.css | 3 + .../src/assets/style/responsive.css | 23 ------- grafana-plugin/src/assets/style/utils.css | 31 +++++++-- .../MatchMediaTooltip/MatchMediaTooltip.tsx | 53 -------------- .../TextEllipsisTooltip.tsx | 60 ++++++++++++++++ .../components/TooltipBadge/TooltipBadge.tsx | 18 ++++- .../src/containers/TeamName/TeamName.tsx | 5 +- .../src/pages/incident/Incident.helpers.tsx | 69 +++++++++---------- .../src/pages/incident/Incident.module.scss | 4 ++ .../src/pages/incidents/Incidents.tsx | 69 +++++++++++-------- .../integrations/Integrations.module.scss | 14 ++-- .../src/pages/integrations/Integrations.tsx | 29 ++++---- .../outgoing_webhooks/OutgoingWebhooks.tsx | 19 +++-- .../src/pages/schedules/Schedules.module.css | 6 -- .../src/pages/schedules/Schedules.tsx | 20 +++--- .../src/plugin/GrafanaPluginRootPage.tsx | 1 - grafana-plugin/src/utils/consts.ts | 5 +- 18 files changed, 239 insertions(+), 194 deletions(-) delete mode 100644 grafana-plugin/src/assets/style/responsive.css delete mode 100644 grafana-plugin/src/components/MatchMediaTooltip/MatchMediaTooltip.tsx create mode 100644 grafana-plugin/src/components/TextEllipsisTooltip/TextEllipsisTooltip.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b188aa6..03508f5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improve alert group deletion API by @vadimkerr ([#3124](https://github.com/grafana/oncall/pull/3124)) +- Removed Integrations Name max characters limit + ([#3123](https://github.com/grafana/oncall/pull/3123)) +- Truncate long table rows (Integration Name/Alert Group) and show tooltip for the truncated content + ([#3123](https://github.com/grafana/oncall/pull/3123)) ## v1.3.42 (2023-10-04) diff --git a/grafana-plugin/src/assets/style/global.css b/grafana-plugin/src/assets/style/global.css index 5d47bdc4..ef7ae849 100644 --- a/grafana-plugin/src/assets/style/global.css +++ b/grafana-plugin/src/assets/style/global.css @@ -47,6 +47,9 @@ .rc-table-cell { padding-left: 4px; padding-right: 4px; + + /* works better than break-all, especially for table headers */ + word-break: break-word; } .grecaptcha-badge { diff --git a/grafana-plugin/src/assets/style/responsive.css b/grafana-plugin/src/assets/style/responsive.css deleted file mode 100644 index e57034a5..00000000 --- a/grafana-plugin/src/assets/style/responsive.css +++ /dev/null @@ -1,23 +0,0 @@ -/* - Make sure if you chage max-width here - You also change it in consts.ts -*/ -@media screen and (max-width: 1500px) { - .table__email-column { - max-width: 175px; - } - - .table__email-content { - text-overflow: ellipsis; - overflow: hidden; - } - - .incident__title-column { - overflow-wrap: anywhere; - white-space: pre-wrap; - } -} - -.table__wrap-column { - word-break: break-word; -} diff --git a/grafana-plugin/src/assets/style/utils.css b/grafana-plugin/src/assets/style/utils.css index b48abdd0..bbcc0df9 100644 --- a/grafana-plugin/src/assets/style/utils.css +++ b/grafana-plugin/src/assets/style/utils.css @@ -3,7 +3,7 @@ */ .u-flex { - display: flex; + display: flex !important; flex-direction: row; } @@ -84,10 +84,6 @@ position: relative; } -.u-overflow-x-auto { - overflow-x: auto; -} - .u-break-word { word-break: break-word; } @@ -129,3 +125,28 @@ margin-bottom: 0; margin-right: 4px; } + +/* ----- + * Overflow + */ + +.u-overflow-x-auto { + overflow-x: auto; +} + +.overflow-child { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + white-space: initial; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.break-word { + word-break: break-all; +} + +.line-clamp-3 { + -webkit-line-clamp: 3; +} diff --git a/grafana-plugin/src/components/MatchMediaTooltip/MatchMediaTooltip.tsx b/grafana-plugin/src/components/MatchMediaTooltip/MatchMediaTooltip.tsx deleted file mode 100644 index 6199712c..00000000 --- a/grafana-plugin/src/components/MatchMediaTooltip/MatchMediaTooltip.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React, { FC, useEffect, useState } from 'react'; - -import { Tooltip } from '@grafana/ui'; -import { debounce } from 'throttle-debounce'; - -interface MatchMediaTooltipProps { - placement: 'top' | 'bottom' | 'right' | 'left'; - content: string; - children: JSX.Element; - - maxWidth?: number; - minWidth?: number; -} - -const DEBOUNCE_MS = 200; - -export const MatchMediaTooltip: FC = ({ minWidth, maxWidth, placement, content, children }) => { - const [match, setMatch] = useState(getMatch()); - - useEffect(() => { - const debouncedResize = debounce(DEBOUNCE_MS, onWindowResize); - window.addEventListener('resize', debouncedResize); - return () => { - window.removeEventListener('resize', debouncedResize); - }; - }, []); - - if (match?.matches) { - return ( - - {children} - - ); - } - - return <>{children}; - - function onWindowResize() { - setMatch(getMatch()); - } - - function getMatch() { - if (minWidth && maxWidth) { - return window.matchMedia(`(min-width: ${minWidth}px) and (max-width: ${maxWidth}px)`); - } else if (minWidth) { - return window.matchMedia(`(min-width: ${minWidth}px)`); - } else if (maxWidth) { - return window.matchMedia(`(max-width: ${maxWidth}px)`); - } - - return undefined; - } -}; diff --git a/grafana-plugin/src/components/TextEllipsisTooltip/TextEllipsisTooltip.tsx b/grafana-plugin/src/components/TextEllipsisTooltip/TextEllipsisTooltip.tsx new file mode 100644 index 00000000..80164980 --- /dev/null +++ b/grafana-plugin/src/components/TextEllipsisTooltip/TextEllipsisTooltip.tsx @@ -0,0 +1,60 @@ +import React, { useEffect, useRef, useState } from 'react'; + +import { Tooltip } from '@grafana/ui'; +import cn from 'classnames/bind'; + +import styles from 'assets/style/utils.css'; +import { TEXT_ELLIPSIS_CLASS } from 'utils/consts'; + +const cx = cn.bind(styles); + +interface TextEllipsisTooltipProps { + content: string; + queryClassName?: string; + placement?: string; + className?: string; + children: JSX.Element | JSX.Element[]; +} + +const TextEllipsisTooltip: React.FC = ({ + queryClassName = TEXT_ELLIPSIS_CLASS, + className, + content: textContent, + placement, + children, +}) => { + const [isEllipsis, setIsEllipsis] = useState(true); + const elContentRef = useRef(null); + + useEffect(() => { + setEllipsis(); + }, []); + + const elContent = ( +
+ {children} +
+ ); + + if (isEllipsis) { + return ( + + {/* The wrapping div is needed, otherwise the attached ref will be lost when mounts */} +
{elContent}
+
+ ); + } + + return elContent; + + function setEllipsis() { + const el = elContentRef?.current?.querySelector(`.${queryClassName}`); + if (!el) { + return; + } + + setIsEllipsis(el.offsetHeight < el.scrollHeight); + } +}; + +export default TextEllipsisTooltip; diff --git a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx index b3eb8e72..84e89a94 100644 --- a/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx +++ b/grafana-plugin/src/components/TooltipBadge/TooltipBadge.tsx @@ -17,6 +17,7 @@ interface TooltipBadgeProps { icon?: IconName; customIcon?: React.ReactNode; addPadding?: boolean; + placement?; onHover?: () => void; } @@ -24,14 +25,25 @@ interface TooltipBadgeProps { const cx = cn.bind(styles); const TooltipBadge: FC = (props) => { - const { borderType, text, tooltipTitle, tooltipContent, onHover, addPadding, icon, customIcon, className, ...rest } = - props; + const { + borderType, + text, + tooltipTitle, + tooltipContent, + placement, + onHover, + addPadding, + icon, + customIcon, + className, + ...rest + } = props; const testId = rest['data-testid']; return ( diff --git a/grafana-plugin/src/containers/TeamName/TeamName.tsx b/grafana-plugin/src/containers/TeamName/TeamName.tsx index 8727dc88..956fd846 100644 --- a/grafana-plugin/src/containers/TeamName/TeamName.tsx +++ b/grafana-plugin/src/containers/TeamName/TeamName.tsx @@ -14,11 +14,12 @@ const cx = cn.bind(styles); interface TeamNameProps { team: GrafanaTeam; + className?: string; size?: 'small' | 'medium' | 'large'; } const TeamName = observer((props: TeamNameProps) => { - const { team, size = 'medium' } = props; + const { team, size = 'medium', className } = props; if (!team) { return null; } @@ -26,7 +27,7 @@ const TeamName = observer((props: TeamNameProps) => { return ; } return ( - + {team.name} diff --git a/grafana-plugin/src/pages/incident/Incident.helpers.tsx b/grafana-plugin/src/pages/incident/Incident.helpers.tsx index 125e86cc..b97f9e30 100644 --- a/grafana-plugin/src/pages/incident/Incident.helpers.tsx +++ b/grafana-plugin/src/pages/incident/Incident.helpers.tsx @@ -4,10 +4,10 @@ import { Button, HorizontalGroup, IconButton, Tooltip, VerticalGroup } from '@gr import cn from 'classnames/bind'; import Avatar from 'components/Avatar/Avatar'; -import { MatchMediaTooltip } from 'components/MatchMediaTooltip/MatchMediaTooltip'; import PluginLink from 'components/PluginLink/PluginLink'; import Tag from 'components/Tag/Tag'; import Text from 'components/Text/Text'; +import TextEllipsisTooltip from 'components/TextEllipsisTooltip/TextEllipsisTooltip'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; import { Alert as AlertType, Alert, IncidentStatus } from 'models/alertgroup/alertgroup.types'; import { User } from 'models/user/user.types'; @@ -15,7 +15,7 @@ import { SilenceButtonCascader } from 'pages/incidents/parts/SilenceButtonCascad import { move } from 'state/helpers'; import { getVar } from 'utils/DOM'; import { UserActions } from 'utils/authorization'; -import { TABLE_COLUMN_MAX_WIDTH } from 'utils/consts'; +import { TEXT_ELLIPSIS_CLASS } from 'utils/consts'; import styles from './Incident.module.scss'; @@ -78,14 +78,13 @@ export function renderRelatedUsers(incident: Alert, isFull = false) { } return ( - - - {' '} - - {user.username} - {' '} - {badge} - + + + + {user.username} + {badge} + + ); } @@ -117,32 +116,30 @@ export function renderRelatedUsers(incident: Alert, isFull = false) { } return ( -
- - {visibleUsers.map(renderUser)} - {Boolean(otherUsers.length) && ( - - {otherUsers.map((user, index) => ( - <> - {index ? ', ' : ''} - {renderUser(user)} - - ))} - - } - > - - - +{otherUsers.length} user{otherUsers.length > 1 ? 's' : ''} - - - - )} - -
+ + {visibleUsers.map(renderUser)} + {Boolean(otherUsers.length) && ( + + {otherUsers.map((user, index) => ( + <> + {index ? ', ' : ''} + {renderUser(user)} + + ))} + + } + > + + + +{otherUsers.length} user{otherUsers.length > 1 ? 's' : ''} + + + + )} + ); } diff --git a/grafana-plugin/src/pages/incident/Incident.module.scss b/grafana-plugin/src/pages/incident/Incident.module.scss index 56fc1eb9..e40de8a9 100644 --- a/grafana-plugin/src/pages/incident/Incident.module.scss +++ b/grafana-plugin/src/pages/incident/Incident.module.scss @@ -196,3 +196,7 @@ } } } + +.user-badge { + vertical-align: middle; +} \ No newline at end of file diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx index 9627b708..878bbf78 100644 --- a/grafana-plugin/src/pages/incidents/Incidents.tsx +++ b/grafana-plugin/src/pages/incidents/Incidents.tsx @@ -1,6 +1,6 @@ import React, { ReactElement, SyntheticEvent } from 'react'; -import { Button, HorizontalGroup, Icon, LoadingPlaceholder, Tooltip, VerticalGroup } from '@grafana/ui'; +import { Button, HorizontalGroup, Icon, LoadingPlaceholder, VerticalGroup } from '@grafana/ui'; import cn from 'classnames/bind'; import { get } from 'lodash-es'; import { observer } from 'mobx-react'; @@ -15,6 +15,7 @@ import IntegrationLogo from 'components/IntegrationLogo/IntegrationLogo'; import ManualAlertGroup from 'components/ManualAlertGroup/ManualAlertGroup'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; +import TextEllipsisTooltip from 'components/TextEllipsisTooltip/TextEllipsisTooltip'; import Tutorial from 'components/Tutorial/Tutorial'; import { TutorialStep } from 'components/Tutorial/Tutorial.types'; import { IncidentsFiltersType } from 'containers/IncidentsFilters/IncidentFilters.types'; @@ -27,7 +28,7 @@ import { PageProps, WithStoreProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; import LocationHelper from 'utils/LocationHelper'; import { UserActions } from 'utils/authorization'; -import { PAGE, PLUGIN_ROOT } from 'utils/consts'; +import { PAGE, PLUGIN_ROOT, TEXT_ELLIPSIS_CLASS } from 'utils/consts'; import styles from './Incidents.module.scss'; import { IncidentDropdown } from './parts/IncidentDropdown'; @@ -463,7 +464,7 @@ class Incidents extends React.Component const columns = [ { - width: '5%', + width: '140px', title: 'Status', key: 'time', render: withSkeleton(this.renderStatus), @@ -553,7 +554,13 @@ class Incidents extends React.Component }; renderId(record: AlertType) { - return #{record.inside_organization_number}; + return ( + + + #{record.inside_organization_number} + + + ); } renderTitle = (record: AlertType) => { @@ -565,25 +572,25 @@ class Incidents extends React.Component const { incidentsItemsPerPage, incidentsCursor } = store.alertGroupStore; return ( - -
- - - {record.render_for_web.title} - - - {Boolean(record.dependent_alert_groups.length) && ` + ${record.dependent_alert_groups.length} attached`} -
-
+
+ + + + {record.render_for_web.title} + + + + {Boolean(record.dependent_alert_groups.length) && ` + ${record.dependent_alert_groups.length} attached`} +
); }; @@ -598,10 +605,14 @@ class Incidents extends React.Component const integration = alertReceiveChannelStore.getIntegration(record.alert_receive_channel); return ( - + - - + + ); }; @@ -631,7 +642,11 @@ class Incidents extends React.Component } renderTeam(record: AlertType, teams: any) { - return ; + return ( + + + + ); } getOnActionButtonClick = (incidentId: string, action: AlertAction): ((e: SyntheticEvent) => Promise) => { diff --git a/grafana-plugin/src/pages/integrations/Integrations.module.scss b/grafana-plugin/src/pages/integrations/Integrations.module.scss index 42146649..a2d942f2 100644 --- a/grafana-plugin/src/pages/integrations/Integrations.module.scss +++ b/grafana-plugin/src/pages/integrations/Integrations.module.scss @@ -2,7 +2,12 @@ width: 180px; } -.title { +.heartbeat-badge { + padding: 4px 10px; + width: 40px; +} + +.integrations-header { margin-bottom: 24px; right: 0; } @@ -15,11 +20,6 @@ margin-top: 16px; } -.heartbeat-badge { - padding: 4px 10px; - width: 40px; -} - .integrations-actionsList { display: flex; flex-direction: column; @@ -44,4 +44,4 @@ &:hover { background: var(--cards-background); } -} \ No newline at end of file +} diff --git a/grafana-plugin/src/pages/integrations/Integrations.tsx b/grafana-plugin/src/pages/integrations/Integrations.tsx index 5b5cfcfd..d9a8a1e5 100644 --- a/grafana-plugin/src/pages/integrations/Integrations.tsx +++ b/grafana-plugin/src/pages/integrations/Integrations.tsx @@ -19,6 +19,7 @@ import { } from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.helpers'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; +import TextEllipsisTooltip from 'components/TextEllipsisTooltip/TextEllipsisTooltip'; import TooltipBadge from 'components/TooltipBadge/TooltipBadge'; import { WithContextMenu } from 'components/WithContextMenu/WithContextMenu'; import IntegrationForm from 'containers/IntegrationForm/IntegrationForm'; @@ -34,14 +35,13 @@ import { withMobXProviderContext } from 'state/withStore'; import { openNotification } from 'utils'; import LocationHelper from 'utils/LocationHelper'; import { UserActions } from 'utils/authorization'; -import { PAGE } from 'utils/consts'; +import { PAGE, TEXT_ELLIPSIS_CLASS } from 'utils/consts'; import styles from './Integrations.module.scss'; const cx = cn.bind(styles); const FILTERS_DEBOUNCE_MS = 500; const ITEMS_PER_PAGE = 15; -const MAX_LINE_LENGTH = 40; interface IntegrationsState extends PageBaseState { integrationsFilters: Filters; @@ -227,16 +227,11 @@ class Integrations extends React.Component ...query, }} > - - MAX_LINE_LENGTH - ? item.verbal_name?.substring(0, MAX_LINE_LENGTH) + '...' - : item.verbal_name - } - /> - + + + + +
); }; @@ -278,6 +273,7 @@ class Integrations extends React.Component icon="link" text={`${connectedEscalationsChainsCount}/${routesCounter}`} tooltipContent={undefined} + placement="top" tooltipTitle={ connectedEscalationsChainsCount + ' connected escalation chain' + @@ -328,6 +325,7 @@ class Integrations extends React.Component : } tooltipTitle={`Last heartbeat: ${heartbeat?.last_heartbeat_time_verbal}`} @@ -347,6 +345,7 @@ class Integrations extends React.Component } renderTeam(item: AlertReceiveChannel, teams: any) { - return ; + return ( + + + + ); } renderButtons = (item: AlertReceiveChannel) => { diff --git a/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx index d61294ee..99f2c1d3 100644 --- a/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx +++ b/grafana-plugin/src/pages/outgoing_webhooks/OutgoingWebhooks.tsx @@ -26,6 +26,7 @@ import { } from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.helpers'; import PluginLink from 'components/PluginLink/PluginLink'; import Text from 'components/Text/Text'; +import TextEllipsisTooltip from 'components/TextEllipsisTooltip/TextEllipsisTooltip'; import OutgoingWebhookForm from 'containers/OutgoingWebhookForm/OutgoingWebhookForm'; import RemoteFilters from 'containers/RemoteFilters/RemoteFilters'; import TeamName from 'containers/TeamName/TeamName'; @@ -36,7 +37,7 @@ import { PageProps, WithStoreProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; import { openErrorNotification, openNotification } from 'utils'; import { isUserActionAllowed, UserActions } from 'utils/authorization'; -import { PAGE, PLUGIN_ROOT } from 'utils/consts'; +import { PAGE, PLUGIN_ROOT, TEXT_ELLIPSIS_CLASS } from 'utils/consts'; import styles from './OutgoingWebhooks.module.scss'; import { WebhookFormActionType } from './OutgoingWebhooks.types'; @@ -246,7 +247,11 @@ class OutgoingWebhooks extends React.Component; + return ( + + + + ); } renderActionButtons = (record: OutgoingWebhook) => { @@ -342,9 +347,13 @@ class OutgoingWebhooks extends React.Component - {url} - + + openNotification('URL has been copied')}> + + {url} + + + ); } diff --git a/grafana-plugin/src/pages/schedules/Schedules.module.css b/grafana-plugin/src/pages/schedules/Schedules.module.css index 2511f367..c77a5af7 100644 --- a/grafana-plugin/src/pages/schedules/Schedules.module.css +++ b/grafana-plugin/src/pages/schedules/Schedules.module.css @@ -35,9 +35,3 @@ flex-grow: 1; gap: 8px; } - -.schedules__user-on-call { - display: flex; - flex-wrap: nowrap; - gap: 4px; -} diff --git a/grafana-plugin/src/pages/schedules/Schedules.tsx b/grafana-plugin/src/pages/schedules/Schedules.tsx index d2fa86be..041cda71 100644 --- a/grafana-plugin/src/pages/schedules/Schedules.tsx +++ b/grafana-plugin/src/pages/schedules/Schedules.tsx @@ -9,11 +9,11 @@ import qs from 'query-string'; import { RouteComponentProps, withRouter } from 'react-router-dom'; import Avatar from 'components/Avatar/Avatar'; -import { MatchMediaTooltip } from 'components/MatchMediaTooltip/MatchMediaTooltip'; import NewScheduleSelector from 'components/NewScheduleSelector/NewScheduleSelector'; import PluginLink from 'components/PluginLink/PluginLink'; import Table from 'components/Table/Table'; import Text from 'components/Text/Text'; +import TextEllipsisTooltip from 'components/TextEllipsisTooltip/TextEllipsisTooltip'; import TimelineMarks from 'components/TimelineMarks/TimelineMarks'; import TooltipBadge from 'components/TooltipBadge/TooltipBadge'; import UserTimezoneSelect from 'components/UserTimezoneSelect/UserTimezoneSelect'; @@ -33,7 +33,7 @@ import { WithStoreProps, PageProps } from 'state/types'; import { withMobXProviderContext } from 'state/withStore'; import LocationHelper from 'utils/LocationHelper'; import { UserActions } from 'utils/authorization'; -import { PAGE, PLUGIN_ROOT, TABLE_COLUMN_MAX_WIDTH } from 'utils/consts'; +import { PAGE, PLUGIN_ROOT, TEXT_ELLIPSIS_CLASS } from 'utils/consts'; import styles from './Schedules.module.css'; @@ -369,14 +369,14 @@ class SchedulesPage extends React.Component { return ( -
-
- -
- - {user.username} - -
+ + + + {' '} + {user.username} + + +
); })} diff --git a/grafana-plugin/src/plugin/GrafanaPluginRootPage.tsx b/grafana-plugin/src/plugin/GrafanaPluginRootPage.tsx index 86494341..2a156f34 100644 --- a/grafana-plugin/src/plugin/GrafanaPluginRootPage.tsx +++ b/grafana-plugin/src/plugin/GrafanaPluginRootPage.tsx @@ -53,7 +53,6 @@ dayjs.extend(customParseFormat); import 'assets/style/vars.css'; import 'assets/style/global.css'; import 'assets/style/utils.css'; -import 'assets/style/responsive.css'; import { getQueryParams, isTopNavbar } from './GrafanaPluginRootPage.helpers'; import PluginSetup from './PluginSetup'; diff --git a/grafana-plugin/src/utils/consts.ts b/grafana-plugin/src/utils/consts.ts index 0182abe7..b045079c 100644 --- a/grafana-plugin/src/utils/consts.ts +++ b/grafana-plugin/src/utils/consts.ts @@ -41,9 +41,6 @@ export const FARO_ENDPOINT_PROD = export const DOCS_SLACK_SETUP = 'https://grafana.com/docs/oncall/latest/open-source/#slack-setup'; export const DOCS_TELEGRAM_SETUP = 'https://grafana.com/docs/oncall/latest/notify/telegram/'; -// Make sure if you chage max-width here you also change it in responsive.css -export const TABLE_COLUMN_MAX_WIDTH = 1500; - export const generateAssignToTeamInputDescription = (objectName: string): string => `Assigning to a team allows you to filter ${objectName} and configure their visibility. Go to OnCall -> Settings -> Team and Access Settings for more details.`; @@ -54,3 +51,5 @@ export enum PAGE { Webhooks = 'webhooks', Schedules = 'schedules', } + +export const TEXT_ELLIPSIS_CLASS = 'overflow-child';