mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
IconName: Move to grafana/data and use type on NavModelItem (#55013)
* IconName: Allow strings * Moving to grafana/data and adding type to NavModelItem * Removed any type * ts fix
This commit is contained in:
parent
64869e3d90
commit
d59bb1e4c2
@ -6,7 +6,7 @@ import { DataSourceInstanceSettings } from './datasource';
|
||||
import { FeatureToggles } from './featureToggles.gen';
|
||||
import { PanelPluginMeta } from './panel';
|
||||
|
||||
import { GrafanaTheme, NavLinkDTO, OrgRole } from '.';
|
||||
import { GrafanaTheme, IconName, NavLinkDTO, OrgRole } from '.';
|
||||
|
||||
/**
|
||||
* Describes the build information that will be available via the Grafana configuration.
|
||||
@ -104,7 +104,7 @@ export type OAuth =
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type OAuthSettings = Partial<Record<OAuth, { name: string; icon?: string }>>;
|
||||
export type OAuthSettings = Partial<Record<OAuth, { name: string; icon?: IconName }>>;
|
||||
|
||||
/** Current user info included in bootData
|
||||
*
|
||||
|
205
packages/grafana-data/src/types/icon.ts
Normal file
205
packages/grafana-data/src/types/icon.ts
Normal file
@ -0,0 +1,205 @@
|
||||
export const availableIconsIndex = {
|
||||
google: true,
|
||||
microsoft: true,
|
||||
github: true,
|
||||
gitlab: true,
|
||||
okta: true,
|
||||
anchor: true,
|
||||
'angle-double-down': true,
|
||||
'angle-double-right': true,
|
||||
'angle-double-up': true,
|
||||
'angle-down': true,
|
||||
'angle-left': true,
|
||||
'angle-right': true,
|
||||
'angle-up': true,
|
||||
apps: true,
|
||||
arrow: true,
|
||||
'arrow-down': true,
|
||||
'arrow-from-right': true,
|
||||
'arrow-left': true,
|
||||
'arrow-random': true,
|
||||
'arrow-right': true,
|
||||
'arrow-up': true,
|
||||
'arrows-h': true,
|
||||
'arrows-v': true,
|
||||
backward: true,
|
||||
bars: true,
|
||||
bell: true,
|
||||
'bell-slash': true,
|
||||
bolt: true,
|
||||
book: true,
|
||||
bookmark: true,
|
||||
'book-open': true,
|
||||
'brackets-curly': true,
|
||||
bug: true,
|
||||
building: true,
|
||||
'calculator-alt': true,
|
||||
'calendar-alt': true,
|
||||
camera: true,
|
||||
capture: true,
|
||||
'channel-add': true,
|
||||
'chart-line': true,
|
||||
check: true,
|
||||
'check-circle': true,
|
||||
'check-square': true,
|
||||
circle: true,
|
||||
'clipboard-alt': true,
|
||||
'clock-nine': true,
|
||||
cloud: true,
|
||||
'cloud-download': true,
|
||||
'cloud-upload': true,
|
||||
'code-branch': true,
|
||||
cog: true,
|
||||
columns: true,
|
||||
'comment-alt': true,
|
||||
'comment-alt-message': true,
|
||||
'comment-alt-share': true,
|
||||
'comments-alt': true,
|
||||
compass: true,
|
||||
copy: true,
|
||||
'credit-card': true,
|
||||
cube: true,
|
||||
dashboard: true,
|
||||
database: true,
|
||||
'document-info': true,
|
||||
'download-alt': true,
|
||||
draggabledots: true,
|
||||
edit: true,
|
||||
'ellipsis-v': true,
|
||||
envelope: true,
|
||||
'exchange-alt': true,
|
||||
'exclamation-triangle': true,
|
||||
'exclamation-circle': true,
|
||||
'external-link-alt': true,
|
||||
eye: true,
|
||||
'eye-slash': true,
|
||||
'ellipsis-h': true,
|
||||
'fa fa-spinner': true,
|
||||
favorite: true,
|
||||
'file-alt': true,
|
||||
'file-blank': true,
|
||||
'file-copy-alt': true,
|
||||
filter: true,
|
||||
folder: true,
|
||||
font: true,
|
||||
fire: true,
|
||||
'folder-open': true,
|
||||
'folder-plus': true,
|
||||
'folder-upload': true,
|
||||
forward: true,
|
||||
'gf-bar-alignment-after': true,
|
||||
'gf-bar-alignment-before': true,
|
||||
'gf-bar-alignment-center': true,
|
||||
'gf-glue': true,
|
||||
'gf-grid': true,
|
||||
'gf-interpolation-linear': true,
|
||||
'gf-interpolation-smooth': true,
|
||||
'gf-interpolation-step-after': true,
|
||||
'gf-interpolation-step-before': true,
|
||||
'gf-landscape': true,
|
||||
'gf-layout-simple': true,
|
||||
'gf-logs': true,
|
||||
'gf-portrait': true,
|
||||
'gf-service-account': true,
|
||||
grafana: true,
|
||||
'graph-bar': true,
|
||||
heart: true,
|
||||
'heart-break': true,
|
||||
history: true,
|
||||
home: true,
|
||||
'home-alt': true,
|
||||
'horizontal-align-center': true,
|
||||
'horizontal-align-left': true,
|
||||
'horizontal-align-right': true,
|
||||
hourglass: true,
|
||||
import: true,
|
||||
info: true,
|
||||
'info-circle': true,
|
||||
'key-skeleton-alt': true,
|
||||
keyboard: true,
|
||||
'layer-group': true,
|
||||
'library-panel': true,
|
||||
'line-alt': true,
|
||||
link: true,
|
||||
'list-ui-alt': true,
|
||||
'list-ul': true,
|
||||
lock: true,
|
||||
'map-marker': true,
|
||||
message: true,
|
||||
minus: true,
|
||||
'minus-circle': true,
|
||||
'mobile-android': true,
|
||||
monitor: true,
|
||||
palette: true,
|
||||
'panel-add': true,
|
||||
pause: true,
|
||||
pen: true,
|
||||
percentage: true,
|
||||
play: true,
|
||||
plug: true,
|
||||
plus: true,
|
||||
'plus-circle': true,
|
||||
'plus-square': true,
|
||||
power: true,
|
||||
'presentation-play': true,
|
||||
process: true,
|
||||
'question-circle': true,
|
||||
'record-audio': true,
|
||||
repeat: true,
|
||||
rocket: true,
|
||||
'ruler-combined': true,
|
||||
save: true,
|
||||
search: true,
|
||||
'search-minus': true,
|
||||
'search-plus': true,
|
||||
'share-alt': true,
|
||||
shield: true,
|
||||
'shield-exclamation': true,
|
||||
signal: true,
|
||||
signin: true,
|
||||
signout: true,
|
||||
sitemap: true,
|
||||
slack: true,
|
||||
'sliders-v-alt': true,
|
||||
'sort-amount-down': true,
|
||||
'sort-amount-up': true,
|
||||
'square-shape': true,
|
||||
star: true,
|
||||
'step-backward': true,
|
||||
'stopwatch-slash': true,
|
||||
sync: true,
|
||||
table: true,
|
||||
'tag-alt': true,
|
||||
'text-fields': true,
|
||||
times: true,
|
||||
'toggle-on': true,
|
||||
'trash-alt': true,
|
||||
unlock: true,
|
||||
upload: true,
|
||||
user: true,
|
||||
'users-alt': true,
|
||||
'vertical-align-bottom': true,
|
||||
'vertical-align-center': true,
|
||||
'vertical-align-top': true,
|
||||
'wrap-text': true,
|
||||
rss: true,
|
||||
x: true,
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof availableIconsIndex;
|
||||
|
||||
export function isIconName(iconName: unknown): iconName is IconName {
|
||||
if (!iconName || typeof iconName !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return iconName in availableIconsIndex;
|
||||
}
|
||||
|
||||
export function toIconName(iconName: string): IconName | undefined {
|
||||
if (isIconName(iconName)) {
|
||||
return iconName;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
@ -50,3 +50,4 @@ export type { FeatureToggles } from './featureToggles.gen';
|
||||
export * from './alerts';
|
||||
export * from './slider';
|
||||
export * from './accesscontrol';
|
||||
export * from './icon';
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
import { IconName } from './icon';
|
||||
|
||||
export interface NavLinkDTO {
|
||||
id?: string;
|
||||
text: string;
|
||||
description?: string;
|
||||
section?: NavSection;
|
||||
subTitle?: string;
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
img?: string;
|
||||
url?: string;
|
||||
target?: string;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
import { KeyValue } from './data';
|
||||
import { IconName } from './icon';
|
||||
|
||||
/** Describes plugins life cycle status */
|
||||
export enum PluginState {
|
||||
@ -158,7 +159,7 @@ export interface PluginConfigPageProps<T extends PluginMeta> {
|
||||
|
||||
export interface PluginConfigPage<T extends PluginMeta> {
|
||||
title: string; // Display
|
||||
icon?: string;
|
||||
icon?: IconName;
|
||||
id: string; // Unique, in URL
|
||||
|
||||
body: ComponentType<PluginConfigPageProps<T>>;
|
||||
|
@ -2,10 +2,9 @@ import { css, cx } from '@emotion/css';
|
||||
import { uniqueId } from 'lodash';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { GrafanaTheme2, SelectableValue, toIconName } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { toIconName } from '../../../types/icon';
|
||||
import { Icon } from '../../Icon/Icon';
|
||||
|
||||
import { RadioButtonSize, RadioButton } from './RadioButton';
|
||||
@ -74,6 +73,7 @@ export function RadioButtonGroup<T>({
|
||||
{options.map((opt, i) => {
|
||||
const isItemDisabled = disabledOptions && opt.value && disabledOptions.includes(opt.value);
|
||||
const icon = opt.icon ? toIconName(opt.icon) : undefined;
|
||||
|
||||
return (
|
||||
<RadioButton
|
||||
size={size}
|
||||
|
@ -2,10 +2,11 @@ import { css } from '@emotion/css';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import React, { ChangeEvent, useState } from 'react';
|
||||
|
||||
import { toIconName, IconName } from '@grafana/data';
|
||||
import { Input, Field, Icon } from '@grafana/ui';
|
||||
|
||||
import { useTheme2 } from '../../themes';
|
||||
import { getAvailableIcons, IconName } from '../../types';
|
||||
import { getAvailableIcons } from '../../types';
|
||||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
|
||||
import mdx from './Icon.mdx';
|
||||
@ -90,7 +91,7 @@ export const IconsOverview = () => {
|
||||
{icons
|
||||
.filter((val) => val.includes(filter))
|
||||
.map((i) => {
|
||||
return <IconWrapper name={i} key={i} />;
|
||||
return <IconWrapper name={toIconName(i)!} key={i} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,11 +2,10 @@ import { css, cx } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import SVG from 'react-inlinesvg';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2, isIconName } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
import { IconName, IconType, IconSize } from '../../types/icon';
|
||||
export { toIconName } from '../../types/icon';
|
||||
|
||||
import { cacheInitialized, initIconCache, iconRoot } from './iconBundle';
|
||||
import { getIconSubDir, getSvgSize } from './utils';
|
||||
@ -54,6 +53,10 @@ export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
|
||||
initIconCache();
|
||||
}
|
||||
|
||||
if (!isIconName(name)) {
|
||||
console.warn('Icon component passed an invalid icon name', name);
|
||||
}
|
||||
|
||||
const svgSize = getSvgSize(size);
|
||||
const svgHgt = svgSize;
|
||||
const svgWid = name?.startsWith('gf-bar-align') ? 16 : name?.startsWith('gf-interp') ? 30 : svgSize;
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Icon, toIconName } from '../Icon/Icon';
|
||||
import { toIconName } from '@grafana/data';
|
||||
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
export function parseAccessory(prefix: string | undefined) {
|
||||
const icon = prefix && prefix.match(/icon-/g) && toIconName(prefix.replace(/icon-/g, ''));
|
||||
|
@ -3,10 +3,10 @@ import { action } from '@storybook/addon-actions';
|
||||
import { Meta, Story } from '@storybook/react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { SelectableValue, toIconName } from '@grafana/data';
|
||||
import { Icon, Select, AsyncSelect, MultiSelect, AsyncMultiSelect } from '@grafana/ui';
|
||||
|
||||
import { getAvailableIcons, toIconName } from '../../types';
|
||||
import { getAvailableIcons } from '../../types';
|
||||
import { withCenteredStory, withHorizontallyCenteredStory } from '../../utils/storybook/withCenteredStory';
|
||||
|
||||
import mdx from './Select.mdx';
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { cx } from '@emotion/css';
|
||||
import React, { FC, RefCallback } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { SelectableValue, toIconName } from '@grafana/data';
|
||||
|
||||
import { useTheme2 } from '../../themes/ThemeContext';
|
||||
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
|
||||
import { Icon, toIconName } from '../Icon/Icon';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
|
||||
import { getSelectStyles } from './getSelectStyles';
|
||||
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { cx, css } from '@emotion/css';
|
||||
import { isString } from 'lodash';
|
||||
import React, { forwardRef, ButtonHTMLAttributes } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { GrafanaTheme2, IconName, isIconName } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { styleMixins, useStyles2 } from '../../themes';
|
||||
import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins';
|
||||
import { IconName, toIconName } from '../../types/icon';
|
||||
import { getPropertiesForVariant } from '../Button';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
@ -115,10 +113,8 @@ function renderIcon(icon: IconName | React.ReactNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const iconName = isString(icon) && toIconName(icon);
|
||||
|
||||
if (iconName) {
|
||||
return <Icon name={iconName} size="lg" />;
|
||||
if (isIconName(icon)) {
|
||||
return <Icon name={icon} size="lg" />;
|
||||
}
|
||||
|
||||
return icon;
|
||||
|
@ -6,7 +6,7 @@ import { AsyncSelect, Select } from './Forms/Legacy/Select/Select';
|
||||
import { Switch } from './Forms/Legacy/Switch/Switch';
|
||||
import { SecretFormField } from './SecretFormField/SecretFormField';
|
||||
|
||||
export { Icon, toIconName } from './Icon/Icon';
|
||||
export { Icon } from './Icon/Icon';
|
||||
export { IconButton, type IconButtonVariant } from './IconButton/IconButton';
|
||||
export { ConfirmButton } from './ConfirmButton/ConfirmButton';
|
||||
export { DeleteButton } from './ConfirmButton/DeleteButton';
|
||||
|
@ -1,207 +1,16 @@
|
||||
import { Field, FieldType } from '@grafana/data';
|
||||
import { availableIconsIndex, Field, FieldType, IconName } from '@grafana/data';
|
||||
|
||||
import { ComponentSize } from './size';
|
||||
|
||||
// Exported from here for backwards compatibility
|
||||
export type { IconName } from '@grafana/data';
|
||||
export { toIconName } from '@grafana/data';
|
||||
|
||||
export type IconType = 'mono' | 'default' | 'solid';
|
||||
export type IconSize = ComponentSize | 'xl' | 'xxl' | 'xxxl';
|
||||
|
||||
const avaibleBrandIcons = [
|
||||
'google' as const,
|
||||
'microsoft' as const,
|
||||
'github' as const,
|
||||
'gitlab' as const,
|
||||
'okta' as const,
|
||||
];
|
||||
|
||||
const availableIcons = [
|
||||
'anchor' as const,
|
||||
'angle-double-down' as const,
|
||||
'angle-double-right' as const,
|
||||
'angle-double-up' as const,
|
||||
'angle-down' as const,
|
||||
'angle-left' as const,
|
||||
'angle-right' as const,
|
||||
'angle-up' as const,
|
||||
'apps' as const,
|
||||
'arrow' as const,
|
||||
'arrow-down' as const,
|
||||
'arrow-from-right' as const,
|
||||
'arrow-left' as const,
|
||||
'arrow-random' as const,
|
||||
'arrow-right' as const,
|
||||
'arrow-up' as const,
|
||||
'arrows-h' as const,
|
||||
'arrows-v' as const,
|
||||
'backward' as const,
|
||||
'bars' as const,
|
||||
'bell' as const,
|
||||
'bell-slash' as const,
|
||||
'bolt' as const,
|
||||
'book' as const,
|
||||
'bookmark' as const,
|
||||
'book-open' as const,
|
||||
'brackets-curly' as const,
|
||||
'building' as const,
|
||||
'bug' as const,
|
||||
'building' as const,
|
||||
'calculator-alt' as const,
|
||||
'calendar-alt' as const,
|
||||
'camera' as const,
|
||||
'capture' as const,
|
||||
'channel-add' as const,
|
||||
'chart-line' as const,
|
||||
'check' as const,
|
||||
'check-circle' as const,
|
||||
'check-square' as const,
|
||||
'circle' as const,
|
||||
'clipboard-alt' as const,
|
||||
'clock-nine' as const,
|
||||
'cloud' as const,
|
||||
'cloud-download' as const,
|
||||
'cloud-upload' as const,
|
||||
'code-branch' as const,
|
||||
'cog' as const,
|
||||
'columns' as const,
|
||||
'comment-alt' as const,
|
||||
'comment-alt-message' as const,
|
||||
'comment-alt-share' as const,
|
||||
'comments-alt' as const,
|
||||
'compass' as const,
|
||||
'copy' as const,
|
||||
'credit-card' as const,
|
||||
'cube' as const,
|
||||
'dashboard' as const,
|
||||
'database' as const,
|
||||
'document-info' as const,
|
||||
'download-alt' as const,
|
||||
'draggabledots' as const,
|
||||
'edit' as const,
|
||||
'ellipsis-v' as const,
|
||||
'envelope' as const,
|
||||
'exchange-alt' as const,
|
||||
'exclamation-triangle' as const,
|
||||
'exclamation-circle' as const,
|
||||
'external-link-alt' as const,
|
||||
'eye' as const,
|
||||
'eye-slash' as const,
|
||||
'ellipsis-h' as const,
|
||||
'fa fa-spinner' as const,
|
||||
'favorite' as const,
|
||||
'file-alt' as const,
|
||||
'file-blank' as const,
|
||||
'file-copy-alt' as const,
|
||||
'filter' as const,
|
||||
'folder' as const,
|
||||
'font' as const,
|
||||
'fire' as const,
|
||||
'folder-open' as const,
|
||||
'folder-plus' as const,
|
||||
'folder-upload' as const,
|
||||
'forward' as const,
|
||||
'gf-bar-alignment-after' as const,
|
||||
'gf-bar-alignment-before' as const,
|
||||
'gf-bar-alignment-center' as const,
|
||||
'gf-glue' as const,
|
||||
'gf-grid' as const,
|
||||
'gf-interpolation-linear' as const,
|
||||
'gf-interpolation-smooth' as const,
|
||||
'gf-interpolation-step-after' as const,
|
||||
'gf-interpolation-step-before' as const,
|
||||
'gf-landscape' as const,
|
||||
'gf-layout-simple' as const,
|
||||
'gf-logs' as const,
|
||||
'gf-portrait' as const,
|
||||
'grafana' as const,
|
||||
'graph-bar' as const,
|
||||
'heart' as const,
|
||||
'heart-break' as const,
|
||||
'history' as const,
|
||||
'home' as const,
|
||||
'home-alt' as const,
|
||||
'horizontal-align-center' as const,
|
||||
'horizontal-align-left' as const,
|
||||
'horizontal-align-right' as const,
|
||||
'hourglass' as const,
|
||||
'import' as const,
|
||||
'info' as const,
|
||||
'info-circle' as const,
|
||||
'key-skeleton-alt' as const,
|
||||
'keyboard' as const,
|
||||
'layer-group' as const,
|
||||
'library-panel' as const,
|
||||
'line-alt' as const,
|
||||
'link' as const,
|
||||
'list-ui-alt' as const,
|
||||
'list-ul' as const,
|
||||
'lock' as const,
|
||||
'map-marker' as const,
|
||||
'message' as const,
|
||||
'minus' as const,
|
||||
'minus-circle' as const,
|
||||
'mobile-android' as const,
|
||||
'monitor' as const,
|
||||
'palette' as const,
|
||||
'panel-add' as const,
|
||||
'pause' as const,
|
||||
'pen' as const,
|
||||
'percentage' as const,
|
||||
'play' as const,
|
||||
'plug' as const,
|
||||
'plus' as const,
|
||||
'plus-circle' as const,
|
||||
'plus-square' as const,
|
||||
'power' as const,
|
||||
'presentation-play' as const,
|
||||
'process' as const,
|
||||
'question-circle' as const,
|
||||
'record-audio' as const,
|
||||
'repeat' as const,
|
||||
'rocket' as const,
|
||||
'ruler-combined' as const,
|
||||
'save' as const,
|
||||
'search' as const,
|
||||
'search-minus' as const,
|
||||
'search-plus' as const,
|
||||
'share-alt' as const,
|
||||
'shield' as const,
|
||||
'shield-exclamation' as const,
|
||||
'signal' as const,
|
||||
'signin' as const,
|
||||
'signout' as const,
|
||||
'sitemap' as const,
|
||||
'slack' as const,
|
||||
'sliders-v-alt' as const,
|
||||
'sort-amount-down' as const,
|
||||
'sort-amount-up' as const,
|
||||
'square-shape' as const,
|
||||
'star' as const,
|
||||
'step-backward' as const,
|
||||
'stopwatch-slash' as const,
|
||||
'sync' as const,
|
||||
'table' as const,
|
||||
'tag-alt' as const,
|
||||
'text-fields' as const,
|
||||
'times' as const,
|
||||
'toggle-on' as const,
|
||||
'trash-alt' as const,
|
||||
'unlock' as const,
|
||||
'upload' as const,
|
||||
'user' as const,
|
||||
'users-alt' as const,
|
||||
'vertical-align-bottom' as const,
|
||||
'vertical-align-center' as const,
|
||||
'vertical-align-top' as const,
|
||||
'wrap-text' as const,
|
||||
'rss' as const,
|
||||
'x' as const,
|
||||
];
|
||||
|
||||
// function remains for backwards compatibility
|
||||
export const getAvailableIcons = () => availableIcons;
|
||||
|
||||
type BrandIconNames = typeof avaibleBrandIcons;
|
||||
|
||||
export type IconName = ReturnType<typeof getAvailableIcons>[number] | BrandIconNames[number];
|
||||
export const getAvailableIcons = () => Object.keys(availableIconsIndex);
|
||||
|
||||
/** Get the icon for a given field type */
|
||||
export function getFieldTypeIcon(field?: Field): IconName {
|
||||
@ -225,18 +34,3 @@ export function getFieldTypeIcon(field?: Field): IconName {
|
||||
}
|
||||
return 'question-circle';
|
||||
}
|
||||
|
||||
function isValidIconName(iconName: string): iconName is IconName {
|
||||
const namedIcons: string[] = availableIcons;
|
||||
const brandIcons: string[] = avaibleBrandIcons;
|
||||
|
||||
return namedIcons.includes(iconName) || brandIcons.includes(iconName);
|
||||
}
|
||||
|
||||
export function toIconName(iconName: string): IconName | undefined {
|
||||
if (isValidIconName(iconName)) {
|
||||
return iconName;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ export function getNotFoundNav(): NavModel {
|
||||
}
|
||||
|
||||
export function getWarningNav(text: string, subTitle?: string): NavModel {
|
||||
const node = {
|
||||
const node: NavModelItem = {
|
||||
text,
|
||||
subTitle,
|
||||
icon: 'exclamation-triangle',
|
||||
|
@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { toIconName, useStyles2 } from '@grafana/ui';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { useNavModel } from 'app/core/hooks/useNavModel';
|
||||
|
||||
@ -28,7 +28,7 @@ export function NavLandingPage({ navId }: Props) {
|
||||
<NavLandingPageCard
|
||||
key={child.id}
|
||||
description={child.description}
|
||||
icon={child.icon ? toIconName(child.icon) : undefined}
|
||||
icon={child.icon}
|
||||
text={child.text}
|
||||
url={child.url ?? ''}
|
||||
/>
|
||||
@ -46,7 +46,7 @@ export function NavLandingPage({ navId }: Props) {
|
||||
<NavLandingPageCard
|
||||
key={child.id}
|
||||
description={child.description}
|
||||
icon={child.icon ? toIconName(child.icon) : undefined}
|
||||
icon={child.icon}
|
||||
text={child.text}
|
||||
url={child.url ?? ''}
|
||||
/>
|
||||
|
@ -6,7 +6,7 @@ import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { GrafanaTheme2, NavSection } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { Dropdown, FilterInput, Icon, Tooltip, useStyles2, toIconName } from '@grafana/ui';
|
||||
import { Dropdown, FilterInput, Icon, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { useSearchQuery } from 'app/features/search/hooks/useSearchQuery';
|
||||
import { StoreState } from 'app/types';
|
||||
@ -46,7 +46,6 @@ export function TopSearchBar() {
|
||||
|
||||
const profileNode = configItems.find((item) => item.id === 'profile');
|
||||
const signInNode = configItems.find((item) => item.id === 'signin');
|
||||
const signInIconName = signInNode?.icon && toIconName(signInNode.icon);
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
@ -78,7 +77,7 @@ export function TopSearchBar() {
|
||||
{signInNode && (
|
||||
<Tooltip placement="bottom" content="Sign in">
|
||||
<a className={styles.actionItem} href={signInNode.url} target={signInNode.target}>
|
||||
{signInIconName && <Icon name={signInIconName} size="lg" />}
|
||||
{signInNode.icon && <Icon name={signInNode.icon} size="lg" />}
|
||||
</a>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
@ -3,7 +3,7 @@ import { pickBy } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { GrafanaTheme, GrafanaTheme2, DEFAULT_SAML_NAME } from '@grafana/data';
|
||||
import { Icon, IconName, LinkButton, toIconName, useStyles, useTheme2, VerticalGroup } from '@grafana/ui';
|
||||
import { Icon, IconName, LinkButton, useStyles, useTheme2, VerticalGroup } from '@grafana/ui';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export interface LoginService {
|
||||
@ -63,13 +63,13 @@ const loginServices: () => LoginServices = () => {
|
||||
bgColor: '#2f2f2f',
|
||||
enabled: oauthEnabled && Boolean(config.oauth.okta),
|
||||
name: config.oauth?.okta?.name || 'Okta',
|
||||
icon: (config.oauth?.okta?.icon && toIconName(config.oauth.okta.icon)) || 'okta',
|
||||
icon: config.oauth?.okta?.icon ?? ('okta' as const),
|
||||
},
|
||||
oauth: {
|
||||
bgColor: '#262628',
|
||||
enabled: oauthEnabled && Boolean(config.oauth.generic_oauth),
|
||||
name: config.oauth?.generic_oauth?.name || 'OAuth',
|
||||
icon: (config.oauth?.generic_oauth?.icon && toIconName(config.oauth?.generic_oauth?.icon)) || 'signin',
|
||||
icon: config.oauth?.generic_oauth?.icon ?? ('signin' as const),
|
||||
hrefName: 'generic_oauth',
|
||||
},
|
||||
};
|
||||
|
@ -57,14 +57,13 @@ const Navigation = ({ children }: { children: NavModelItem[] }) => {
|
||||
<SelectNav customCss="page-header__select-nav">{children}</SelectNav>
|
||||
<TabsBar className="page-header__tabs" hideBorder={true}>
|
||||
{children.map((child, index) => {
|
||||
const icon = child.icon ? toIconName(child.icon) : undefined;
|
||||
return (
|
||||
!child.hideFromTabs && (
|
||||
<Tab
|
||||
label={child.text}
|
||||
active={child.active}
|
||||
key={`${child.url}-${index}`}
|
||||
icon={icon}
|
||||
icon={child.icon}
|
||||
href={child.url}
|
||||
suffix={child.tabSuffix}
|
||||
/>
|
||||
|
@ -29,7 +29,7 @@ function buildWarningNav(text: string, subTitle?: string): NavModel {
|
||||
const node = {
|
||||
text,
|
||||
subTitle,
|
||||
icon: 'exclamation-triangle',
|
||||
icon: 'exclamation-triangle' as const,
|
||||
};
|
||||
return {
|
||||
node: node,
|
||||
|
@ -1458,7 +1458,7 @@ export const navIndex: NavIndex = {
|
||||
},
|
||||
{
|
||||
text: 'Configuration',
|
||||
icon: 'fa fa-cog',
|
||||
icon: 'cog',
|
||||
url: '/plugins/basic-app',
|
||||
},
|
||||
],
|
||||
|
@ -1454,7 +1454,7 @@ export const navIndex: NavIndex = {
|
||||
},
|
||||
{
|
||||
text: 'Configuration',
|
||||
icon: 'fa fa-cog',
|
||||
icon: 'cog',
|
||||
url: '/plugins/basic-app',
|
||||
},
|
||||
],
|
||||
|
@ -20,7 +20,7 @@ export function NewDataSourcePage() {
|
||||
|
||||
export function getNavModel(): NavModel {
|
||||
const main = {
|
||||
icon: 'database',
|
||||
icon: 'database' as const,
|
||||
id: 'datasource-new',
|
||||
text: 'Add data source',
|
||||
href: DATASOURCES_ROUTES.New,
|
||||
|
@ -3,7 +3,7 @@ import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AccessControlAction, FolderDTO } from 'app/types';
|
||||
|
||||
export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
const model = {
|
||||
const model: NavModelItem = {
|
||||
icon: 'folder',
|
||||
id: 'manage-folder',
|
||||
subTitle: 'Manage folder dashboards and permissions',
|
||||
@ -21,7 +21,7 @@ export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
],
|
||||
};
|
||||
|
||||
model.children.push({
|
||||
model.children!.push({
|
||||
active: false,
|
||||
icon: 'library-panel',
|
||||
id: `folder-library-panels-${folder.uid}`,
|
||||
@ -30,7 +30,7 @@ export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
});
|
||||
|
||||
if (contextSrv.hasPermission(AccessControlAction.AlertingRuleRead)) {
|
||||
model.children.push({
|
||||
model.children!.push({
|
||||
active: false,
|
||||
icon: 'bell',
|
||||
id: `folder-alerting-${folder.uid}`,
|
||||
@ -40,7 +40,7 @@ export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
}
|
||||
|
||||
if (folder.canAdmin) {
|
||||
model.children.push({
|
||||
model.children!.push({
|
||||
active: false,
|
||||
icon: 'lock',
|
||||
id: `folder-permissions-${folder.uid}`,
|
||||
@ -50,7 +50,7 @@ export function buildNavModel(folder: FolderDTO): NavModelItem {
|
||||
}
|
||||
|
||||
if (folder.canSave) {
|
||||
model.children.push({
|
||||
model.children!.push({
|
||||
active: false,
|
||||
icon: 'cog',
|
||||
id: `folder-settings-${folder.uid}`,
|
||||
|
@ -17,7 +17,7 @@ interface FormModel {
|
||||
|
||||
const navModel = {
|
||||
main: {
|
||||
icon: 'grafana',
|
||||
icon: 'grafana' as const,
|
||||
text: 'Invite',
|
||||
subTitle: 'Register your Grafana account',
|
||||
breadcrumbs: [{ title: 'Login', url: 'login' }],
|
||||
|
@ -11,7 +11,7 @@ import { getUserOrganizations, setUserOrganization } from './state/actions';
|
||||
|
||||
const navModel = {
|
||||
main: {
|
||||
icon: 'grafana',
|
||||
icon: 'grafana' as const,
|
||||
subTitle: 'Preferences',
|
||||
text: 'Select active organization',
|
||||
},
|
||||
|
@ -13,7 +13,6 @@ export type Props = DataSourcePluginOptionsEditorProps<AlertManagerDataSourceJso
|
||||
const IMPL_OPTIONS: Array<SelectableValue<AlertManagerImplementation>> = [
|
||||
{
|
||||
value: AlertManagerImplementation.mimir,
|
||||
icon: 'public/img/alerting/mimir_logo.svg',
|
||||
label: 'Mimir',
|
||||
description: `https://grafana.com/oss/mimir/. An open source, horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.`,
|
||||
},
|
||||
|
@ -31,12 +31,11 @@ export function createNavModel(title: string, ...tabs: string[]): NavModel {
|
||||
breadcrumbs: [],
|
||||
};
|
||||
|
||||
const children = [];
|
||||
const children: NavModelItem[] = [];
|
||||
|
||||
for (const tab of tabs) {
|
||||
children.push({
|
||||
id: tab,
|
||||
icon: 'icon',
|
||||
subTitle: 'subTitle',
|
||||
url: title,
|
||||
text: title,
|
||||
|
Loading…
Reference in New Issue
Block a user