mirror of https://github.com/grafana/grafana.git
i18n: imports use @grafana/i18n (#105177)
* i18n: everything should target @grafana/i18n * wip * chore: updates after PR feedback * Trigger build * Trigger build * Trigger build * chore: skip flaky tests * chore: skip flaky tests * chore: skip flaky tests * chore: skip flaky tests * chore: skip flaky tests * chore: skip flaky tests * chore: revert all flaky tests * chore: some incorrect usages of useTranslate
This commit is contained in:
parent
d8dd2facdd
commit
119d5897ea
|
@ -17,10 +17,10 @@ Grafana uses the [i18next](https://www.i18next.com/) framework for managing tran
|
|||
|
||||
### JSX
|
||||
|
||||
1. For JSX children, use the `<Trans />` component from `app/core/internationalization` with the `i18nKey`, ensuring it conforms to the following guidelines, with the default English translation. For example:
|
||||
1. For JSX children, use the `<Trans />` component from `@grafana/i18n` with the `i18nKey`, ensuring it conforms to the following guidelines, with the default English translation. For example:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
const SearchTitle = ({ term }) => <Trans i18nKey="search-page.results-title">Results for {{ term }}</Trans>;
|
||||
```
|
||||
|
@ -32,7 +32,7 @@ There may be cases where you need to interpolate variables inside other componen
|
|||
If the nested component is displaying the variable only (e.g. to add emphasis or color), the best solution is to create a new wrapping component:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Text } from '@grafana/ui';
|
||||
|
||||
const SearchTerm = ({ term }) => <Text color="success">{term}</Text>;
|
||||
|
@ -47,7 +47,7 @@ const SearchTitle = ({ term }) => (
|
|||
However there are also cases where the nested component might be displaying additional text which also needs to be translated. In this case, you can use the `values` prop to explicitly pass variables to the translation, and reference them as templated strings in the markup. For example:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Text } from '@grafana/ui';
|
||||
|
||||
const SearchTitle = ({ term }) => (
|
||||
|
@ -75,8 +75,9 @@ const ErrorMessage = ({ id, message }) => <Trans i18nKey={`errors.${id}`}>There
|
|||
Sometimes you may need to translate a string cannot be represented in JSX, such as `placeholder` props. Use the `t` macro for this.
|
||||
|
||||
```jsx
|
||||
import { t } from "app/core/internationalization"
|
||||
import { useTranslate } from "@grafana/i18n"
|
||||
|
||||
const { t } = useTranslate();
|
||||
const placeholder = t('form.username-placeholder','Username');
|
||||
|
||||
return <input type="value" placeholder={placeholder}>
|
||||
|
@ -146,7 +147,7 @@ Refer to the [i18next](https://www.i18next.com/) and [react-i18next](https://rea
|
|||
For fixed phrases:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
<Trans i18nKey="page.greeting">Hello user!</Trans>;
|
||||
```
|
||||
|
@ -154,7 +155,7 @@ import { Trans } from 'app/core/internationalization';
|
|||
To interpolate a variable, include it as an object child. It's a weird syntax, but `Trans` will do its magic to make it work:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
<Trans i18nKey="page.greeting">Hello {{ name: user.name }}!</Trans>;
|
||||
|
||||
|
@ -165,7 +166,7 @@ const userName = user.name;
|
|||
Variables must be strings (or, must support calling `.toString()`, which we almost never want). For example:
|
||||
|
||||
```jsx
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
// This will not work
|
||||
const userName = <strong>user.name</strong>;
|
||||
|
@ -183,7 +184,7 @@ const userName = user.name;
|
|||
Both HTML tags and React components can be included in a phase. The `Trans` function handles interpolating for its children.
|
||||
|
||||
```js
|
||||
import { Trans } from "app/core/internationalization"
|
||||
import { Trans } from "@grafana/i18n"
|
||||
|
||||
<Trans i18nKey="page.explainer">
|
||||
Click <button>here</button> to <a href="https://grafana.com">learn more.</a>
|
||||
|
@ -202,7 +203,7 @@ import { Trans } from "app/core/internationalization"
|
|||
Plurals require special handling to make sure they can be translated according to the rules of each locale (which may be more complex than you think). Use either the `<Trans />` component or the `t` function, with the `count` prop to provide a singular form. For example:
|
||||
|
||||
```js
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
<Trans i18nKey="inbox.heading" count={messages.length}>
|
||||
You got {{ count: messages.length }} messages
|
||||
|
@ -210,8 +211,9 @@ import { Trans } from 'app/core/internationalization';
|
|||
```
|
||||
|
||||
```js
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
|
||||
const { t } = useTranslate();
|
||||
const translatedString = t('inbox.heading', 'You got {{count}} messages', { count: messages.length });
|
||||
```
|
||||
|
||||
|
|
|
@ -119,7 +119,8 @@ export function getNamespaces() {
|
|||
}
|
||||
|
||||
export async function changeLanguage(language?: string) {
|
||||
await getI18nInstance().changeLanguage(language ?? DEFAULT_LANGUAGE);
|
||||
const validLanguage = LANGUAGES.find((lang) => lang.code === language)?.code ?? DEFAULT_LANGUAGE;
|
||||
await getI18nInstance().changeLanguage(validLanguage);
|
||||
}
|
||||
|
||||
type ResourceKey = string;
|
||||
|
|
|
@ -9,6 +9,13 @@
|
|||
* preventing the code from being importable by plugins or other npm packages making it truly "internal".
|
||||
*
|
||||
*/
|
||||
import { t } from '../i18n';
|
||||
|
||||
type TFunction = typeof t;
|
||||
|
||||
export type { TFunction };
|
||||
export { t };
|
||||
|
||||
export {
|
||||
addResourceBundle,
|
||||
changeLanguage,
|
||||
|
@ -16,5 +23,4 @@ export {
|
|||
getLanguage,
|
||||
getResolvedLanguage,
|
||||
initTranslations,
|
||||
t,
|
||||
} from '../i18n';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { t } from '@grafana/i18n/internal';
|
||||
import { isFetchError } from '@grafana/runtime';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { createSuccessNotification, createErrorNotification } from 'app/core/copy/appNotification';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import {
|
||||
generatedAPI,
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
standardFieldConfigEditorRegistry,
|
||||
standardTransformersRegistry,
|
||||
} from '@grafana/data';
|
||||
import { initTranslations } from '@grafana/i18n/internal';
|
||||
import {
|
||||
locationService,
|
||||
registerEchoBackend,
|
||||
|
@ -61,7 +62,8 @@ import { getAllOptionEditors, getAllStandardFieldConfigs } from './core/componen
|
|||
import { PluginPage } from './core/components/Page/PluginPage';
|
||||
import { GrafanaContextType, useReturnToPreviousInternal } from './core/context/GrafanaContext';
|
||||
import { initializeCrashDetection } from './core/crash';
|
||||
import { initializeI18n } from './core/internationalization';
|
||||
import { NAMESPACES } from './core/internationalization/constants';
|
||||
import { loadTranslations } from './core/internationalization/loadTranslations';
|
||||
import { postInitTasks, preInitTasks } from './core/lifecycle-hooks';
|
||||
import { setMonacoEnv } from './core/monacoEnv';
|
||||
import { interceptLinkClicks } from './core/navigation/patch/interceptLinkClicks';
|
||||
|
@ -124,7 +126,14 @@ export class GrafanaApp {
|
|||
// Let iframe container know grafana has started loading
|
||||
window.parent.postMessage('GrafanaAppInit', '*');
|
||||
|
||||
const initI18nPromise = initializeI18n(config.bootData.user.language);
|
||||
// This is a placeholder so we can put a 'comment' in the message json files.
|
||||
// Starts with an underscore so it's sorted to the top of the file. Even though it is in a comment the following line is still extracted
|
||||
// t('_comment', 'The code is the source of truth for English phrases. They should be updated in the components directly, and additional plurals specified in this file.');
|
||||
const initI18nPromise = initTranslations({
|
||||
language: config.bootData.user.language,
|
||||
ns: NAMESPACES,
|
||||
module: loadTranslations,
|
||||
});
|
||||
initI18nPromise.then(({ language }) => updateConfig({ language }));
|
||||
|
||||
setBackendSrv(backendSrv);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { Button, Select, Stack } from '@grafana/ui';
|
||||
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
|
||||
import { ServiceAccountPicker } from 'app/core/components/Select/ServiceAccountPicker';
|
||||
import { TeamPicker } from 'app/core/components/Select/TeamPicker';
|
||||
import { UserPicker } from 'app/core/components/Select/UserPicker';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { OrgRole } from 'app/types/acl';
|
||||
|
||||
import { Assignments, PermissionTarget, SetPermission } from './types';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useMemo } from 'react';
|
||||
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
|
||||
import { PermissionListItem } from './PermissionListItem';
|
||||
import { ResourcePermission } from './types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Box, Button, Icon, Select, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ResourcePermission } from './types';
|
||||
|
||||
|
@ -16,7 +16,7 @@ interface Props {
|
|||
|
||||
export const PermissionListItem = ({ item, permissionLevels, canSet, onRemove, onChange }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<tr>
|
||||
<td>{getAvatar(item)}</td>
|
||||
|
|
|
@ -4,9 +4,10 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { Text, Box, Button, useStyles2, Space } from '@grafana/ui';
|
||||
import { SlideDown } from 'app/core/components/Animations/SlideDown';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DescendantCount } from 'app/features/browse-dashboards/components/BrowseActions/DescendantCount';
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@ import { Resizable } from 're-resizable';
|
|||
import { PropsWithChildren, useEffect } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { locationSearchToObject, locationService, useScopes } from '@grafana/runtime';
|
||||
import { ErrorBoundaryAlert, getDragStyles, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { useMediaQueryMinWidth } from 'app/core/hooks/useMediaQueryMinWidth';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import store from 'app/core/store';
|
||||
import { CommandPalette } from 'app/features/commandPalette/CommandPalette';
|
||||
import { ScopesDashboards } from 'app/features/scopes/dashboards/ScopesDashboards';
|
||||
|
|
|
@ -2,9 +2,9 @@ import { useObservable } from 'react-use';
|
|||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
import { AppEvents, NavModel, NavModelItem, PageLayoutType, UrlQueryValue } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { config, locationService, reportInteraction } from '@grafana/runtime';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import store from 'app/core/store';
|
||||
import { isShallowEqual } from 'app/core/utils/isShallowEqual';
|
||||
import { KioskMode } from 'app/types';
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css, cx } from '@emotion/css';
|
|||
import { useCallback } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Dropdown, Menu, ToolbarButton, useTheme2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { NavToolbarSeparator } from '../NavToolbar/NavToolbarSeparator';
|
||||
|
||||
|
@ -17,6 +17,7 @@ export function ExtensionToolbarItem() {
|
|||
const styles = getStyles(useTheme2());
|
||||
const { availableComponents, dockedComponentId, setDockedComponentId, isOpen, isEnabled } =
|
||||
useExtensionSidebarContext();
|
||||
const { t } = useTranslate();
|
||||
|
||||
let dockedComponentTitle = '';
|
||||
if (dockedComponentId) {
|
||||
|
@ -72,7 +73,7 @@ export function ExtensionToolbarItem() {
|
|||
/>
|
||||
);
|
||||
},
|
||||
[setDockedComponentId, styles.button, styles.buttonActive]
|
||||
[setDockedComponentId, styles.button, styles.buttonActive, t]
|
||||
);
|
||||
|
||||
if (components.length === 1) {
|
||||
|
|
|
@ -3,9 +3,9 @@ import { useEffect } from 'react';
|
|||
import { useToggle } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, store } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Drawer, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { appEvents } from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { RecordHistoryEntryEvent } from 'app/types/events';
|
||||
|
||||
import { HISTORY_LOCAL_STORAGE_KEY } from '../AppChromeService';
|
||||
|
@ -47,6 +47,7 @@ export function HistoryContainer() {
|
|||
};
|
||||
});
|
||||
}, []);
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -3,8 +3,8 @@ import moment from 'moment';
|
|||
import { useState } from 'react';
|
||||
|
||||
import { FieldType, GrafanaTheme2, store } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Button, Card, IconButton, Space, Stack, Text, useStyles2, Box, Sparkline, useTheme2, Icon } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { formatDate } from 'app/core/internationalization/dates';
|
||||
|
||||
import { HISTORY_LOCAL_STORAGE_KEY } from '../AppChromeService';
|
||||
|
@ -13,6 +13,7 @@ import { HistoryEntry } from '../types';
|
|||
import { logClickUnifiedHistoryEntryEvent, logUnifiedHistoryShowMoreEvent } from './eventsTracking';
|
||||
|
||||
export function HistoryWrapper({ onClose }: { onClose: () => void }) {
|
||||
const { t } = useTranslate();
|
||||
const history = store.getObject<HistoryEntry[]>(HISTORY_LOCAL_STORAGE_KEY, []).filter((entry) => {
|
||||
return moment(entry.time).isAfter(moment().subtract(2, 'day').startOf('day'));
|
||||
});
|
||||
|
@ -88,6 +89,7 @@ function HistoryEntryAppView({ entry, isSelected, onClick }: ItemProps) {
|
|||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
const [isExpanded, setIsExpanded] = useState(isSelected && entry.views.length > 0);
|
||||
const { t } = useTranslate();
|
||||
const { breadcrumbs, views, time, url, sparklineData } = entry;
|
||||
const expandedLabel = isExpanded
|
||||
? t('nav.history-wrapper.collapse', 'Collapse')
|
||||
|
|
|
@ -5,10 +5,10 @@ import { useLocation } from 'react-router-dom-v5-compat';
|
|||
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { ScrollContainer, useStyles2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { setBookmark } from 'app/core/reducers/navBarTree';
|
||||
import { usePatchUserPreferencesMutation } from 'app/features/preferences/api/index';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
@ -37,7 +37,7 @@ export const MegaMenu = memo(
|
|||
const state = chrome.useState();
|
||||
const [patchPreferences] = usePatchUserPreferencesMutation();
|
||||
const pinnedItems = usePinnedItems();
|
||||
|
||||
const { t } = useTranslate();
|
||||
// Remove profile + help from tree
|
||||
const navItems = navTree
|
||||
.filter((item) => item.id !== 'profile' && item.id !== 'help')
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { IconButton, Stack, ToolbarButton, useTheme2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { Branding } from '../../Branding/Branding';
|
||||
import { OrganizationSwitcher } from '../OrganizationSwitcher/OrganizationSwitcher';
|
||||
|
@ -22,6 +22,7 @@ export function MegaMenuHeader({ handleMegaMenu, handleDockedMenu, onClose }: Pr
|
|||
const theme = useTheme2();
|
||||
const { chrome } = useGrafana();
|
||||
const state = chrome.useState();
|
||||
const { t } = useTranslate();
|
||||
const styles = getStyles(theme);
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,10 +5,10 @@ import { useLocation } from 'react-router-dom-v5-compat';
|
|||
import { useLocalStorage } from 'react-use';
|
||||
|
||||
import { FeatureState, GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2, Text, IconButton, Icon, Stack, FeatureBadge } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
|
||||
import { t } from '../../../internationalization';
|
||||
import { Indent } from '../../Indent/Indent';
|
||||
|
||||
import { FeatureHighlight } from './FeatureHighlight';
|
||||
|
@ -58,6 +58,7 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
|
|||
});
|
||||
}
|
||||
}, [isActive]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (!link.url) {
|
||||
return null;
|
||||
|
|
|
@ -3,9 +3,9 @@ import * as React from 'react';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Icon, IconButton, Link, useTheme2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
export interface Props {
|
||||
|
@ -20,6 +20,7 @@ export interface Props {
|
|||
|
||||
export function MegaMenuItemText({ children, isActive, onClick, target, url, onPin, isPinned }: Props) {
|
||||
const theme = useTheme2();
|
||||
const { t } = useTranslate();
|
||||
const styles = getStyles(theme, isActive);
|
||||
const LinkComponent = !target && url.startsWith('/') ? Link : 'a';
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { MEGA_MENU_TOGGLE_ID } from 'app/core/constants';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { HOME_NAV_ID } from 'app/core/reducers/navModel';
|
||||
|
||||
import { ShowModalReactEvent } from '../../../../types/events';
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { IconButton, Drawer, useStyles2, Text } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { DEFAULT_FEED_URL } from 'app/plugins/panel/news/constants';
|
||||
import grotNewsSvg from 'img/grot-news.svg';
|
||||
|
||||
|
@ -16,7 +16,7 @@ interface NewsContainerProps {
|
|||
|
||||
export function NewsContainer({ onClose }: NewsContainerProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<Drawer
|
||||
title={
|
||||
|
|
|
@ -3,13 +3,12 @@ import { useEffect } from 'react';
|
|||
import { useMeasure } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { News } from 'app/plugins/panel/news/component/News';
|
||||
import { useNewsFeed } from 'app/plugins/panel/news/useNewsFeed';
|
||||
import grotNewsSvg from 'img/grot-news.svg';
|
||||
|
||||
import { t } from '../../../internationalization';
|
||||
|
||||
interface NewsWrapperProps {
|
||||
feedUrl: string;
|
||||
}
|
||||
|
@ -21,6 +20,7 @@ export function NewsWrapper({ feedUrl }: NewsWrapperProps) {
|
|||
useEffect(() => {
|
||||
getNews();
|
||||
}, [getNews]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (state.error) {
|
||||
return <div className={styles.innerWrapper}>{state.error && state.error.message}</div>;
|
||||
|
|
|
@ -2,16 +2,16 @@ import { css } from '@emotion/css';
|
|||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { SelectableValue, GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Icon, Select, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { UserOrg } from 'app/types';
|
||||
|
||||
import { t } from '../../../internationalization';
|
||||
|
||||
import { OrganizationBaseProps } from './types';
|
||||
|
||||
export function OrganizationSelect({ orgs, onSelectChange }: OrganizationBaseProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
const { orgId } = contextSrv.user;
|
||||
|
||||
const options = useMemo(
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { Menu, Dropdown, ToolbarButton } from '@grafana/ui';
|
||||
import { getExternalUserMngLinkUrl } from 'app/features/users/utils';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { t } from '../../../internationalization';
|
||||
import { performInviteUserClick, shouldRenderInviteUserButton } from '../../InviteUserButton/utils';
|
||||
import { NavToolbarSeparator } from '../NavToolbar/NavToolbarSeparator';
|
||||
|
||||
|
@ -16,6 +16,7 @@ export interface Props {}
|
|||
export const QuickAdd = ({}: Props) => {
|
||||
const navBarTree = useSelector((state) => state.navBarTree);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const { t } = useTranslate();
|
||||
const createActions = useMemo(() => {
|
||||
const actions = findCreateActions(navBarTree);
|
||||
|
||||
|
@ -32,7 +33,7 @@ export const QuickAdd = ({}: Props) => {
|
|||
}
|
||||
|
||||
return actions;
|
||||
}, [navBarTree]);
|
||||
}, [navBarTree, t]);
|
||||
const showQuickAdd = createActions.length > 0;
|
||||
|
||||
if (!showQuickAdd) {
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Button, ButtonGroup, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
export interface DismissableButtonProps {
|
||||
label: string;
|
||||
|
@ -13,7 +13,7 @@ export interface DismissableButtonProps {
|
|||
|
||||
export const DismissableButton = ({ label, onClick, onDismiss }: DismissableButtonProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<ButtonGroup className={styles.buttonGroup}>
|
||||
<Button
|
||||
|
|
|
@ -3,10 +3,10 @@ import { useCallback } from 'react';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { DismissableButton } from './DismissableButton';
|
||||
|
||||
|
@ -27,7 +27,7 @@ export const ReturnToPrevious = ({ href, title }: ReturnToPreviousProps) => {
|
|||
const handleOnDismiss = useCallback(() => {
|
||||
chrome.clearReturnToPrevious('dismissed');
|
||||
}, [chrome]);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div className={styles.returnToPrevious} data-testid={selectors.components.ReturnToPrevious.buttonGroup}>
|
||||
<DismissableButton
|
||||
|
|
|
@ -3,10 +3,10 @@ import { cloneDeep } from 'lodash';
|
|||
import { useToggle } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Dropdown, Menu, MenuItem, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { ThemeSelectorDrawer } from '../../ThemeSelector/ThemeSelectorDrawer';
|
||||
import { enrichWithInteractionTracking } from '../MegaMenu/utils';
|
||||
|
@ -24,7 +24,7 @@ export function ProfileButton({ profileNode, onToggleKioskMode }: Props) {
|
|||
const node = enrichWithInteractionTracking(cloneDeep(profileNode), false);
|
||||
const [showNewsDrawer, onToggleShowNewsDrawer] = useToggle(false);
|
||||
const [showThemeDrawer, onToggleThemeDrawer] = useToggle(false);
|
||||
|
||||
const { t } = useTranslate();
|
||||
if (!node) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
import { useLocation } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { GrafanaTheme2, locationUtil, textUtil } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export function SignInLink() {
|
||||
const location = useLocation();
|
||||
|
|
|
@ -4,6 +4,7 @@ import { memo } from 'react';
|
|||
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { Components } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { ScopesContextValue } from '@grafana/runtime';
|
||||
import { Dropdown, Icon, Stack, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
|
@ -11,7 +12,6 @@ import { MEGA_MENU_TOGGLE_ID } from 'app/core/constants';
|
|||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { useMediaQueryMinWidth } from 'app/core/hooks/useMediaQueryMinWidth';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { HOME_NAV_ID } from 'app/core/reducers/navModel';
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
|
@ -64,7 +64,7 @@ export const SingleTopBar = memo(function SingleTopBar({
|
|||
const breadcrumbs = buildBreadcrumbs(sectionNav, pageNav, homeNav);
|
||||
const unifiedHistoryEnabled = config.featureToggles.unifiedHistory;
|
||||
const isSmallScreen = !useMediaQueryMinWidth('sm');
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<>
|
||||
<div className={styles.layout}>
|
||||
|
|
|
@ -4,10 +4,10 @@ import React, { useMemo } from 'react';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { getInputStyles, Icon, Text, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { getFocusStyles } from '@grafana/ui/internal';
|
||||
import { useMediaQueryMinWidth } from 'app/core/hooks/useMediaQueryMinWidth';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { getModKey } from 'app/core/utils/browser';
|
||||
|
||||
import { NavToolbarSeparator } from '../NavToolbar/NavToolbarSeparator';
|
||||
|
@ -19,7 +19,7 @@ export const TopSearchBarCommandPaletteTrigger = React.memo(() => {
|
|||
}));
|
||||
|
||||
const isLargeScreen = useMediaQueryMinWidth('lg');
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onOpenSearch = () => {
|
||||
kbar.toggle();
|
||||
};
|
||||
|
@ -48,7 +48,7 @@ interface PretendTextInputProps {
|
|||
function PretendTextInput({ onClick }: PretendTextInputProps) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const modKey = useMemo(() => getModKey(), []);
|
||||
|
||||
const { t } = useTranslate();
|
||||
// We want the desktop command palette trigger to look like a search box,
|
||||
// but it actually behaves like a button - you active it and it performs an
|
||||
// action. You don't actually type into it.
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
import { useEffectOnce } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Alert, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { AppNotification, timeoutMap } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { css, keyframes } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import grafanaIconSvg from 'img/grafana_icon.svg';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export function BouncingLoader() {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div
|
||||
className={styles.container}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { BreadcrumbItem } from './BreadcrumbItem';
|
||||
import { Breadcrumb } from './types';
|
||||
|
||||
|
@ -15,7 +14,7 @@ export interface Props {
|
|||
|
||||
export function Breadcrumbs({ breadcrumbs, className }: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<nav aria-label={t('navigation.breadcrumbs.aria-label', 'Breadcrumbs')} className={className}>
|
||||
<ol className={styles.breadcrumbs}>
|
||||
|
|
|
@ -2,10 +2,9 @@ import { css } from '@emotion/css';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { IconButton, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
type Props = {
|
||||
onClick: () => void;
|
||||
'aria-label'?: string;
|
||||
|
@ -14,6 +13,8 @@ type Props = {
|
|||
|
||||
export const CloseButton = ({ onClick, 'aria-label': ariaLabel, style }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
aria-label={ariaLabel ?? 'Close'}
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
import { MouseEvent } from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Alert, Button, CallToActionCard, Icon, IconName, LinkButton } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
|
|
|
@ -3,9 +3,9 @@ import debounce from 'debounce-promise';
|
|||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { getGrafanaSearcher } from 'app/features/search/service/searcher';
|
||||
import { DashboardSearchItemType } from 'app/features/search/types';
|
||||
|
@ -21,6 +21,7 @@ export function FolderFilter({ onChange, maxMenuHeight }: FolderFilterProps): JS
|
|||
const [loading, setLoading] = useState(false);
|
||||
const getOptions = useCallback((searchString: string) => getFoldersAsOptions(searchString, setLoading), []);
|
||||
const debouncedLoadOptions = useMemo(() => debounce(getOptions, 300), [getOptions]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
const [value, setValue] = useState<Array<SelectableValue<FolderInfo>>>([]);
|
||||
const onSelectOptionChange = useCallback(
|
||||
|
|
|
@ -2,9 +2,9 @@ import { css } from '@emotion/css';
|
|||
import { memo } from 'react';
|
||||
|
||||
import { GrafanaTheme2, LinkTarget } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Icon, IconName, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
export interface FooterLink {
|
||||
target: LinkTarget;
|
||||
|
|
|
@ -2,9 +2,9 @@ import { SyntheticEvent, useState } from 'react';
|
|||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Tooltip, Field, Button, Alert, useStyles2, Stack } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { getStyles } from '../Login/LoginForm';
|
||||
import { PasswordField } from '../PasswordField/PasswordField';
|
||||
|
@ -27,6 +27,7 @@ interface PasswordDTO {
|
|||
|
||||
export const ChangePassword = ({ onSubmit, onSkip, showDefaultPasswordWarning }: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
const [displayValidationLabels, setDisplayValidationLabels] = useState(false);
|
||||
const [pristine, setPristine] = useState(true);
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@ import { useState } from 'react';
|
|||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, Legend, Container, useStyles2, LinkButton, Stack } from '@grafana/ui';
|
||||
import config from 'app/core/config';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
interface EmailDTO {
|
||||
userOrEmail: string;
|
||||
|
@ -30,6 +30,7 @@ export const ForgottenPassword = () => {
|
|||
register,
|
||||
formState: { errors },
|
||||
} = useForm<EmailDTO>();
|
||||
const { t } = useTranslate();
|
||||
|
||||
const sendEmail = async (formModel: EmailDTO) => {
|
||||
const res = await getBackendSrv().post('/api/user/password/send-reset-email', formModel);
|
||||
|
|
|
@ -3,8 +3,8 @@ import history from 'history';
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Button, Modal } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Prompt } from './Prompt';
|
||||
|
||||
|
@ -96,6 +96,8 @@ interface UnsavedChangesModalProps {
|
|||
}
|
||||
|
||||
const UnsavedChangesModal = ({ onDiscard, onBackToForm, isOpen }: UnsavedChangesModalProps) => {
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Button } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { performInviteUserClick } from './utils';
|
||||
|
||||
export function InviteUserButton() {
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon="add-user"
|
||||
|
|
|
@ -2,10 +2,9 @@ import { css, cx } from '@emotion/css';
|
|||
import { DragDropContext, Draggable, Droppable, DropResult } from '@hello-pangea/dnd';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Icon, IconButton, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { LayerName } from './LayerName';
|
||||
import { LayerElement } from './types';
|
||||
|
||||
|
@ -39,7 +38,7 @@ export const LayerDragDropList = <T extends LayerElement>({
|
|||
verifyLayerNameUniqueness,
|
||||
}: LayerDragDropListProps<T>) => {
|
||||
const style = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const getRowStyle = (isSelected: boolean) => {
|
||||
return isSelected ? `${style.row} ${style.sel}` : style.row;
|
||||
};
|
||||
|
|
|
@ -3,10 +3,9 @@ import { useState } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Icon, Input, FieldValidationMessage, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface LayerNameProps {
|
||||
name: string;
|
||||
onChange: (v: string) => void;
|
||||
|
@ -19,6 +18,7 @@ export const LayerName = ({ name, onChange, verifyLayerNameUniqueness, overrideS
|
|||
|
||||
const [isEditing, setIsEditing] = useState<boolean>(false);
|
||||
const [validationError, setValidationError] = useState<string | null>(null);
|
||||
const { t } = useTranslate();
|
||||
|
||||
const onEditLayer = (event: React.SyntheticEvent) => {
|
||||
setIsEditing(true);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { PureComponent } from 'react';
|
||||
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { FetchError, getBackendSrv, isFetchError, locationService } from '@grafana/runtime';
|
||||
import config from 'app/core/config';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { LoginDTO, AuthNRedirectDTO } from './types';
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import { useForm } from 'react-hook-form';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Button, Input, Field, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { PasswordField } from '../PasswordField/PasswordField';
|
||||
|
||||
|
@ -28,7 +28,7 @@ export const LoginForm = ({ children, onSubmit, isLoggingIn, passwordHint, login
|
|||
register,
|
||||
formState: { errors },
|
||||
} = useForm<FormModel>({ mode: 'onChange' });
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
|
|
|
@ -3,8 +3,8 @@ import { useEffect, useState } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Branding } from '../Branding/Branding';
|
||||
import { BrandingSettings } from '../Branding/types';
|
||||
|
|
|
@ -3,10 +3,10 @@ import { css } from '@emotion/css';
|
|||
|
||||
// Components
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Alert, LinkButton, Stack, useStyles2 } from '@grafana/ui';
|
||||
import { Branding } from 'app/core/components/Branding/Branding';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ChangePassword } from '../ForgottenPassword/ChangePassword';
|
||||
|
||||
|
@ -20,6 +20,7 @@ import { UserSignup } from './UserSignup';
|
|||
|
||||
const LoginPage = () => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
document.title = Branding.AppTitle;
|
||||
|
||||
return (
|
||||
|
|
|
@ -2,9 +2,9 @@ import { css, cx } from '@emotion/css';
|
|||
import { pickBy } from 'lodash';
|
||||
|
||||
import { GrafanaTheme2, DEFAULT_SAML_NAME } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Icon, IconName, LinkButton, Stack, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import config from 'app/core/config';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export interface LoginService {
|
||||
bgColor: string;
|
||||
|
|
|
@ -4,10 +4,10 @@ import { useForm } from 'react-hook-form';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { Button, Input, Field, useStyles2 } from '@grafana/ui';
|
||||
import { Branding } from 'app/core/components/Branding/Branding';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { PasswordlessConfirmationFormModel } from './LoginCtrl';
|
||||
|
||||
|
@ -55,6 +55,7 @@ export const PasswordlessConfirmation = ({ onSubmit, isLoggingIn }: Props) => {
|
|||
setValue('name', queryValues.get('name') || '');
|
||||
}
|
||||
}, [setValue, handleSubmit, onSubmit, setSignup]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
|
|
|
@ -4,8 +4,8 @@ import { useForm } from 'react-hook-form';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Button, Input, Field, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { PasswordlessFormModel } from './LoginCtrl';
|
||||
|
||||
|
@ -22,7 +22,7 @@ export const PasswordlessLoginForm = ({ onSubmit, isLoggingIn }: Props) => {
|
|||
register,
|
||||
formState: { errors },
|
||||
} = useForm<PasswordlessFormModel>({ mode: 'onChange' });
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { LinkButton, Stack } from '@grafana/ui';
|
||||
import { getConfig } from 'app/core/config';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export const UserSignup = () => {
|
||||
const href = getConfig().verifyEmailEnabled ? `${getConfig().appSubUrl}/verify` : `${getConfig().appSubUrl}/signup`;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Badge } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { useIsProvisionedInstance } from 'app/features/provisioning/hooks/useIsProvisionedInstance';
|
||||
import { NestedFolderDTO } from 'app/features/search/service/types';
|
||||
import { FolderDTO, FolderListItemDTO } from 'app/types';
|
||||
|
@ -10,6 +10,8 @@ export interface Props {
|
|||
|
||||
export function FolderRepo({ folder }: Props) {
|
||||
const isProvisionedInstance = useIsProvisionedInstance();
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (!folder || ('parentUID' in folder && folder.parentUID) || !folder.managedBy || isProvisionedInstance) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ import { FixedSizeList as List } from 'react-window';
|
|||
import InfiniteLoader from 'react-window-infinite-loader';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { IconButton, useStyles2, Text } from '@grafana/ui';
|
||||
import { Indent } from 'app/core/components/Indent/Indent';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { childrenByParentUIDSelector, rootItemsSelector } from 'app/features/browse-dashboards/state';
|
||||
import { DashboardsTreeItem } from 'app/features/browse-dashboards/types';
|
||||
import { DashboardViewItem } from 'app/features/search/types';
|
||||
|
|
|
@ -6,9 +6,9 @@ import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Alert, Icon, Input, LoadingBar, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { useGetFolderQuery } from 'app/features/browse-dashboards/api/browseDashboardsAPI';
|
||||
import { DashboardViewItemWithUIItems, DashboardsTreeItem } from 'app/features/browse-dashboards/types';
|
||||
import { getGrafanaSearcher } from 'app/features/search/service/searcher';
|
||||
|
@ -250,6 +250,7 @@ export function NestedFolderPicker({
|
|||
},
|
||||
[flatTree]
|
||||
);
|
||||
const { t } = useTranslate();
|
||||
|
||||
const isLoading = isBrowseLoading || isFetchingSearchResults;
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ import { forwardRef, ReactNode, ButtonHTMLAttributes } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Icon, getInputStyles, useTheme2, Text } from '@grafana/ui';
|
||||
import { getFocusStyles, getMouseFocusStyles } from '@grafana/ui/internal';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
|
||||
import { FolderPickerSkeleton } from './Skeleton';
|
||||
|
||||
|
@ -21,6 +21,7 @@ function Trigger(
|
|||
ref: React.ForwardedRef<HTMLButtonElement>
|
||||
) {
|
||||
const theme = useTheme2();
|
||||
const { t } = useTranslate();
|
||||
const styles = getStyles(theme, invalid);
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent<SVGElement>) => {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useTheme2, useStyles2, ColorPicker, IconButton } from '@grafana/ui';
|
||||
import { ColorSwatch } from '@grafana/ui/internal';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface ColorValueEditorSettings {
|
||||
placeholder?: string;
|
||||
/** defaults to true */
|
||||
|
@ -29,7 +28,7 @@ interface Props {
|
|||
export const ColorValueEditor = ({ value, settings, onChange, details }: Props) => {
|
||||
const theme = useTheme2();
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<ColorPicker color={value ?? ''} onChange={onChange} enableNamedColors={settings?.enableNamedColors !== false}>
|
||||
{({ ref, showColorPicker, hideColorPicker }) => {
|
||||
|
|
|
@ -13,10 +13,9 @@ import {
|
|||
FieldColorSeriesByMode,
|
||||
getFieldColorMode,
|
||||
} from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2, useTheme2, Field, RadioButtonGroup, Select } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { ColorValueEditor } from './color';
|
||||
|
||||
type Props = StandardEditorProps<FieldColor | undefined, FieldColorConfigSettings>;
|
||||
|
@ -24,6 +23,7 @@ type Props = StandardEditorProps<FieldColor | undefined, FieldColorConfigSetting
|
|||
export const FieldColorEditor = ({ value, onChange, item, id }: Props) => {
|
||||
const theme = useTheme2();
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
|
||||
const colorMode = getFieldColorMode(value?.mode);
|
||||
const availableOptions = item.settings?.byValueSupport
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { StandardEditorProps, GrafanaTheme2, UnitFieldConfigSettings } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { IconButton, UnitPicker, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
type Props = StandardEditorProps<string, UnitFieldConfigSettings>;
|
||||
|
||||
export function UnitValueEditor({ value, onChange, item }: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
if (item?.settings?.isClearable && value != null) {
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
|
|
|
@ -3,11 +3,10 @@ import { useCallback, useEffect, useState } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { isFetchError } from '@grafana/runtime';
|
||||
import { Field, IconButton, Input, useStyles2, Text } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface Props {
|
||||
value: string;
|
||||
onEdit: (newValue: string) => Promise<void>;
|
||||
|
@ -54,6 +53,7 @@ export const EditableTitle = ({ value, onEdit }: Props) => {
|
|||
},
|
||||
[onEdit, value]
|
||||
);
|
||||
const { t } = useTranslate();
|
||||
|
||||
return !isEditing ? (
|
||||
<div className={styles.textContainer}>
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { EmptyState, TextLink, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export interface Props {
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getAllPanelPluginMeta } from 'app/features/panel/state/util';
|
||||
|
||||
export interface Props {
|
||||
|
@ -30,7 +30,7 @@ export const PanelTypeFilter = ({ onChange: propsOnChange, maxMenuHeight }: Prop
|
|||
[propsOnChange]
|
||||
);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const selectOptions = {
|
||||
defaultOptions: true,
|
||||
getOptionLabel: (i: SelectableValue<PanelPluginMeta>) => i.label,
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import { forwardRef, useState } from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Input, IconButton } from '@grafana/ui';
|
||||
import { InputProps } from '@grafana/ui/internal';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
interface Props extends Omit<InputProps, 'type'> {}
|
||||
|
||||
export const PasswordField = forwardRef<HTMLInputElement, Props>((props, ref) => {
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<Input
|
||||
{...props}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import { useAsync } from 'react-use';
|
||||
|
||||
import { renderMarkdown } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { LoadingPlaceholder } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
interface Props {
|
||||
pluginId: string;
|
||||
}
|
||||
|
||||
export function PluginHelp({ pluginId }: Props) {
|
||||
const { t } = useTranslate();
|
||||
|
||||
const { value, loading, error } = useAsync(async () => {
|
||||
return getBackendSrv().get(`/api/plugins/${pluginId}/markdown/query_help`);
|
||||
}, []);
|
||||
|
|
|
@ -4,8 +4,8 @@ import { MouseEventHandler } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Icon, IconButton, useStyles2, Stack } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
export interface QueryOperationRowHeaderProps {
|
||||
actionsElement?: React.ReactNode;
|
||||
|
@ -42,7 +42,7 @@ export const QueryOperationRowHeader = ({
|
|||
expanderMessages,
|
||||
}: QueryOperationRowHeaderProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
let tooltipMessage = isContentVisible
|
||||
? t('query-operation.header.collapse-row', 'Collapse query row')
|
||||
: t('query-operation.header.expand-row', 'Expand query row');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { SelectableValue } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Icon, RadioButtonList, Tooltip, useStyles2, useTheme2, PopoverContent } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { OrgRole } from 'app/types';
|
||||
|
||||
import { getStyles } from './styles';
|
||||
|
|
|
@ -2,11 +2,10 @@ import { cx } from '@emotion/css';
|
|||
import { FormEvent, memo } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Checkbox, Portal, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/internal';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { getStyles } from './styles';
|
||||
|
||||
interface RoleMenuGroupsOptionProps {
|
||||
|
@ -48,7 +47,7 @@ export const RoleMenuGroupOption = memo(
|
|||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
const customStyles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const wrapperClassName = cx(
|
||||
styles.option,
|
||||
isFocused && styles.optionFocused,
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { cx } from '@emotion/css';
|
||||
import { forwardRef, FormEvent } from 'react';
|
||||
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Checkbox, Icon, Tooltip, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/internal';
|
||||
import { Role } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { getStyles } from './styles';
|
||||
|
||||
interface RoleMenuOptionProps {
|
||||
|
@ -25,6 +24,7 @@ export const RoleMenuOption = forwardRef<HTMLDivElement, React.PropsWithChildren
|
|||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
const customStyles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
disabled = disabled || mapped;
|
||||
let disabledMessage = '';
|
||||
if (disabled) {
|
||||
|
|
|
@ -3,9 +3,9 @@ import { FormEvent, HTMLProps, useEffect, useRef } from 'react';
|
|||
import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2, getInputStyles, sharedInputStyle, Tooltip, Icon, Spinner } from '@grafana/ui';
|
||||
import { getFocusStyles } from '@grafana/ui/internal';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Role } from '../../../types';
|
||||
|
||||
|
@ -44,6 +44,7 @@ export const RolePickerInput = ({
|
|||
}: InputProps): JSX.Element => {
|
||||
const styles = useStyles2(getRolePickerInputStyles, false, !!isFocused, !!disabled, false, width);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const { t } = useTranslate();
|
||||
|
||||
useEffect(() => {
|
||||
if (isFocused) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { css, cx } from '@emotion/css';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Button, ScrollContainer, Stack, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/internal';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { OrgRole, Role } from 'app/types';
|
||||
|
||||
import { BuiltinRoleSelector } from './BuiltinRoleSelector';
|
||||
|
@ -138,6 +138,8 @@ export const RolePickerMenu = ({
|
|||
});
|
||||
}, [options]);
|
||||
|
||||
const { t } = useTranslate();
|
||||
|
||||
const getSelectedGroupOptions = (group: string) => {
|
||||
const selectedGroupOptions = [];
|
||||
for (const role of selectedOptions) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { cx } from '@emotion/css';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Button, ScrollContainer, Stack, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/internal';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { Role } from 'app/types';
|
||||
|
||||
import { RoleMenuOption } from './RoleMenuOption';
|
||||
|
@ -30,7 +30,7 @@ export const RolePickerSubMenu = ({
|
|||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
const customStyles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onClearInternal = async () => {
|
||||
if (onClear) {
|
||||
onClear();
|
||||
|
|
|
@ -3,11 +3,10 @@ import { useState } from 'react';
|
|||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2, Badge, Stack } from '@grafana/ui';
|
||||
import { OrgUser } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { RolePickerDrawer } from './RolePickerDrawer';
|
||||
|
||||
export interface Props {
|
||||
|
@ -28,6 +27,7 @@ export const RolePickerBadges = ({ disabled, user }: Props) => {
|
|||
roles: user.roles,
|
||||
},
|
||||
});
|
||||
const { t } = useTranslate();
|
||||
const { watch } = methods;
|
||||
|
||||
const drawerControl = () => {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
|
||||
import { toOption } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Drawer, Field, RadioButtonGroup, TextLink } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { OrgRole } from 'app/types';
|
||||
|
||||
const roleOptions = Object.keys(OrgRole).map(toOption);
|
||||
|
@ -29,6 +29,8 @@ export const RolePickerDrawer = ({ onClose }: Props) => {
|
|||
const methods = useFormContext();
|
||||
const { control, getValues, setValue } = methods;
|
||||
const [name, roles] = getValues(['name', 'roles']);
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<Drawer title={name} subtitle={drawerSubtitle} onClose={onClose}>
|
||||
<Field label={t('role-picker-drawer.basic-roles.label', 'Basic Roles')}>
|
||||
|
|
|
@ -6,10 +6,10 @@ import { useAsync } from 'react-use';
|
|||
|
||||
import { AppEvents, GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { ActionMeta, AsyncVirtualizedSelect, Input, InputActionMeta, useStyles2 } from '@grafana/ui';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { createFolder, getFolderByUid, searchFolders } from 'app/features/manage-dashboards/state/actions';
|
||||
import { DashboardSearchHit } from 'app/features/search/types';
|
||||
|
@ -281,6 +281,8 @@ export function OldFolderPicker(props: Props) {
|
|||
[customAdd?.disallowValues, customAdd?.isAllowedValue, newFolderValue, createNewFolder, folder?.title, rootName]
|
||||
);
|
||||
|
||||
const { t } = useTranslate();
|
||||
|
||||
const onNewFolderChange = (e: FormEvent<HTMLInputElement>) => {
|
||||
const value = e.currentTarget.value;
|
||||
setNewFolderValue(value);
|
||||
|
|
|
@ -2,12 +2,11 @@ import { useEffect, useState } from 'react';
|
|||
import { useAsyncFn } from 'react-use';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { AsyncSelect } from '@grafana/ui';
|
||||
import { Organization, UserOrg } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export type OrgSelectItem = SelectableValue<Organization>;
|
||||
|
||||
export interface Props {
|
||||
|
@ -50,6 +49,7 @@ export function OrgPicker({ onSelected, className, inputId, autoFocus, excludeOr
|
|||
return allOrgs;
|
||||
}
|
||||
});
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<AsyncSelect
|
||||
|
|
|
@ -3,12 +3,11 @@ import { isNil } from 'lodash';
|
|||
import { Component } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { AsyncSelect } from '@grafana/ui';
|
||||
import { ServiceAccountDTO, ServiceAccountsState } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface Props {
|
||||
onSelected: (user: SelectableValue<ServiceAccountDTO>) => void;
|
||||
className?: string;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { useAsync } from 'react-use';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { Icon, Select } from '@grafana/ui';
|
||||
import { DEFAULT_SORT } from 'app/features/search/constants';
|
||||
import { getGrafanaSearcher } from 'app/features/search/service/searcher';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface Props {
|
||||
onChange: (sortValue: SelectableValue) => void;
|
||||
value?: string;
|
||||
|
@ -29,6 +28,7 @@ export function SortPicker({ onChange, value, placeholder, filter, getSortOption
|
|||
}
|
||||
return vals;
|
||||
}, [getSortOptions, filter]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
if (options.loading) {
|
||||
return null;
|
||||
|
|
|
@ -3,12 +3,11 @@ import { isNil } from 'lodash';
|
|||
import { Component } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { AsyncSelect } from '@grafana/ui';
|
||||
import { Team } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface Props {
|
||||
onSelected: (team: SelectableValue<Team>) => void;
|
||||
className?: string;
|
||||
|
|
|
@ -3,12 +3,11 @@ import { isNil } from 'lodash';
|
|||
import { Component } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { AsyncSelect } from '@grafana/ui';
|
||||
import { OrgUser } from 'app/types';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
export interface Props {
|
||||
onSelected: (user: SelectableValue<OrgUser>) => void;
|
||||
className?: string;
|
||||
|
|
|
@ -4,7 +4,8 @@ import * as React from 'react';
|
|||
|
||||
import { FeatureState, ThemeRegistryItem } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { PSEUDO_LOCALE } from '@grafana/i18n';
|
||||
import { PSEUDO_LOCALE, Trans } from '@grafana/i18n';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { Preferences as UserPreferencesDTO } from '@grafana/schema/src/raw/preferences/x/preferences_types.gen';
|
||||
import {
|
||||
|
@ -23,7 +24,6 @@ import {
|
|||
isWeekStart,
|
||||
} from '@grafana/ui';
|
||||
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { LANGUAGES } from 'app/core/internationalization/constants';
|
||||
import { LOCALES } from 'app/core/internationalization/locales';
|
||||
import { PreferencesService } from 'app/core/services/PreferencesService';
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, LinkButton, Stack } from '@grafana/ui';
|
||||
import { getConfig } from 'app/core/config';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { w3cStandardEmailValidator } from 'app/features/admin/utils';
|
||||
|
||||
|
@ -36,7 +36,7 @@ export const SignupPage = ({ queryParams }: Props) => {
|
|||
register,
|
||||
getValues,
|
||||
} = useForm<SignupDTO>({ defaultValues: { email: queryParams.email, code: queryParams.code } });
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onSubmit = async (formData: SignupDTO) => {
|
||||
if (formData.name === '') {
|
||||
delete formData.name;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, Legend, Container, LinkButton, Stack } from '@grafana/ui';
|
||||
import { getConfig } from 'app/core/config';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { w3cStandardEmailValidator } from 'app/features/admin/utils';
|
||||
|
||||
interface EmailDTO {
|
||||
|
@ -20,7 +20,7 @@ export const VerifyEmail = () => {
|
|||
formState: { errors },
|
||||
} = useForm<EmailDTO>();
|
||||
const [emailSent, setEmailSent] = useState(false);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onSubmit = (formModel: EmailDTO) => {
|
||||
getBackendSrv()
|
||||
.post('/api/user/signup', formModel)
|
||||
|
|
|
@ -3,8 +3,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { components, MultiValueRemoveProps } from 'react-select';
|
||||
|
||||
import { escapeStringForRegex, GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Icon, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { TagBadge, getStyles as getTagBadgeStyles } from './TagBadge';
|
||||
import { TagOption, TagSelectOption } from './TagOption';
|
||||
|
@ -55,7 +55,7 @@ export const TagFilter = ({
|
|||
|
||||
// Necessary to force re-render to keep tag options up to date / relevant
|
||||
const selectKey = useMemo(() => tags.join(), [tags]);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onLoadOptions = useCallback(async () => {
|
||||
const options = await tagOptions();
|
||||
return options.map((option) => {
|
||||
|
|
|
@ -2,10 +2,9 @@ import { css, cx } from '@emotion/css';
|
|||
import { OptionProps } from 'react-select';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { t } from '../../internationalization';
|
||||
|
||||
import { TagBadge } from './TagBadge';
|
||||
|
||||
export interface TagSelectOption {
|
||||
|
@ -16,7 +15,7 @@ export interface TagSelectOption {
|
|||
|
||||
export const TagOption = ({ data, className, label, isFocused, innerProps }: OptionProps<TagSelectOption>) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<div
|
||||
className={cx(styles.option, isFocused && styles.optionFocused)}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { css, cx } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2, ThemeContext } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Box, Divider, Icon, Stack, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { Trans } from '../../internationalization';
|
||||
import { Branding } from '../Branding/Branding';
|
||||
|
||||
interface ThemePreviewProps {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { css } from '@emotion/css';
|
||||
|
||||
import { FeatureState, GrafanaTheme2, ThemeRegistryItem } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { TFunction } from '@grafana/i18n/internal';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { Drawer, FeatureBadge, RadioButtonDot, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { changeTheme } from 'app/core/services/theme';
|
||||
|
||||
import { ThemePreview } from '../Theme/ThemePreview';
|
||||
|
@ -18,7 +19,7 @@ export function ThemeSelectorDrawer({ onClose }: Props) {
|
|||
const styles = useStyles2(getStyles);
|
||||
const themes = getSelectableThemes();
|
||||
const currentTheme = useTheme2();
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onChange = (theme: ThemeRegistryItem) => {
|
||||
reportInteraction('grafana_preferences_theme_changed', {
|
||||
toTheme: theme.id,
|
||||
|
@ -70,8 +71,9 @@ interface ThemeCardProps {
|
|||
}
|
||||
|
||||
function ThemeCard({ themeOption, isExperimental, isSelected, onSelect }: ThemeCardProps) {
|
||||
const { t } = useTranslate();
|
||||
const theme = themeOption.build();
|
||||
const label = getTranslatedThemeName(themeOption);
|
||||
const label = getTranslatedThemeName(themeOption, t);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
return (
|
||||
|
@ -126,7 +128,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
|||
};
|
||||
};
|
||||
|
||||
function getTranslatedThemeName(theme: ThemeRegistryItem) {
|
||||
function getTranslatedThemeName(theme: ThemeRegistryItem, t: TFunction) {
|
||||
switch (theme.id) {
|
||||
case 'dark':
|
||||
return t('shared.preferences.theme.dark-label', 'Dark');
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { uniqBy } from 'lodash';
|
||||
|
||||
import { AppEvents, TimeRange, isDateTime, rangeUtil } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { TimeRangePickerProps, TimeRangePicker } from '@grafana/ui';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { LocalStorageValueProvider } from '../LocalStorageValueProvider';
|
||||
|
||||
|
@ -21,6 +21,8 @@ interface TimePickerHistoryItem {
|
|||
type LSTimePickerHistoryItem = TimePickerHistoryItem | TimeRange;
|
||||
|
||||
export const TimePickerWithHistory = (props: Props) => {
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<LocalStorageValueProvider<LSTimePickerHistoryItem[]> storageKey={LOCAL_STORAGE_KEY} defaultValue={[]}>
|
||||
{(rawValues, onSaveToStore) => {
|
||||
|
|
|
@ -2,9 +2,9 @@ import { css, cx } from '@emotion/css';
|
|||
import { HTMLAttributes, useEffect } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { reportExperimentView } from '@grafana/runtime';
|
||||
import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
type ComponentSize = 'sm' | 'md';
|
||||
|
||||
|
@ -32,6 +32,8 @@ export const UpgradeBox = ({
|
|||
reportExperimentView(`feature-highlights-${featureId}`, 'test', eventVariant);
|
||||
}, [eventVariant, featureId]);
|
||||
|
||||
const { t } = useTranslate();
|
||||
|
||||
return (
|
||||
<div className={cx(styles.box, className)} {...htmlProps}>
|
||||
<Icon name={'rocket'} className={styles.icon} />
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { css, cx } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { Box, Icon, Text, useStyles2 } from '@grafana/ui';
|
||||
import config from 'app/core/config';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
interface StrongPasswordValidation {
|
||||
message: string;
|
||||
|
|
|
@ -2,8 +2,8 @@ import { identity } from 'lodash';
|
|||
import { useState } from 'react';
|
||||
|
||||
import { dateTimeFormatTimeAgo } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Box, Button, Divider, EmptyState, Icon, Stack, Text } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { DiffGroup } from 'app/features/dashboard-scene/settings/version-history/DiffGroup';
|
||||
import { DiffViewer } from 'app/features/dashboard-scene/settings/version-history/DiffViewer';
|
||||
import { jsonDiff } from 'app/features/dashboard-scene/settings/version-history/utils';
|
||||
|
@ -66,7 +66,7 @@ export const VersionHistoryComparison = <T extends DiffArgument>({
|
|||
const diff = jsonDiff(preprocessVersion(oldVersion), preprocessVersion(newVersion));
|
||||
const noHumanReadableDiffs = Object.entries(diff).length === 0;
|
||||
const [showJsonDiff, setShowJsonDiff] = useState(noHumanReadableDiffs);
|
||||
|
||||
const { t } = useTranslate();
|
||||
return (
|
||||
<Stack gap={2} direction="column">
|
||||
<Box>
|
||||
|
|
|
@ -2,11 +2,12 @@ import { css } from '@emotion/css';
|
|||
import { useMemo } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { TFunction } from '@grafana/i18n/internal';
|
||||
import { Grid, Modal, useStyles2, Text } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getModKey } from 'app/core/utils/browser';
|
||||
|
||||
const getShortcuts = (modKey: string) => {
|
||||
const getShortcuts = (modKey: string, t: TFunction) => {
|
||||
return [
|
||||
{
|
||||
category: t('help-modal.shortcuts-category.global', 'Global'),
|
||||
|
@ -149,9 +150,10 @@ export interface HelpModalProps {
|
|||
|
||||
export const HelpModal = ({ onDismiss }: HelpModalProps): JSX.Element => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { t } = useTranslate();
|
||||
|
||||
const modKey = useMemo(() => getModKey(), []);
|
||||
const shortcuts = useMemo(() => getShortcuts(modKey), [modKey]);
|
||||
const shortcuts = useMemo(() => getShortcuts(modKey, t), [modKey, t]);
|
||||
return (
|
||||
<Modal title={t('help-modal.title', 'Shortcuts')} isOpen onDismiss={onDismiss} onClickBackdrop={onDismiss}>
|
||||
<Grid columns={{ xs: 1, sm: 2 }} gap={3} tabIndex={0}>
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
import { ReactElement } from 'react';
|
||||
|
||||
import { Trans as TransCore, TransProps } from '@grafana/i18n';
|
||||
import { changeLanguage as changeLanguageCore, initTranslations, t as tCore } from '@grafana/i18n/internal';
|
||||
|
||||
import { NAMESPACES, VALID_LANGUAGES } from './constants';
|
||||
import { loadTranslations } from './loadTranslations';
|
||||
|
||||
// This is a placeholder so we can put a 'comment' in the message json files.
|
||||
// Starts with an underscore so it's sorted to the top of the file. Even though it is in a comment the following line is still extracted
|
||||
// t('_comment', 'The code is the source of truth for English phrases. They should be updated in the components directly, and additional plurals specified in this file.');
|
||||
|
||||
export async function initializeI18n(language: string): Promise<{ language: string | undefined }> {
|
||||
return initTranslations({ language, ns: NAMESPACES, module: loadTranslations });
|
||||
}
|
||||
|
||||
export function changeLanguage(locale: string) {
|
||||
const validLocale = VALID_LANGUAGES.includes(locale) ? locale : undefined;
|
||||
return changeLanguageCore(validLocale);
|
||||
}
|
||||
|
||||
export const Trans = (props: TransProps): ReactElement => <TransCore {...props} />;
|
||||
|
||||
/**
|
||||
* This is a simple wrapper over i18n.t() to provide default namespaces and enforce a consistent API.
|
||||
* Note: Don't use this in the top level module scope. This wrapper needs initialization, which is done during Grafana
|
||||
* startup, and it will throw if used before.
|
||||
*
|
||||
* This will soon be deprecated in favor of useTranslate()
|
||||
* @param id ID of the translation string
|
||||
* @param defaultMessage Default message to use if the translation is missing
|
||||
* @param values Values to be interpolated into the string
|
||||
*/
|
||||
export const t = (id: string, defaultMessage: string, values?: Record<string, unknown>) =>
|
||||
tCore(id, defaultMessage, values);
|
|
@ -3,10 +3,10 @@ import { ErrorInfo, useEffect } from 'react';
|
|||
import { useLocation } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { GrafanaTheme2, locationUtil, PageLayoutType } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Button, ErrorWithStack, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { Page } from '../components/Page/Page';
|
||||
import { t, Trans } from '../internationalization';
|
||||
|
||||
interface Props {
|
||||
error: Error | null;
|
||||
|
@ -24,6 +24,7 @@ export function GrafanaRouteError({ error, errorInfo }: Props) {
|
|||
window.location.href = locationUtil.getUrlForPartial(location, { chunkNotFound: true });
|
||||
}
|
||||
}, [location, isChunkLoadingError]);
|
||||
const { t } = useTranslate();
|
||||
|
||||
// Would be good to know the page navId here but needs a pretty big refactoring
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { t } from '@grafana/i18n/internal';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
// Maps the ID of the nav item to a translated phrase to later pass to <Trans />
|
||||
// Because the navigation content is dynamic (defined in the backend), we can not use
|
||||
|
|
|
@ -8,10 +8,10 @@ import {
|
|||
urlUtil,
|
||||
serializeStateToUrlParam,
|
||||
} from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { createErrorNotification, createWarningNotification } from 'app/core/copy/appNotification';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { dispatch } from 'app/store/store';
|
||||
import { RichHistoryQuery } from 'app/types/explore';
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import memoizeOne from 'memoize-one';
|
||||
|
||||
import { AbsoluteTimeRange, LogRowModel, UrlQueryMap } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n/internal';
|
||||
import { getBackendSrv, config, locationService } from '@grafana/runtime';
|
||||
import { sceneGraph, SceneTimeRangeLike, VizPanel } from '@grafana/scenes';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
|
@ -10,7 +11,6 @@ import { getDashboardUrl } from 'app/features/dashboard-scene/utils/getDashboard
|
|||
import { dispatch } from 'app/store/store';
|
||||
|
||||
import { ShareLinkConfiguration } from '../../features/dashboard-scene/sharing/ShareButton/utils';
|
||||
import { t } from '../internationalization';
|
||||
|
||||
import { copyStringToClipboard } from './explore';
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { css } from '@emotion/css';
|
|||
import { memo } from 'react';
|
||||
|
||||
import { Action, GrafanaTheme2, httpMethodOptions, HttpRequestMethod, VariableSuggestion } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import {
|
||||
Switch,
|
||||
Field,
|
||||
|
@ -13,7 +14,6 @@ import {
|
|||
ColorPicker,
|
||||
useTheme2,
|
||||
} from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { HTMLElementType, SuggestionsInput } from '../transformers/suggestionsInput/SuggestionsInput';
|
||||
|
||||
|
@ -32,7 +32,7 @@ const LABEL_WIDTH = 13;
|
|||
export const ActionEditor = memo(({ index, value, onChange, suggestions, showOneClick }: ActionEditorProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
|
||||
const { t } = useTranslate();
|
||||
const onTitleChange = (title: string) => {
|
||||
onChange(index, { ...value, title });
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { useState } from 'react';
|
||||
|
||||
import { Action, DataFrame, VariableSuggestion } from '@grafana/data';
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Button, Modal } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ActionEditor } from './ActionEditor';
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import { css } from '@emotion/css';
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { contentTypeOptions, GrafanaTheme2, VariableSuggestion } from '@grafana/data';
|
||||
import { useTranslate } from '@grafana/i18n';
|
||||
import { IconButton, Input, Stack, Select, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { SuggestionsInput } from '../transformers/suggestionsInput/SuggestionsInput';
|
||||
|
||||
|
@ -33,6 +33,7 @@ export const ParamsEditor = ({ value, onChange, suggestions, contentTypeHeader =
|
|||
|
||||
// forces re-init of first SuggestionsInput(s), since they are stateful and don't respond to 'value' prop changes to be able to clear them :(
|
||||
const [entryKey, setEntryKey] = useState(Math.random().toString());
|
||||
const { t } = useTranslate();
|
||||
|
||||
const changeParamValue = (paramValue: string) => {
|
||||
setParamValue(paramValue);
|
||||
|
|
|
@ -4,10 +4,10 @@ import { useParams } from 'react-router-dom-v5-compat';
|
|||
import { useAsyncFn } from 'react-use';
|
||||
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Field, Input, Button, Legend, Alert } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { OrgUser, AccessControlAction, OrgRole } from 'app/types';
|
||||
|
||||
import { OrgUsersTable } from './Users/OrgUsersTable';
|
||||
|
@ -51,6 +51,8 @@ const AdminEditOrgPage = () => {
|
|||
fetchOrgUsers(page);
|
||||
}, [fetchOrg, fetchOrgUsers, page]);
|
||||
|
||||
const { t } = useTranslate();
|
||||
|
||||
const onUpdateOrgName = async ({ orgName }: OrgNameDTO) => {
|
||||
await updateOrgName(orgName, orgId);
|
||||
};
|
||||
|
|
|
@ -3,9 +3,9 @@ import { useState } from 'react';
|
|||
import { useAsync } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { useStyles2, Icon } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { getTogglesAPI } from './AdminFeatureTogglesAPI';
|
||||
import { AdminFeatureTogglesTable } from './AdminFeatureTogglesTable';
|
||||
|
@ -15,7 +15,7 @@ export default function AdminFeatureTogglesPage() {
|
|||
const togglesApi = getTogglesAPI();
|
||||
const featureState = useAsync(() => togglesApi.getFeatureToggles(), [reload]);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { t } = useTranslate();
|
||||
const handleUpdateSuccess = () => {
|
||||
setReload(reload + 1);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useState, useRef } from 'react';
|
||||
|
||||
import { Trans, useTranslate } from '@grafana/i18n';
|
||||
import { Switch, InteractiveTable, Tooltip, type CellProps, Button, ConfirmModal, type SortByFn } from '@grafana/ui';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
|
||||
import { FeatureToggle, getTogglesAPI } from './AdminFeatureTogglesAPI';
|
||||
|
||||
|
@ -37,6 +37,7 @@ export function AdminFeatureTogglesTable({ featureToggles, allowEditing, onUpdat
|
|||
const [localToggles, setLocalToggles] = useState<FeatureToggle[]>(featureToggles);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [showSaveModel, setShowSaveModal] = useState(false);
|
||||
const { t } = useTranslate();
|
||||
const togglesApi = getTogglesAPI();
|
||||
|
||||
const handleToggleChange = (toggle: FeatureToggle, newValue: boolean) => {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue