Explore: Fix incorrect interpolation of table title (#80227)

pull/80608/head
Uladzimir Dzmitračkoŭ 1 year ago committed by GitHub
parent 127decee1e
commit 313c43749c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx
  2. 26
      public/app/core/internationalization/index.test.tsx
  3. 2
      public/app/core/internationalization/index.tsx
  4. 8
      public/app/features/explore/Table/TableContainer.test.tsx
  5. 8
      public/app/features/explore/Table/TableContainer.tsx

@ -25,7 +25,7 @@ export type PanelChromeProps = (AutoSize | FixedDimensions) & (Collapsible | Hov
interface BaseProps {
padding?: PanelPadding;
title?: string;
title?: string | React.ReactElement;
description?: string | (() => string);
titleItems?: ReactNode;
menu?: ReactElement | (() => ReactElement);
@ -161,13 +161,13 @@ export function PanelChrome({
actions = leftItems;
}
const testid = title ? selectors.components.Panels.Panel.title(title) : 'Panel';
const testid = typeof title === 'string' ? selectors.components.Panels.Panel.title(title) : 'Panel';
const headerContent = (
<>
{/* Non collapsible title */}
{!collapsible && title && (
<h6 title={title} className={styles.title}>
<h6 title={typeof title === 'string' ? title : undefined} className={styles.title}>
{title}
</h6>
)}
@ -246,7 +246,7 @@ export function PanelChrome({
<>
<HoverWidget
menu={menu}
title={title}
title={typeof title === 'string' ? title : undefined}
offset={hoverHeaderOffset}
dragClass={dragClass}
onOpenMenu={onOpenMenu}
@ -275,7 +275,7 @@ export function PanelChrome({
{menu && (
<PanelMenu
menu={menu}
title={title}
title={typeof title === 'string' ? title : undefined}
placement="bottom-end"
menuButtonClass={cx(styles.menuItem, dragClassCancel, showOnHoverClass)}
onOpenMenu={onOpenMenu}

@ -0,0 +1,26 @@
import { render } from '@testing-library/react';
import React from 'react';
import { Trans } from './index';
describe('internationalization', () => {
describe('Trans component', () => {
it('should interpolate strings without escaping dangerous characters', () => {
const name = '<script></script>';
const { getByText } = render(<Trans i18nKey="explore.table.title-with-name">Table - {{ name }}</Trans>);
expect(getByText('Table - <script></script>')).toBeInTheDocument();
});
it('should escape dangerous characters when shouldUnescape is false', () => {
const name = '<script></script>';
const { getByText } = render(
<Trans i18nKey="explore.table.title-with-name" shouldUnescape={false}>
Table - {{ name }}
</Trans>
);
expect(getByText('Table - &lt;script&gt;&lt;&#x2F;script&gt;')).toBeInTheDocument();
});
});
});

@ -56,7 +56,7 @@ export function changeLanguage(locale: string) {
}
export const Trans: typeof I18NextTrans = (props) => {
return <I18NextTrans {...props} />;
return <I18NextTrans shouldUnescape {...props} />;
};
// Reassign t() so i18next-parser doesn't warn on dynamic key, and we can have 'failOnWarnings' enabled

@ -105,7 +105,15 @@ describe('TableContainerWithTheme', () => {
{ time: '2020-12-31 21:00:00', text: 'test_string_4' },
]);
});
it('should render table title with Prometheus query', () => {
const dataFrames = [{ ...dataFrame, name: 'metric{label="value"}' }];
const tableProps = { ...defaultProps, tableResult: dataFrames };
render(<TableContainerWithTheme {...tableProps} />);
expect(screen.getByText('Table - metric{label="value"}')).toBeInTheDocument();
});
});
describe('With multiple main frames', () => {
it('should render multiple tables for multiple frames', () => {
const dataFrames = [dataFrame, dataFrame];

@ -7,7 +7,7 @@ import { getTemplateSrv } from '@grafana/runtime';
import { TimeZone } from '@grafana/schema';
import { Table, AdHocFilterItem, PanelChrome, withTheme2, Themeable2 } from '@grafana/ui';
import { config } from 'app/core/config';
import { t } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import {
hasDeprecatedParentRowIndex,
migrateFromParentRowIndexToNestedFrames,
@ -59,7 +59,11 @@ export class TableContainer extends PureComponent<Props> {
name = data.refId || `${i}`;
}
return name ? t('explore.table.title-with-name', 'Table - {{name}}', { name }) : t('explore.table.title', 'Table');
return name ? (
<Trans i18nKey="explore.table.title-with-name">Table - {{ name }}</Trans>
) : (
t('explore.table.title', 'Table')
);
}
render() {

Loading…
Cancel
Save